Commit 97448d5b authored by Linus Torvalds's avatar Linus Torvalds

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
parents bb8ef2fb 8265d448
...@@ -645,6 +645,7 @@ static int create_sdma_queue_nocpsch(struct device_queue_manager *dqm, ...@@ -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 queue id: %d\n", q->properties.sdma_queue_id);
pr_debug(" sdma engine id: %d\n", q->properties.sdma_engine_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, retval = mqd->init_mqd(mqd, &q->mqd, &q->mqd_mem_obj,
&q->gart_mqd_addr, &q->properties); &q->gart_mqd_addr, &q->properties);
if (retval != 0) { if (retval != 0) {
...@@ -652,7 +653,14 @@ static int create_sdma_queue_nocpsch(struct device_queue_manager *dqm, ...@@ -652,7 +653,14 @@ static int create_sdma_queue_nocpsch(struct device_queue_manager *dqm,
return retval; 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; return 0;
} }
......
...@@ -44,7 +44,7 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev, ...@@ -44,7 +44,7 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev,
BUG_ON(!kq || !dev); BUG_ON(!kq || !dev);
BUG_ON(type != KFD_QUEUE_TYPE_DIQ && type != KFD_QUEUE_TYPE_HIQ); 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); __func__, KFD_QUEUE_TYPE_HIQ, queue_size);
nop.opcode = IT_NOP; nop.opcode = IT_NOP;
...@@ -69,12 +69,16 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev, ...@@ -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); 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; goto err_get_kernel_doorbell;
}
retval = kfd_gtt_sa_allocate(dev, queue_size, &kq->pq); 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; goto err_pq_allocate_vidmem;
}
kq->pq_kernel_addr = kq->pq->cpu_ptr; kq->pq_kernel_addr = kq->pq->cpu_ptr;
kq->pq_gpu_addr = kq->pq->gpu_addr; kq->pq_gpu_addr = kq->pq->gpu_addr;
...@@ -165,10 +169,8 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev, ...@@ -165,10 +169,8 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev,
err_eop_allocate_vidmem: err_eop_allocate_vidmem:
kfd_gtt_sa_free(dev, kq->pq); kfd_gtt_sa_free(dev, kq->pq);
err_pq_allocate_vidmem: err_pq_allocate_vidmem:
pr_err("kfd: error init pq\n");
kfd_release_kernel_doorbell(dev, prop.doorbell_ptr); kfd_release_kernel_doorbell(dev, prop.doorbell_ptr);
err_get_kernel_doorbell: err_get_kernel_doorbell:
pr_err("kfd: error init doorbell");
return false; return false;
} }
...@@ -187,6 +189,8 @@ static void uninitialize(struct kernel_queue *kq) ...@@ -187,6 +189,8 @@ static void uninitialize(struct kernel_queue *kq)
else if (kq->queue->properties.type == KFD_QUEUE_TYPE_DIQ) else if (kq->queue->properties.type == KFD_QUEUE_TYPE_DIQ)
kfd_gtt_sa_free(kq->dev, kq->fence_mem_obj); 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->rptr_mem);
kfd_gtt_sa_free(kq->dev, kq->wptr_mem); kfd_gtt_sa_free(kq->dev, kq->wptr_mem);
kq->ops_asic_specific.uninitialize(kq); kq->ops_asic_specific.uninitialize(kq);
...@@ -211,7 +215,7 @@ static int acquire_packet_buffer(struct kernel_queue *kq, ...@@ -211,7 +215,7 @@ static int acquire_packet_buffer(struct kernel_queue *kq,
queue_address = (unsigned int *)kq->pq_kernel_addr; queue_address = (unsigned int *)kq->pq_kernel_addr;
queue_size_dwords = kq->queue->properties.queue_size / sizeof(uint32_t); 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); __func__, rptr, wptr, queue_address);
available_size = (rptr - 1 - wptr + queue_size_dwords) % available_size = (rptr - 1 - wptr + queue_size_dwords) %
...@@ -296,7 +300,7 @@ struct kernel_queue *kernel_queue_init(struct kfd_dev *dev, ...@@ -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) { 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); kfree(kq);
return NULL; return NULL;
} }
...@@ -319,7 +323,7 @@ static __attribute__((unused)) void test_kq(struct kfd_dev *dev) ...@@ -319,7 +323,7 @@ static __attribute__((unused)) void test_kq(struct kfd_dev *dev)
BUG_ON(!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); kq = kernel_queue_init(dev, KFD_QUEUE_TYPE_HIQ);
BUG_ON(!kq); BUG_ON(!kq);
...@@ -330,7 +334,7 @@ static __attribute__((unused)) void test_kq(struct kfd_dev *dev) ...@@ -330,7 +334,7 @@ static __attribute__((unused)) void test_kq(struct kfd_dev *dev)
buffer[i] = kq->nop_packet; buffer[i] = kq->nop_packet;
kq->ops.submit_packet(kq); 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 ...@@ -50,7 +50,7 @@ config DRM_EXYNOS_DSI
config DRM_EXYNOS_DP config DRM_EXYNOS_DP
bool "EXYNOS DRM DP driver support" 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 default DRM_EXYNOS
select DRM_PANEL select DRM_PANEL
help help
......
...@@ -888,8 +888,8 @@ static int decon_probe(struct platform_device *pdev) ...@@ -888,8 +888,8 @@ static int decon_probe(struct platform_device *pdev)
of_node_put(i80_if_timings); of_node_put(i80_if_timings);
ctx->regs = of_iomap(dev->of_node, 0); ctx->regs = of_iomap(dev->of_node, 0);
if (IS_ERR(ctx->regs)) { if (!ctx->regs) {
ret = PTR_ERR(ctx->regs); ret = -ENOMEM;
goto err_del_component; goto err_del_component;
} }
......
/*
* 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;
}
/*
* 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) ...@@ -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 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. */ /* attach this sub driver to iommu mapping if supported. */
if (is_drm_iommu_supported(ctx->drm_dev)) { if (is_drm_iommu_supported(ctx->drm_dev)) {
...@@ -313,7 +308,7 @@ static int fimd_ctx_initialize(struct fimd_context *ctx, ...@@ -313,7 +308,7 @@ static int fimd_ctx_initialize(struct fimd_context *ctx,
return 0; 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. */ /* detach this sub driver from iommu mapping if supported. */
if (is_drm_iommu_supported(ctx->drm_dev)) if (is_drm_iommu_supported(ctx->drm_dev))
...@@ -1056,25 +1051,23 @@ static int fimd_bind(struct device *dev, struct device *master, void *data) ...@@ -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 fimd_context *ctx = dev_get_drvdata(dev);
struct drm_device *drm_dev = data; struct drm_device *drm_dev = data;
struct exynos_drm_private *priv = drm_dev->dev_private;
int ret; int ret;
ret = fimd_ctx_initialize(ctx, drm_dev); ctx->drm_dev = drm_dev;
if (ret) { ctx->pipe = priv->pipe++;
DRM_ERROR("fimd_ctx_initialize failed.\n");
return ret;
}
ctx->crtc = exynos_drm_crtc_create(drm_dev, ctx->pipe, ctx->crtc = exynos_drm_crtc_create(drm_dev, ctx->pipe,
EXYNOS_DISPLAY_TYPE_LCD, EXYNOS_DISPLAY_TYPE_LCD,
&fimd_crtc_ops, ctx); &fimd_crtc_ops, ctx);
if (IS_ERR(ctx->crtc)) {
fimd_ctx_remove(ctx);
return PTR_ERR(ctx->crtc);
}
if (ctx->display) if (ctx->display)
exynos_drm_create_enc_conn(drm_dev, 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; return 0;
} }
...@@ -1086,10 +1079,10 @@ static void fimd_unbind(struct device *dev, struct device *master, ...@@ -1086,10 +1079,10 @@ static void fimd_unbind(struct device *dev, struct device *master,
fimd_dpms(ctx->crtc, DRM_MODE_DPMS_OFF); fimd_dpms(ctx->crtc, DRM_MODE_DPMS_OFF);
fimd_iommu_detach_devices(ctx);
if (ctx->display) if (ctx->display)
exynos_dpi_remove(ctx->display); exynos_dpi_remove(ctx->display);
fimd_ctx_remove(ctx);
} }
static const struct component_ops fimd_component_ops = { static const struct component_ops fimd_component_ops = {
......
...@@ -175,7 +175,7 @@ static int exynos_disable_plane(struct drm_plane *plane) ...@@ -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_plane *exynos_plane = to_exynos_plane(plane);
struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(plane->crtc); 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_crtc->ops->win_disable(exynos_crtc,
exynos_plane->zpos); exynos_plane->zpos);
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include <drm/i915_drm.h> #include <drm/i915_drm.h>
#include "i915_drv.h" #include "i915_drv.h"
#include "i915_trace.h" #include "i915_trace.h"
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h> #include <drm/drm_atomic_helper.h>
#include <drm/drm_dp_helper.h> #include <drm/drm_dp_helper.h>
#include <drm/drm_crtc_helper.h> #include <drm/drm_crtc_helper.h>
...@@ -2416,6 +2417,14 @@ intel_alloc_plane_obj(struct intel_crtc *crtc, ...@@ -2416,6 +2417,14 @@ intel_alloc_plane_obj(struct intel_crtc *crtc,
return false; 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 static void
intel_find_plane_obj(struct intel_crtc *intel_crtc, intel_find_plane_obj(struct intel_crtc *intel_crtc,
struct intel_initial_plane_config *plane_config) struct intel_initial_plane_config *plane_config)
...@@ -2462,6 +2471,8 @@ intel_find_plane_obj(struct intel_crtc *intel_crtc, ...@@ -2462,6 +2471,8 @@ intel_find_plane_obj(struct intel_crtc *intel_crtc,
break; break;
} }
} }
update_state_fb(intel_crtc->base.primary);
} }
static void i9xx_update_primary_plane(struct drm_crtc *crtc, static void i9xx_update_primary_plane(struct drm_crtc *crtc,
...@@ -6602,6 +6613,10 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc, ...@@ -6602,6 +6613,10 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
struct drm_framebuffer *fb; struct drm_framebuffer *fb;
struct intel_framebuffer *intel_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); intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
if (!intel_fb) { if (!intel_fb) {
DRM_DEBUG_KMS("failed to alloc fb\n"); DRM_DEBUG_KMS("failed to alloc fb\n");
...@@ -6610,8 +6625,6 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc, ...@@ -6610,8 +6625,6 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
fb = &intel_fb->base; fb = &intel_fb->base;
val = I915_READ(DSPCNTR(plane));
if (INTEL_INFO(dev)->gen >= 4) if (INTEL_INFO(dev)->gen >= 4)
if (val & DISPPLANE_TILED) if (val & DISPPLANE_TILED)
plane_config->tiling = I915_TILING_X; plane_config->tiling = I915_TILING_X;
...@@ -6650,6 +6663,7 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc, ...@@ -6650,6 +6663,7 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
plane_config->size); plane_config->size);
crtc->base.primary->fb = fb; crtc->base.primary->fb = fb;
update_state_fb(crtc->base.primary);
} }
static void chv_crtc_clock_get(struct intel_crtc *crtc, static void chv_crtc_clock_get(struct intel_crtc *crtc,
...@@ -7643,6 +7657,9 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc, ...@@ -7643,6 +7657,9 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc,
fb = &intel_fb->base; fb = &intel_fb->base;
val = I915_READ(PLANE_CTL(pipe, 0)); val = I915_READ(PLANE_CTL(pipe, 0));
if (!(val & PLANE_CTL_ENABLE))
goto error;
if (val & PLANE_CTL_TILED_MASK) if (val & PLANE_CTL_TILED_MASK)
plane_config->tiling = I915_TILING_X; plane_config->tiling = I915_TILING_X;
...@@ -7687,6 +7704,7 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc, ...@@ -7687,6 +7704,7 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc,
plane_config->size); plane_config->size);
crtc->base.primary->fb = fb; crtc->base.primary->fb = fb;
update_state_fb(crtc->base.primary);
return; return;
error: error:
...@@ -7730,6 +7748,10 @@ ironlake_get_initial_plane_config(struct intel_crtc *crtc, ...@@ -7730,6 +7748,10 @@ ironlake_get_initial_plane_config(struct intel_crtc *crtc,
struct drm_framebuffer *fb; struct drm_framebuffer *fb;
struct intel_framebuffer *intel_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); intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
if (!intel_fb) { if (!intel_fb) {
DRM_DEBUG_KMS("failed to alloc fb\n"); DRM_DEBUG_KMS("failed to alloc fb\n");
...@@ -7738,8 +7760,6 @@ ironlake_get_initial_plane_config(struct intel_crtc *crtc, ...@@ -7738,8 +7760,6 @@ ironlake_get_initial_plane_config(struct intel_crtc *crtc,
fb = &intel_fb->base; fb = &intel_fb->base;
val = I915_READ(DSPCNTR(pipe));
if (INTEL_INFO(dev)->gen >= 4) if (INTEL_INFO(dev)->gen >= 4)
if (val & DISPPLANE_TILED) if (val & DISPPLANE_TILED)
plane_config->tiling = I915_TILING_X; plane_config->tiling = I915_TILING_X;
...@@ -7778,6 +7798,7 @@ ironlake_get_initial_plane_config(struct intel_crtc *crtc, ...@@ -7778,6 +7798,7 @@ ironlake_get_initial_plane_config(struct intel_crtc *crtc,
plane_config->size); plane_config->size);
crtc->base.primary->fb = fb; crtc->base.primary->fb = fb;
update_state_fb(crtc->base.primary);
} }
static bool ironlake_get_pipe_config(struct intel_crtc *crtc, static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
...@@ -9816,6 +9837,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, ...@@ -9816,6 +9837,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
drm_gem_object_reference(&obj->base); drm_gem_object_reference(&obj->base);
crtc->primary->fb = fb; crtc->primary->fb = fb;
update_state_fb(crtc->primary);
work->pending_flip_obj = obj; work->pending_flip_obj = obj;
...@@ -9884,6 +9906,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, ...@@ -9884,6 +9906,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
cleanup_pending: cleanup_pending:
atomic_dec(&intel_crtc->unpin_work_count); atomic_dec(&intel_crtc->unpin_work_count);
crtc->primary->fb = old_fb; crtc->primary->fb = old_fb;
update_state_fb(crtc->primary);
drm_gem_object_unreference(&work->old_fb_obj->base); drm_gem_object_unreference(&work->old_fb_obj->base);
drm_gem_object_unreference(&obj->base); drm_gem_object_unreference(&obj->base);
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
...@@ -13718,6 +13741,7 @@ void intel_modeset_gem_init(struct drm_device *dev) ...@@ -13718,6 +13741,7 @@ void intel_modeset_gem_init(struct drm_device *dev)
to_intel_crtc(c)->pipe); to_intel_crtc(c)->pipe);
drm_framebuffer_unreference(c->primary->fb); drm_framebuffer_unreference(c->primary->fb);
c->primary->fb = NULL; c->primary->fb = NULL;
update_state_fb(c->primary);
} }
} }
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
......
...@@ -340,11 +340,13 @@ nvkm_devobj_ctor(struct nvkm_object *parent, struct nvkm_object *engine, ...@@ -340,11 +340,13 @@ nvkm_devobj_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
/* switch mmio to cpu's native endianness */ /* switch mmio to cpu's native endianness */
#ifndef __BIG_ENDIAN #ifndef __BIG_ENDIAN
if (ioread32_native(map + 0x000004) != 0x00000000) if (ioread32_native(map + 0x000004) != 0x00000000) {
#else #else
if (ioread32_native(map + 0x000004) == 0x00000000) if (ioread32_native(map + 0x000004) == 0x00000000) {
#endif #endif
iowrite32_native(0x01000001, map + 0x000004); iowrite32_native(0x01000001, map + 0x000004);
ioread32_native(map);
}
/* read boot0 and strapping information */ /* read boot0 and strapping information */
boot0 = ioread32_native(map + 0x000000); boot0 = ioread32_native(map + 0x000000);
......
...@@ -140,6 +140,49 @@ gm100_identify(struct nvkm_device *device) ...@@ -140,6 +140,49 @@ gm100_identify(struct nvkm_device *device)
device->oclass[NVDEV_ENGINE_MSVLD ] = &gk104_msvld_oclass; device->oclass[NVDEV_ENGINE_MSVLD ] = &gk104_msvld_oclass;
device->oclass[NVDEV_ENGINE_MSPDEC ] = &gk104_mspdec_oclass; device->oclass[NVDEV_ENGINE_MSPDEC ] = &gk104_mspdec_oclass;
device->oclass[NVDEV_ENGINE_MSPPP ] = &gf100_msppp_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 #endif
break; break;
default: default:
......
...@@ -502,72 +502,57 @@ nv04_fifo_intr(struct nvkm_subdev *subdev) ...@@ -502,72 +502,57 @@ nv04_fifo_intr(struct nvkm_subdev *subdev)
{ {
struct nvkm_device *device = nv_device(subdev); struct nvkm_device *device = nv_device(subdev);
struct nv04_fifo_priv *priv = (void *)subdev; struct nv04_fifo_priv *priv = (void *)subdev;
uint32_t status, reassign; u32 mask = nv_rd32(priv, NV03_PFIFO_INTR_EN_0);
int cnt = 0; u32 stat = nv_rd32(priv, NV03_PFIFO_INTR_0) & mask;
u32 reassign, chid, get, sem;
reassign = nv_rd32(priv, NV03_PFIFO_CACHES) & 1; reassign = nv_rd32(priv, NV03_PFIFO_CACHES) & 1;
while ((status = nv_rd32(priv, NV03_PFIFO_INTR_0)) && (cnt++ < 100)) { nv_wr32(priv, NV03_PFIFO_CACHES, 0);
uint32_t chid, get;
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);
if (status & NV_PFIFO_INTR_CACHE_ERROR) { chid = nv_rd32(priv, NV03_PFIFO_CACHE1_PUSH1) & priv->base.max;
nv04_fifo_cache_error(device, priv, chid, get); get = nv_rd32(priv, NV03_PFIFO_CACHE1_GET);
status &= ~NV_PFIFO_INTR_CACHE_ERROR;
}
if (status & NV_PFIFO_INTR_DMA_PUSHER) { if (stat & NV_PFIFO_INTR_CACHE_ERROR) {
nv04_fifo_dma_pusher(device, priv, chid); nv04_fifo_cache_error(device, priv, chid, get);
status &= ~NV_PFIFO_INTR_DMA_PUSHER; stat &= ~NV_PFIFO_INTR_CACHE_ERROR;
} }
if (status & NV_PFIFO_INTR_SEMAPHORE) { if (stat & NV_PFIFO_INTR_DMA_PUSHER) {
uint32_t sem; nv04_fifo_dma_pusher(device, priv, chid);
stat &= ~NV_PFIFO_INTR_DMA_PUSHER;
}
status &= ~NV_PFIFO_INTR_SEMAPHORE; if (stat & NV_PFIFO_INTR_SEMAPHORE) {
nv_wr32(priv, NV03_PFIFO_INTR_0, stat &= ~NV_PFIFO_INTR_SEMAPHORE;
NV_PFIFO_INTR_SEMAPHORE); nv_wr32(priv, NV03_PFIFO_INTR_0, NV_PFIFO_INTR_SEMAPHORE);
sem = nv_rd32(priv, NV10_PFIFO_CACHE1_SEMAPHORE); sem = nv_rd32(priv, NV10_PFIFO_CACHE1_SEMAPHORE);
nv_wr32(priv, NV10_PFIFO_CACHE1_SEMAPHORE, sem | 0x1); nv_wr32(priv, NV10_PFIFO_CACHE1_SEMAPHORE, sem | 0x1);
nv_wr32(priv, NV03_PFIFO_CACHE1_GET, get + 4); nv_wr32(priv, NV03_PFIFO_CACHE1_GET, get + 4);
nv_wr32(priv, NV04_PFIFO_CACHE1_PULL0, 1); nv_wr32(priv, NV04_PFIFO_CACHE1_PULL0, 1);
} }
if (device->card_type == NV_50) { if (device->card_type == NV_50) {
if (status & 0x00000010) { if (stat & 0x00000010) {
status &= ~0x00000010; stat &= ~0x00000010;
nv_wr32(priv, 0x002100, 0x00000010); nv_wr32(priv, 0x002100, 0x00000010);
}
if (status & 0x40000000) {
nv_wr32(priv, 0x002100, 0x40000000);
nvkm_fifo_uevent(&priv->base);
status &= ~0x40000000;
}
} }
if (status) { if (stat & 0x40000000) {
nv_warn(priv, "unknown intr 0x%08x, ch %d\n", nv_wr32(priv, 0x002100, 0x40000000);
status, chid); nvkm_fifo_uevent(&priv->base);
nv_wr32(priv, NV03_PFIFO_INTR_0, status); stat &= ~0x40000000;
status = 0;
} }
nv_wr32(priv, NV03_PFIFO_CACHES, reassign);
} }
if (status) { if (stat) {
nv_error(priv, "still angry after %d spins, halt\n", cnt); nv_warn(priv, "unknown intr 0x%08x\n", stat);
nv_wr32(priv, 0x002140, 0); nv_mask(priv, NV03_PFIFO_INTR_EN_0, stat, 0x00000000);
nv_wr32(priv, 0x000140, 0); nv_wr32(priv, NV03_PFIFO_INTR_0, stat);
} }
nv_wr32(priv, 0x000100, 0x00000100); nv_wr32(priv, NV03_PFIFO_CACHES, reassign);
} }
static int static int
......
...@@ -1032,9 +1032,9 @@ gf100_grctx_generate_bundle(struct gf100_grctx *info) ...@@ -1032,9 +1032,9 @@ gf100_grctx_generate_bundle(struct gf100_grctx *info)
const int s = 8; const int s = 8;
const int b = mmio_vram(info, impl->bundle_size, (1 << s), access); const int b = mmio_vram(info, impl->bundle_size, (1 << s), access);
mmio_refn(info, 0x408004, 0x00000000, s, b); 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, 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 void
......
...@@ -851,9 +851,9 @@ gk104_grctx_generate_bundle(struct gf100_grctx *info) ...@@ -851,9 +851,9 @@ gk104_grctx_generate_bundle(struct gf100_grctx *info)
const int s = 8; const int s = 8;
const int b = mmio_vram(info, impl->bundle_size, (1 << s), access); const int b = mmio_vram(info, impl->bundle_size, (1 << s), access);
mmio_refn(info, 0x408004, 0x00000000, s, b); 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, 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); mmio_wr32(info, 0x4064c8, (state_limit << 16) | token_limit);
} }
......
...@@ -871,9 +871,9 @@ gm107_grctx_generate_bundle(struct gf100_grctx *info) ...@@ -871,9 +871,9 @@ gm107_grctx_generate_bundle(struct gf100_grctx *info)
const int s = 8; const int s = 8;
const int b = mmio_vram(info, impl->bundle_size, (1 << s), access); const int b = mmio_vram(info, impl->bundle_size, (1 << s), access);
mmio_refn(info, 0x408004, 0x00000000, s, b); 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, 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); 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) ...@@ -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); u16 ent = dcb_i2c_entry(bios, idx, &ver, &len);
if (ent) { if (ent) {
if (ver >= 0x41) { 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; info->type = DCB_I2C_UNUSED;
else else
info->type = DCB_I2C_PMGR; info->type = DCB_I2C_PMGR;
......
...@@ -153,7 +153,7 @@ void radeon_kfd_device_init(struct radeon_device *rdev) ...@@ -153,7 +153,7 @@ void radeon_kfd_device_init(struct radeon_device *rdev)
.compute_vmid_bitmap = 0xFF00, .compute_vmid_bitmap = 0xFF00,
.first_compute_pipe = 1, .first_compute_pipe = 1,
.compute_pipe_count = 8 - 1, .compute_pipe_count = 4 - 1,
}; };
radeon_doorbell_get_kfd_info(rdev, radeon_doorbell_get_kfd_info(rdev,
......
...@@ -173,17 +173,6 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain) ...@@ -173,17 +173,6 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain)
else else
rbo->placements[i].lpfn = 0; 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, int radeon_bo_create(struct radeon_device *rdev,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment