forked from Minki/linux
Merge git://people.freedesktop.org/~airlied/linux
Pull drm updates from Dave Airlie: "A bunch of fixes across drivers: radeon: disable two ended allocation for now, it breaks some stuff amdkfd: misc fixes nouveau: fix irq loop problem, add basic support for GM206 (new hw) i915: fix some WARNs people were seeing exynos: fix some iommu interactions causing boot failures" * git://people.freedesktop.org/~airlied/linux: drm/radeon: drop ttm two ended allocation drm/exynos: fix the initialization order in FIMD drm/exynos: fix typo config name correctly. drm/exynos: Check for NULL dereference of crtc drm/exynos: IS_ERR() vs NULL bug drm/exynos: remove unused files drm/i915: Make sure the primary plane is enabled before reading out the fb state drm/nouveau/bios: fix i2c table parsing for dcb 4.1 drm/nouveau/device/gm100: Basic GM206 bring up (as copy of GM204) drm/nouveau/device: post write to NV_PMC_BOOT_1 when flipping endian switch drm/nouveau/gr/gf100: fix some accidental or'ing of buffer addresses drm/nouveau/fifo/nv04: remove the loop from the interrupt handler drm/radeon: Changing number of compute pipe lines drm/amdkfd: Fix SDMA queue init. in non-HWS mode drm/amdkfd: destroy mqd when destroying kernel queue drm/i915: Ensure plane->state->fb stays in sync with plane->fb
This commit is contained in:
commit
97448d5b3d
@ -645,6 +645,7 @@ static int create_sdma_queue_nocpsch(struct device_queue_manager *dqm,
|
||||
pr_debug(" sdma queue id: %d\n", q->properties.sdma_queue_id);
|
||||
pr_debug(" sdma engine id: %d\n", q->properties.sdma_engine_id);
|
||||
|
||||
init_sdma_vm(dqm, q, qpd);
|
||||
retval = mqd->init_mqd(mqd, &q->mqd, &q->mqd_mem_obj,
|
||||
&q->gart_mqd_addr, &q->properties);
|
||||
if (retval != 0) {
|
||||
@ -652,7 +653,14 @@ static int create_sdma_queue_nocpsch(struct device_queue_manager *dqm,
|
||||
return retval;
|
||||
}
|
||||
|
||||
init_sdma_vm(dqm, q, qpd);
|
||||
retval = mqd->load_mqd(mqd, q->mqd, 0,
|
||||
0, NULL);
|
||||
if (retval != 0) {
|
||||
deallocate_sdma_queue(dqm, q->sdma_id);
|
||||
mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj);
|
||||
return retval;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev,
|
||||
BUG_ON(!kq || !dev);
|
||||
BUG_ON(type != KFD_QUEUE_TYPE_DIQ && type != KFD_QUEUE_TYPE_HIQ);
|
||||
|
||||
pr_debug("kfd: In func %s initializing queue type %d size %d\n",
|
||||
pr_debug("amdkfd: In func %s initializing queue type %d size %d\n",
|
||||
__func__, KFD_QUEUE_TYPE_HIQ, queue_size);
|
||||
|
||||
nop.opcode = IT_NOP;
|
||||
@ -69,12 +69,16 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev,
|
||||
|
||||
prop.doorbell_ptr = kfd_get_kernel_doorbell(dev, &prop.doorbell_off);
|
||||
|
||||
if (prop.doorbell_ptr == NULL)
|
||||
if (prop.doorbell_ptr == NULL) {
|
||||
pr_err("amdkfd: error init doorbell");
|
||||
goto err_get_kernel_doorbell;
|
||||
}
|
||||
|
||||
retval = kfd_gtt_sa_allocate(dev, queue_size, &kq->pq);
|
||||
if (retval != 0)
|
||||
if (retval != 0) {
|
||||
pr_err("amdkfd: error init pq queues size (%d)\n", queue_size);
|
||||
goto err_pq_allocate_vidmem;
|
||||
}
|
||||
|
||||
kq->pq_kernel_addr = kq->pq->cpu_ptr;
|
||||
kq->pq_gpu_addr = kq->pq->gpu_addr;
|
||||
@ -165,10 +169,8 @@ err_rptr_allocate_vidmem:
|
||||
err_eop_allocate_vidmem:
|
||||
kfd_gtt_sa_free(dev, kq->pq);
|
||||
err_pq_allocate_vidmem:
|
||||
pr_err("kfd: error init pq\n");
|
||||
kfd_release_kernel_doorbell(dev, prop.doorbell_ptr);
|
||||
err_get_kernel_doorbell:
|
||||
pr_err("kfd: error init doorbell");
|
||||
return false;
|
||||
|
||||
}
|
||||
@ -187,6 +189,8 @@ static void uninitialize(struct kernel_queue *kq)
|
||||
else if (kq->queue->properties.type == KFD_QUEUE_TYPE_DIQ)
|
||||
kfd_gtt_sa_free(kq->dev, kq->fence_mem_obj);
|
||||
|
||||
kq->mqd->uninit_mqd(kq->mqd, kq->queue->mqd, kq->queue->mqd_mem_obj);
|
||||
|
||||
kfd_gtt_sa_free(kq->dev, kq->rptr_mem);
|
||||
kfd_gtt_sa_free(kq->dev, kq->wptr_mem);
|
||||
kq->ops_asic_specific.uninitialize(kq);
|
||||
@ -211,7 +215,7 @@ static int acquire_packet_buffer(struct kernel_queue *kq,
|
||||
queue_address = (unsigned int *)kq->pq_kernel_addr;
|
||||
queue_size_dwords = kq->queue->properties.queue_size / sizeof(uint32_t);
|
||||
|
||||
pr_debug("kfd: In func %s\nrptr: %d\nwptr: %d\nqueue_address 0x%p\n",
|
||||
pr_debug("amdkfd: In func %s\nrptr: %d\nwptr: %d\nqueue_address 0x%p\n",
|
||||
__func__, rptr, wptr, queue_address);
|
||||
|
||||
available_size = (rptr - 1 - wptr + queue_size_dwords) %
|
||||
@ -296,7 +300,7 @@ struct kernel_queue *kernel_queue_init(struct kfd_dev *dev,
|
||||
}
|
||||
|
||||
if (kq->ops.initialize(kq, dev, type, KFD_KERNEL_QUEUE_SIZE) == false) {
|
||||
pr_err("kfd: failed to init kernel queue\n");
|
||||
pr_err("amdkfd: failed to init kernel queue\n");
|
||||
kfree(kq);
|
||||
return NULL;
|
||||
}
|
||||
@ -319,7 +323,7 @@ static __attribute__((unused)) void test_kq(struct kfd_dev *dev)
|
||||
|
||||
BUG_ON(!dev);
|
||||
|
||||
pr_err("kfd: starting kernel queue test\n");
|
||||
pr_err("amdkfd: starting kernel queue test\n");
|
||||
|
||||
kq = kernel_queue_init(dev, KFD_QUEUE_TYPE_HIQ);
|
||||
BUG_ON(!kq);
|
||||
@ -330,7 +334,7 @@ static __attribute__((unused)) void test_kq(struct kfd_dev *dev)
|
||||
buffer[i] = kq->nop_packet;
|
||||
kq->ops.submit_packet(kq);
|
||||
|
||||
pr_err("kfd: ending kernel queue test\n");
|
||||
pr_err("amdkfd: ending kernel queue test\n");
|
||||
}
|
||||
|
||||
|
||||
|
@ -50,7 +50,7 @@ config DRM_EXYNOS_DSI
|
||||
|
||||
config DRM_EXYNOS_DP
|
||||
bool "EXYNOS DRM DP driver support"
|
||||
depends on (DRM_EXYNOS_FIMD || DRM_EXYNOS7DECON) && ARCH_EXYNOS && (DRM_PTN3460=n || DRM_PTN3460=y || DRM_PTN3460=DRM_EXYNOS)
|
||||
depends on (DRM_EXYNOS_FIMD || DRM_EXYNOS7_DECON) && ARCH_EXYNOS && (DRM_PTN3460=n || DRM_PTN3460=y || DRM_PTN3460=DRM_EXYNOS)
|
||||
default DRM_EXYNOS
|
||||
select DRM_PANEL
|
||||
help
|
||||
|
@ -888,8 +888,8 @@ static int decon_probe(struct platform_device *pdev)
|
||||
of_node_put(i80_if_timings);
|
||||
|
||||
ctx->regs = of_iomap(dev->of_node, 0);
|
||||
if (IS_ERR(ctx->regs)) {
|
||||
ret = PTR_ERR(ctx->regs);
|
||||
if (!ctx->regs) {
|
||||
ret = -ENOMEM;
|
||||
goto err_del_component;
|
||||
}
|
||||
|
||||
|
@ -1,245 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Samsung Electronics Co., Ltd.
|
||||
* Authors:
|
||||
* Inki Dae <inki.dae@samsung.com>
|
||||
* Joonyoung Shim <jy0922.shim@samsung.com>
|
||||
* Seung-Woo Kim <sw0312.kim@samsung.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
|
||||
#include <drm/drmP.h>
|
||||
#include <drm/drm_crtc_helper.h>
|
||||
|
||||
#include <drm/exynos_drm.h>
|
||||
#include "exynos_drm_drv.h"
|
||||
#include "exynos_drm_encoder.h"
|
||||
#include "exynos_drm_connector.h"
|
||||
|
||||
#define to_exynos_connector(x) container_of(x, struct exynos_drm_connector,\
|
||||
drm_connector)
|
||||
|
||||
struct exynos_drm_connector {
|
||||
struct drm_connector drm_connector;
|
||||
uint32_t encoder_id;
|
||||
struct exynos_drm_display *display;
|
||||
};
|
||||
|
||||
static int exynos_drm_connector_get_modes(struct drm_connector *connector)
|
||||
{
|
||||
struct exynos_drm_connector *exynos_connector =
|
||||
to_exynos_connector(connector);
|
||||
struct exynos_drm_display *display = exynos_connector->display;
|
||||
struct edid *edid = NULL;
|
||||
unsigned int count = 0;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* if get_edid() exists then get_edid() callback of hdmi side
|
||||
* is called to get edid data through i2c interface else
|
||||
* get timing from the FIMD driver(display controller).
|
||||
*
|
||||
* P.S. in case of lcd panel, count is always 1 if success
|
||||
* because lcd panel has only one mode.
|
||||
*/
|
||||
if (display->ops->get_edid) {
|
||||
edid = display->ops->get_edid(display, connector);
|
||||
if (IS_ERR_OR_NULL(edid)) {
|
||||
ret = PTR_ERR(edid);
|
||||
edid = NULL;
|
||||
DRM_ERROR("Panel operation get_edid failed %d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
count = drm_add_edid_modes(connector, edid);
|
||||
if (!count) {
|
||||
DRM_ERROR("Add edid modes failed %d\n", count);
|
||||
goto out;
|
||||
}
|
||||
|
||||
drm_mode_connector_update_edid_property(connector, edid);
|
||||
} else {
|
||||
struct exynos_drm_panel_info *panel;
|
||||
struct drm_display_mode *mode = drm_mode_create(connector->dev);
|
||||
if (!mode) {
|
||||
DRM_ERROR("failed to create a new display mode.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (display->ops->get_panel)
|
||||
panel = display->ops->get_panel(display);
|
||||
else {
|
||||
drm_mode_destroy(connector->dev, mode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
drm_display_mode_from_videomode(&panel->vm, mode);
|
||||
mode->width_mm = panel->width_mm;
|
||||
mode->height_mm = panel->height_mm;
|
||||
connector->display_info.width_mm = mode->width_mm;
|
||||
connector->display_info.height_mm = mode->height_mm;
|
||||
|
||||
mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
|
||||
drm_mode_set_name(mode);
|
||||
drm_mode_probed_add(connector, mode);
|
||||
|
||||
count = 1;
|
||||
}
|
||||
|
||||
out:
|
||||
kfree(edid);
|
||||
return count;
|
||||
}
|
||||
|
||||
static int exynos_drm_connector_mode_valid(struct drm_connector *connector,
|
||||
struct drm_display_mode *mode)
|
||||
{
|
||||
struct exynos_drm_connector *exynos_connector =
|
||||
to_exynos_connector(connector);
|
||||
struct exynos_drm_display *display = exynos_connector->display;
|
||||
int ret = MODE_BAD;
|
||||
|
||||
DRM_DEBUG_KMS("%s\n", __FILE__);
|
||||
|
||||
if (display->ops->check_mode)
|
||||
if (!display->ops->check_mode(display, mode))
|
||||
ret = MODE_OK;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct drm_encoder *exynos_drm_best_encoder(
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct drm_device *dev = connector->dev;
|
||||
struct exynos_drm_connector *exynos_connector =
|
||||
to_exynos_connector(connector);
|
||||
return drm_encoder_find(dev, exynos_connector->encoder_id);
|
||||
}
|
||||
|
||||
static struct drm_connector_helper_funcs exynos_connector_helper_funcs = {
|
||||
.get_modes = exynos_drm_connector_get_modes,
|
||||
.mode_valid = exynos_drm_connector_mode_valid,
|
||||
.best_encoder = exynos_drm_best_encoder,
|
||||
};
|
||||
|
||||
static int exynos_drm_connector_fill_modes(struct drm_connector *connector,
|
||||
unsigned int max_width, unsigned int max_height)
|
||||
{
|
||||
struct exynos_drm_connector *exynos_connector =
|
||||
to_exynos_connector(connector);
|
||||
struct exynos_drm_display *display = exynos_connector->display;
|
||||
unsigned int width, height;
|
||||
|
||||
width = max_width;
|
||||
height = max_height;
|
||||
|
||||
/*
|
||||
* if specific driver want to find desired_mode using maxmum
|
||||
* resolution then get max width and height from that driver.
|
||||
*/
|
||||
if (display->ops->get_max_resol)
|
||||
display->ops->get_max_resol(display, &width, &height);
|
||||
|
||||
return drm_helper_probe_single_connector_modes(connector, width,
|
||||
height);
|
||||
}
|
||||
|
||||
/* get detection status of display device. */
|
||||
static enum drm_connector_status
|
||||
exynos_drm_connector_detect(struct drm_connector *connector, bool force)
|
||||
{
|
||||
struct exynos_drm_connector *exynos_connector =
|
||||
to_exynos_connector(connector);
|
||||
struct exynos_drm_display *display = exynos_connector->display;
|
||||
enum drm_connector_status status = connector_status_disconnected;
|
||||
|
||||
if (display->ops->is_connected) {
|
||||
if (display->ops->is_connected(display))
|
||||
status = connector_status_connected;
|
||||
else
|
||||
status = connector_status_disconnected;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void exynos_drm_connector_destroy(struct drm_connector *connector)
|
||||
{
|
||||
struct exynos_drm_connector *exynos_connector =
|
||||
to_exynos_connector(connector);
|
||||
|
||||
drm_connector_unregister(connector);
|
||||
drm_connector_cleanup(connector);
|
||||
kfree(exynos_connector);
|
||||
}
|
||||
|
||||
static struct drm_connector_funcs exynos_connector_funcs = {
|
||||
.dpms = drm_helper_connector_dpms,
|
||||
.fill_modes = exynos_drm_connector_fill_modes,
|
||||
.detect = exynos_drm_connector_detect,
|
||||
.destroy = exynos_drm_connector_destroy,
|
||||
};
|
||||
|
||||
struct drm_connector *exynos_drm_connector_create(struct drm_device *dev,
|
||||
struct drm_encoder *encoder)
|
||||
{
|
||||
struct exynos_drm_connector *exynos_connector;
|
||||
struct exynos_drm_display *display = exynos_drm_get_display(encoder);
|
||||
struct drm_connector *connector;
|
||||
int type;
|
||||
int err;
|
||||
|
||||
exynos_connector = kzalloc(sizeof(*exynos_connector), GFP_KERNEL);
|
||||
if (!exynos_connector)
|
||||
return NULL;
|
||||
|
||||
connector = &exynos_connector->drm_connector;
|
||||
|
||||
switch (display->type) {
|
||||
case EXYNOS_DISPLAY_TYPE_HDMI:
|
||||
type = DRM_MODE_CONNECTOR_HDMIA;
|
||||
connector->interlace_allowed = true;
|
||||
connector->polled = DRM_CONNECTOR_POLL_HPD;
|
||||
break;
|
||||
case EXYNOS_DISPLAY_TYPE_VIDI:
|
||||
type = DRM_MODE_CONNECTOR_VIRTUAL;
|
||||
connector->polled = DRM_CONNECTOR_POLL_HPD;
|
||||
break;
|
||||
default:
|
||||
type = DRM_MODE_CONNECTOR_Unknown;
|
||||
break;
|
||||
}
|
||||
|
||||
drm_connector_init(dev, connector, &exynos_connector_funcs, type);
|
||||
drm_connector_helper_add(connector, &exynos_connector_helper_funcs);
|
||||
|
||||
err = drm_connector_register(connector);
|
||||
if (err)
|
||||
goto err_connector;
|
||||
|
||||
exynos_connector->encoder_id = encoder->base.id;
|
||||
exynos_connector->display = display;
|
||||
connector->dpms = DRM_MODE_DPMS_OFF;
|
||||
connector->encoder = encoder;
|
||||
|
||||
err = drm_mode_connector_attach_encoder(connector, encoder);
|
||||
if (err) {
|
||||
DRM_ERROR("failed to attach a connector to a encoder\n");
|
||||
goto err_sysfs;
|
||||
}
|
||||
|
||||
DRM_DEBUG_KMS("connector has been created\n");
|
||||
|
||||
return connector;
|
||||
|
||||
err_sysfs:
|
||||
drm_connector_unregister(connector);
|
||||
err_connector:
|
||||
drm_connector_cleanup(connector);
|
||||
kfree(exynos_connector);
|
||||
return NULL;
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Samsung Electronics Co., Ltd.
|
||||
* Authors:
|
||||
* Inki Dae <inki.dae@samsung.com>
|
||||
* Joonyoung Shim <jy0922.shim@samsung.com>
|
||||
* Seung-Woo Kim <sw0312.kim@samsung.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef _EXYNOS_DRM_CONNECTOR_H_
|
||||
#define _EXYNOS_DRM_CONNECTOR_H_
|
||||
|
||||
struct drm_connector *exynos_drm_connector_create(struct drm_device *dev,
|
||||
struct drm_encoder *encoder);
|
||||
|
||||
#endif
|
@ -284,14 +284,9 @@ static void fimd_clear_channel(struct fimd_context *ctx)
|
||||
}
|
||||
}
|
||||
|
||||
static int fimd_ctx_initialize(struct fimd_context *ctx,
|
||||
static int fimd_iommu_attach_devices(struct fimd_context *ctx,
|
||||
struct drm_device *drm_dev)
|
||||
{
|
||||
struct exynos_drm_private *priv;
|
||||
priv = drm_dev->dev_private;
|
||||
|
||||
ctx->drm_dev = drm_dev;
|
||||
ctx->pipe = priv->pipe++;
|
||||
|
||||
/* attach this sub driver to iommu mapping if supported. */
|
||||
if (is_drm_iommu_supported(ctx->drm_dev)) {
|
||||
@ -313,7 +308,7 @@ static int fimd_ctx_initialize(struct fimd_context *ctx,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fimd_ctx_remove(struct fimd_context *ctx)
|
||||
static void fimd_iommu_detach_devices(struct fimd_context *ctx)
|
||||
{
|
||||
/* detach this sub driver from iommu mapping if supported. */
|
||||
if (is_drm_iommu_supported(ctx->drm_dev))
|
||||
@ -1056,25 +1051,23 @@ static int fimd_bind(struct device *dev, struct device *master, void *data)
|
||||
{
|
||||
struct fimd_context *ctx = dev_get_drvdata(dev);
|
||||
struct drm_device *drm_dev = data;
|
||||
struct exynos_drm_private *priv = drm_dev->dev_private;
|
||||
int ret;
|
||||
|
||||
ret = fimd_ctx_initialize(ctx, drm_dev);
|
||||
if (ret) {
|
||||
DRM_ERROR("fimd_ctx_initialize failed.\n");
|
||||
return ret;
|
||||
}
|
||||
ctx->drm_dev = drm_dev;
|
||||
ctx->pipe = priv->pipe++;
|
||||
|
||||
ctx->crtc = exynos_drm_crtc_create(drm_dev, ctx->pipe,
|
||||
EXYNOS_DISPLAY_TYPE_LCD,
|
||||
&fimd_crtc_ops, ctx);
|
||||
if (IS_ERR(ctx->crtc)) {
|
||||
fimd_ctx_remove(ctx);
|
||||
return PTR_ERR(ctx->crtc);
|
||||
}
|
||||
|
||||
if (ctx->display)
|
||||
exynos_drm_create_enc_conn(drm_dev, ctx->display);
|
||||
|
||||
ret = fimd_iommu_attach_devices(ctx, drm_dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
@ -1086,10 +1079,10 @@ static void fimd_unbind(struct device *dev, struct device *master,
|
||||
|
||||
fimd_dpms(ctx->crtc, DRM_MODE_DPMS_OFF);
|
||||
|
||||
fimd_iommu_detach_devices(ctx);
|
||||
|
||||
if (ctx->display)
|
||||
exynos_dpi_remove(ctx->display);
|
||||
|
||||
fimd_ctx_remove(ctx);
|
||||
}
|
||||
|
||||
static const struct component_ops fimd_component_ops = {
|
||||
|
@ -175,7 +175,7 @@ static int exynos_disable_plane(struct drm_plane *plane)
|
||||
struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
|
||||
struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(plane->crtc);
|
||||
|
||||
if (exynos_crtc->ops->win_disable)
|
||||
if (exynos_crtc && exynos_crtc->ops->win_disable)
|
||||
exynos_crtc->ops->win_disable(exynos_crtc,
|
||||
exynos_plane->zpos);
|
||||
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include <drm/i915_drm.h>
|
||||
#include "i915_drv.h"
|
||||
#include "i915_trace.h"
|
||||
#include <drm/drm_atomic.h>
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
#include <drm/drm_dp_helper.h>
|
||||
#include <drm/drm_crtc_helper.h>
|
||||
@ -2416,6 +2417,14 @@ out_unref_obj:
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Update plane->state->fb to match plane->fb after driver-internal updates */
|
||||
static void
|
||||
update_state_fb(struct drm_plane *plane)
|
||||
{
|
||||
if (plane->fb != plane->state->fb)
|
||||
drm_atomic_set_fb_for_plane(plane->state, plane->fb);
|
||||
}
|
||||
|
||||
static void
|
||||
intel_find_plane_obj(struct intel_crtc *intel_crtc,
|
||||
struct intel_initial_plane_config *plane_config)
|
||||
@ -2462,6 +2471,8 @@ intel_find_plane_obj(struct intel_crtc *intel_crtc,
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
update_state_fb(intel_crtc->base.primary);
|
||||
}
|
||||
|
||||
static void i9xx_update_primary_plane(struct drm_crtc *crtc,
|
||||
@ -6602,6 +6613,10 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
|
||||
struct drm_framebuffer *fb;
|
||||
struct intel_framebuffer *intel_fb;
|
||||
|
||||
val = I915_READ(DSPCNTR(plane));
|
||||
if (!(val & DISPLAY_PLANE_ENABLE))
|
||||
return;
|
||||
|
||||
intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
|
||||
if (!intel_fb) {
|
||||
DRM_DEBUG_KMS("failed to alloc fb\n");
|
||||
@ -6610,8 +6625,6 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
|
||||
|
||||
fb = &intel_fb->base;
|
||||
|
||||
val = I915_READ(DSPCNTR(plane));
|
||||
|
||||
if (INTEL_INFO(dev)->gen >= 4)
|
||||
if (val & DISPPLANE_TILED)
|
||||
plane_config->tiling = I915_TILING_X;
|
||||
@ -6650,6 +6663,7 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
|
||||
plane_config->size);
|
||||
|
||||
crtc->base.primary->fb = fb;
|
||||
update_state_fb(crtc->base.primary);
|
||||
}
|
||||
|
||||
static void chv_crtc_clock_get(struct intel_crtc *crtc,
|
||||
@ -7643,6 +7657,9 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc,
|
||||
fb = &intel_fb->base;
|
||||
|
||||
val = I915_READ(PLANE_CTL(pipe, 0));
|
||||
if (!(val & PLANE_CTL_ENABLE))
|
||||
goto error;
|
||||
|
||||
if (val & PLANE_CTL_TILED_MASK)
|
||||
plane_config->tiling = I915_TILING_X;
|
||||
|
||||
@ -7687,6 +7704,7 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc,
|
||||
plane_config->size);
|
||||
|
||||
crtc->base.primary->fb = fb;
|
||||
update_state_fb(crtc->base.primary);
|
||||
return;
|
||||
|
||||
error:
|
||||
@ -7730,6 +7748,10 @@ ironlake_get_initial_plane_config(struct intel_crtc *crtc,
|
||||
struct drm_framebuffer *fb;
|
||||
struct intel_framebuffer *intel_fb;
|
||||
|
||||
val = I915_READ(DSPCNTR(pipe));
|
||||
if (!(val & DISPLAY_PLANE_ENABLE))
|
||||
return;
|
||||
|
||||
intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
|
||||
if (!intel_fb) {
|
||||
DRM_DEBUG_KMS("failed to alloc fb\n");
|
||||
@ -7738,8 +7760,6 @@ ironlake_get_initial_plane_config(struct intel_crtc *crtc,
|
||||
|
||||
fb = &intel_fb->base;
|
||||
|
||||
val = I915_READ(DSPCNTR(pipe));
|
||||
|
||||
if (INTEL_INFO(dev)->gen >= 4)
|
||||
if (val & DISPPLANE_TILED)
|
||||
plane_config->tiling = I915_TILING_X;
|
||||
@ -7778,6 +7798,7 @@ ironlake_get_initial_plane_config(struct intel_crtc *crtc,
|
||||
plane_config->size);
|
||||
|
||||
crtc->base.primary->fb = fb;
|
||||
update_state_fb(crtc->base.primary);
|
||||
}
|
||||
|
||||
static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
|
||||
@ -9816,6 +9837,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
|
||||
drm_gem_object_reference(&obj->base);
|
||||
|
||||
crtc->primary->fb = fb;
|
||||
update_state_fb(crtc->primary);
|
||||
|
||||
work->pending_flip_obj = obj;
|
||||
|
||||
@ -9884,6 +9906,7 @@ cleanup_unpin:
|
||||
cleanup_pending:
|
||||
atomic_dec(&intel_crtc->unpin_work_count);
|
||||
crtc->primary->fb = old_fb;
|
||||
update_state_fb(crtc->primary);
|
||||
drm_gem_object_unreference(&work->old_fb_obj->base);
|
||||
drm_gem_object_unreference(&obj->base);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
@ -13718,6 +13741,7 @@ void intel_modeset_gem_init(struct drm_device *dev)
|
||||
to_intel_crtc(c)->pipe);
|
||||
drm_framebuffer_unreference(c->primary->fb);
|
||||
c->primary->fb = NULL;
|
||||
update_state_fb(c->primary);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
|
@ -340,11 +340,13 @@ nvkm_devobj_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
|
||||
|
||||
/* switch mmio to cpu's native endianness */
|
||||
#ifndef __BIG_ENDIAN
|
||||
if (ioread32_native(map + 0x000004) != 0x00000000)
|
||||
if (ioread32_native(map + 0x000004) != 0x00000000) {
|
||||
#else
|
||||
if (ioread32_native(map + 0x000004) == 0x00000000)
|
||||
if (ioread32_native(map + 0x000004) == 0x00000000) {
|
||||
#endif
|
||||
iowrite32_native(0x01000001, map + 0x000004);
|
||||
ioread32_native(map);
|
||||
}
|
||||
|
||||
/* read boot0 and strapping information */
|
||||
boot0 = ioread32_native(map + 0x000000);
|
||||
|
@ -140,6 +140,49 @@ gm100_identify(struct nvkm_device *device)
|
||||
device->oclass[NVDEV_ENGINE_MSVLD ] = &gk104_msvld_oclass;
|
||||
device->oclass[NVDEV_ENGINE_MSPDEC ] = &gk104_mspdec_oclass;
|
||||
device->oclass[NVDEV_ENGINE_MSPPP ] = &gf100_msppp_oclass;
|
||||
#endif
|
||||
break;
|
||||
case 0x126:
|
||||
device->cname = "GM206";
|
||||
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_GPIO ] = gk104_gpio_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_I2C ] = gm204_i2c_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_FUSE ] = &gm107_fuse_oclass;
|
||||
#if 0
|
||||
/* looks to be some non-trivial changes */
|
||||
device->oclass[NVDEV_SUBDEV_CLK ] = &gk104_clk_oclass;
|
||||
/* priv ring says no to 0x10eb14 writes */
|
||||
device->oclass[NVDEV_SUBDEV_THERM ] = &gm107_therm_oclass;
|
||||
#endif
|
||||
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_DEVINIT] = gm204_devinit_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_MC ] = gk20a_mc_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_BUS ] = gf100_bus_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_TIMER ] = &gk20a_timer_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_FB ] = gm107_fb_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_LTC ] = gm107_ltc_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_IBUS ] = &gk104_ibus_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_MMU ] = &gf100_mmu_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_BAR ] = &gf100_bar_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_PMU ] = gk208_pmu_oclass;
|
||||
#if 0
|
||||
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
|
||||
#endif
|
||||
device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf110_dmaeng_oclass;
|
||||
#if 0
|
||||
device->oclass[NVDEV_ENGINE_FIFO ] = gk208_fifo_oclass;
|
||||
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
|
||||
device->oclass[NVDEV_ENGINE_GR ] = gm107_gr_oclass;
|
||||
#endif
|
||||
device->oclass[NVDEV_ENGINE_DISP ] = gm204_disp_oclass;
|
||||
#if 0
|
||||
device->oclass[NVDEV_ENGINE_CE0 ] = &gm204_ce0_oclass;
|
||||
device->oclass[NVDEV_ENGINE_CE1 ] = &gm204_ce1_oclass;
|
||||
device->oclass[NVDEV_ENGINE_CE2 ] = &gm204_ce2_oclass;
|
||||
device->oclass[NVDEV_ENGINE_MSVLD ] = &gk104_msvld_oclass;
|
||||
device->oclass[NVDEV_ENGINE_MSPDEC ] = &gk104_mspdec_oclass;
|
||||
device->oclass[NVDEV_ENGINE_MSPPP ] = &gf100_msppp_oclass;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
|
@ -502,72 +502,57 @@ nv04_fifo_intr(struct nvkm_subdev *subdev)
|
||||
{
|
||||
struct nvkm_device *device = nv_device(subdev);
|
||||
struct nv04_fifo_priv *priv = (void *)subdev;
|
||||
uint32_t status, reassign;
|
||||
int cnt = 0;
|
||||
u32 mask = nv_rd32(priv, NV03_PFIFO_INTR_EN_0);
|
||||
u32 stat = nv_rd32(priv, NV03_PFIFO_INTR_0) & mask;
|
||||
u32 reassign, chid, get, sem;
|
||||
|
||||
reassign = nv_rd32(priv, NV03_PFIFO_CACHES) & 1;
|
||||
while ((status = nv_rd32(priv, NV03_PFIFO_INTR_0)) && (cnt++ < 100)) {
|
||||
uint32_t chid, get;
|
||||
nv_wr32(priv, NV03_PFIFO_CACHES, 0);
|
||||
|
||||
nv_wr32(priv, NV03_PFIFO_CACHES, 0);
|
||||
chid = nv_rd32(priv, NV03_PFIFO_CACHE1_PUSH1) & priv->base.max;
|
||||
get = nv_rd32(priv, NV03_PFIFO_CACHE1_GET);
|
||||
|
||||
chid = nv_rd32(priv, NV03_PFIFO_CACHE1_PUSH1) & priv->base.max;
|
||||
get = nv_rd32(priv, NV03_PFIFO_CACHE1_GET);
|
||||
|
||||
if (status & NV_PFIFO_INTR_CACHE_ERROR) {
|
||||
nv04_fifo_cache_error(device, priv, chid, get);
|
||||
status &= ~NV_PFIFO_INTR_CACHE_ERROR;
|
||||
}
|
||||
|
||||
if (status & NV_PFIFO_INTR_DMA_PUSHER) {
|
||||
nv04_fifo_dma_pusher(device, priv, chid);
|
||||
status &= ~NV_PFIFO_INTR_DMA_PUSHER;
|
||||
}
|
||||
|
||||
if (status & NV_PFIFO_INTR_SEMAPHORE) {
|
||||
uint32_t sem;
|
||||
|
||||
status &= ~NV_PFIFO_INTR_SEMAPHORE;
|
||||
nv_wr32(priv, NV03_PFIFO_INTR_0,
|
||||
NV_PFIFO_INTR_SEMAPHORE);
|
||||
|
||||
sem = nv_rd32(priv, NV10_PFIFO_CACHE1_SEMAPHORE);
|
||||
nv_wr32(priv, NV10_PFIFO_CACHE1_SEMAPHORE, sem | 0x1);
|
||||
|
||||
nv_wr32(priv, NV03_PFIFO_CACHE1_GET, get + 4);
|
||||
nv_wr32(priv, NV04_PFIFO_CACHE1_PULL0, 1);
|
||||
}
|
||||
|
||||
if (device->card_type == NV_50) {
|
||||
if (status & 0x00000010) {
|
||||
status &= ~0x00000010;
|
||||
nv_wr32(priv, 0x002100, 0x00000010);
|
||||
}
|
||||
|
||||
if (status & 0x40000000) {
|
||||
nv_wr32(priv, 0x002100, 0x40000000);
|
||||
nvkm_fifo_uevent(&priv->base);
|
||||
status &= ~0x40000000;
|
||||
}
|
||||
}
|
||||
|
||||
if (status) {
|
||||
nv_warn(priv, "unknown intr 0x%08x, ch %d\n",
|
||||
status, chid);
|
||||
nv_wr32(priv, NV03_PFIFO_INTR_0, status);
|
||||
status = 0;
|
||||
}
|
||||
|
||||
nv_wr32(priv, NV03_PFIFO_CACHES, reassign);
|
||||
if (stat & NV_PFIFO_INTR_CACHE_ERROR) {
|
||||
nv04_fifo_cache_error(device, priv, chid, get);
|
||||
stat &= ~NV_PFIFO_INTR_CACHE_ERROR;
|
||||
}
|
||||
|
||||
if (status) {
|
||||
nv_error(priv, "still angry after %d spins, halt\n", cnt);
|
||||
nv_wr32(priv, 0x002140, 0);
|
||||
nv_wr32(priv, 0x000140, 0);
|
||||
if (stat & NV_PFIFO_INTR_DMA_PUSHER) {
|
||||
nv04_fifo_dma_pusher(device, priv, chid);
|
||||
stat &= ~NV_PFIFO_INTR_DMA_PUSHER;
|
||||
}
|
||||
|
||||
nv_wr32(priv, 0x000100, 0x00000100);
|
||||
if (stat & NV_PFIFO_INTR_SEMAPHORE) {
|
||||
stat &= ~NV_PFIFO_INTR_SEMAPHORE;
|
||||
nv_wr32(priv, NV03_PFIFO_INTR_0, NV_PFIFO_INTR_SEMAPHORE);
|
||||
|
||||
sem = nv_rd32(priv, NV10_PFIFO_CACHE1_SEMAPHORE);
|
||||
nv_wr32(priv, NV10_PFIFO_CACHE1_SEMAPHORE, sem | 0x1);
|
||||
|
||||
nv_wr32(priv, NV03_PFIFO_CACHE1_GET, get + 4);
|
||||
nv_wr32(priv, NV04_PFIFO_CACHE1_PULL0, 1);
|
||||
}
|
||||
|
||||
if (device->card_type == NV_50) {
|
||||
if (stat & 0x00000010) {
|
||||
stat &= ~0x00000010;
|
||||
nv_wr32(priv, 0x002100, 0x00000010);
|
||||
}
|
||||
|
||||
if (stat & 0x40000000) {
|
||||
nv_wr32(priv, 0x002100, 0x40000000);
|
||||
nvkm_fifo_uevent(&priv->base);
|
||||
stat &= ~0x40000000;
|
||||
}
|
||||
}
|
||||
|
||||
if (stat) {
|
||||
nv_warn(priv, "unknown intr 0x%08x\n", stat);
|
||||
nv_mask(priv, NV03_PFIFO_INTR_EN_0, stat, 0x00000000);
|
||||
nv_wr32(priv, NV03_PFIFO_INTR_0, stat);
|
||||
}
|
||||
|
||||
nv_wr32(priv, NV03_PFIFO_CACHES, reassign);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -1032,9 +1032,9 @@ gf100_grctx_generate_bundle(struct gf100_grctx *info)
|
||||
const int s = 8;
|
||||
const int b = mmio_vram(info, impl->bundle_size, (1 << s), access);
|
||||
mmio_refn(info, 0x408004, 0x00000000, s, b);
|
||||
mmio_refn(info, 0x408008, 0x80000000 | (impl->bundle_size >> s), 0, b);
|
||||
mmio_wr32(info, 0x408008, 0x80000000 | (impl->bundle_size >> s));
|
||||
mmio_refn(info, 0x418808, 0x00000000, s, b);
|
||||
mmio_refn(info, 0x41880c, 0x80000000 | (impl->bundle_size >> s), 0, b);
|
||||
mmio_wr32(info, 0x41880c, 0x80000000 | (impl->bundle_size >> s));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -851,9 +851,9 @@ gk104_grctx_generate_bundle(struct gf100_grctx *info)
|
||||
const int s = 8;
|
||||
const int b = mmio_vram(info, impl->bundle_size, (1 << s), access);
|
||||
mmio_refn(info, 0x408004, 0x00000000, s, b);
|
||||
mmio_refn(info, 0x408008, 0x80000000 | (impl->bundle_size >> s), 0, b);
|
||||
mmio_wr32(info, 0x408008, 0x80000000 | (impl->bundle_size >> s));
|
||||
mmio_refn(info, 0x418808, 0x00000000, s, b);
|
||||
mmio_refn(info, 0x41880c, 0x80000000 | (impl->bundle_size >> s), 0, b);
|
||||
mmio_wr32(info, 0x41880c, 0x80000000 | (impl->bundle_size >> s));
|
||||
mmio_wr32(info, 0x4064c8, (state_limit << 16) | token_limit);
|
||||
}
|
||||
|
||||
|
@ -871,9 +871,9 @@ gm107_grctx_generate_bundle(struct gf100_grctx *info)
|
||||
const int s = 8;
|
||||
const int b = mmio_vram(info, impl->bundle_size, (1 << s), access);
|
||||
mmio_refn(info, 0x408004, 0x00000000, s, b);
|
||||
mmio_refn(info, 0x408008, 0x80000000 | (impl->bundle_size >> s), 0, b);
|
||||
mmio_wr32(info, 0x408008, 0x80000000 | (impl->bundle_size >> s));
|
||||
mmio_refn(info, 0x418e24, 0x00000000, s, b);
|
||||
mmio_refn(info, 0x418e28, 0x80000000 | (impl->bundle_size >> s), 0, b);
|
||||
mmio_wr32(info, 0x418e28, 0x80000000 | (impl->bundle_size >> s));
|
||||
mmio_wr32(info, 0x4064c8, (state_limit << 16) | token_limit);
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,11 @@ dcb_i2c_parse(struct nvkm_bios *bios, u8 idx, struct dcb_i2c_entry *info)
|
||||
u16 ent = dcb_i2c_entry(bios, idx, &ver, &len);
|
||||
if (ent) {
|
||||
if (ver >= 0x41) {
|
||||
if (!(nv_ro32(bios, ent) & 0x80000000))
|
||||
u32 ent_value = nv_ro32(bios, ent);
|
||||
u8 i2c_port = (ent_value >> 27) & 0x1f;
|
||||
u8 dpaux_port = (ent_value >> 22) & 0x1f;
|
||||
/* value 0x1f means unused according to DCB 4.x spec */
|
||||
if (i2c_port == 0x1f && dpaux_port == 0x1f)
|
||||
info->type = DCB_I2C_UNUSED;
|
||||
else
|
||||
info->type = DCB_I2C_PMGR;
|
||||
|
@ -153,7 +153,7 @@ void radeon_kfd_device_init(struct radeon_device *rdev)
|
||||
.compute_vmid_bitmap = 0xFF00,
|
||||
|
||||
.first_compute_pipe = 1,
|
||||
.compute_pipe_count = 8 - 1,
|
||||
.compute_pipe_count = 4 - 1,
|
||||
};
|
||||
|
||||
radeon_doorbell_get_kfd_info(rdev,
|
||||
|
@ -173,17 +173,6 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain)
|
||||
else
|
||||
rbo->placements[i].lpfn = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Use two-ended allocation depending on the buffer size to
|
||||
* improve fragmentation quality.
|
||||
* 512kb was measured as the most optimal number.
|
||||
*/
|
||||
if (rbo->tbo.mem.size > 512 * 1024) {
|
||||
for (i = 0; i < c; i++) {
|
||||
rbo->placements[i].flags |= TTM_PL_FLAG_TOPDOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int radeon_bo_create(struct radeon_device *rdev,
|
||||
|
Loading…
Reference in New Issue
Block a user