提交 5e0e7a40 编写于 作者: D Dave Airlie

Merge tag 'drm-misc-fixes-2021-06-24' of git://anongit.freedesktop.org/drm/drm-misc into drm-fixes

A DMA address check for nouveau, an error code return fix for kmb, fixes
to wait for a moving fence after pinning the BO for amdgpu, nouveau and
radeon, a crtc and async page flip fix for atmel-hlcdc and a cpu hang
fix for vc4.
Signed-off-by: NDave Airlie <airlied@redhat.com>

From: Maxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20210624190353.wyizoil3wqrrxz5d@gilmour
...@@ -214,9 +214,21 @@ static int amdgpu_dma_buf_pin(struct dma_buf_attachment *attach) ...@@ -214,9 +214,21 @@ static int amdgpu_dma_buf_pin(struct dma_buf_attachment *attach)
{ {
struct drm_gem_object *obj = attach->dmabuf->priv; struct drm_gem_object *obj = attach->dmabuf->priv;
struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj); struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
int r;
/* pin buffer into GTT */ /* pin buffer into GTT */
return amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_GTT); r = amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_GTT);
if (r)
return r;
if (bo->tbo.moving) {
r = dma_fence_wait(bo->tbo.moving, true);
if (r) {
amdgpu_bo_unpin(bo);
return r;
}
}
return 0;
} }
/** /**
......
...@@ -232,7 +232,6 @@ static void atmel_hlcdc_crtc_atomic_enable(struct drm_crtc *c, ...@@ -232,7 +232,6 @@ static void atmel_hlcdc_crtc_atomic_enable(struct drm_crtc *c,
pm_runtime_put_sync(dev->dev); pm_runtime_put_sync(dev->dev);
drm_crtc_vblank_on(c);
} }
#define ATMEL_HLCDC_RGB444_OUTPUT BIT(0) #define ATMEL_HLCDC_RGB444_OUTPUT BIT(0)
...@@ -343,8 +342,17 @@ static int atmel_hlcdc_crtc_atomic_check(struct drm_crtc *c, ...@@ -343,8 +342,17 @@ static int atmel_hlcdc_crtc_atomic_check(struct drm_crtc *c,
static void atmel_hlcdc_crtc_atomic_begin(struct drm_crtc *c, static void atmel_hlcdc_crtc_atomic_begin(struct drm_crtc *c,
struct drm_atomic_state *state) struct drm_atomic_state *state)
{
drm_crtc_vblank_on(c);
}
static void atmel_hlcdc_crtc_atomic_flush(struct drm_crtc *c,
struct drm_atomic_state *state)
{ {
struct atmel_hlcdc_crtc *crtc = drm_crtc_to_atmel_hlcdc_crtc(c); struct atmel_hlcdc_crtc *crtc = drm_crtc_to_atmel_hlcdc_crtc(c);
unsigned long flags;
spin_lock_irqsave(&c->dev->event_lock, flags);
if (c->state->event) { if (c->state->event) {
c->state->event->pipe = drm_crtc_index(c); c->state->event->pipe = drm_crtc_index(c);
...@@ -354,12 +362,7 @@ static void atmel_hlcdc_crtc_atomic_begin(struct drm_crtc *c, ...@@ -354,12 +362,7 @@ static void atmel_hlcdc_crtc_atomic_begin(struct drm_crtc *c,
crtc->event = c->state->event; crtc->event = c->state->event;
c->state->event = NULL; c->state->event = NULL;
} }
} spin_unlock_irqrestore(&c->dev->event_lock, flags);
static void atmel_hlcdc_crtc_atomic_flush(struct drm_crtc *crtc,
struct drm_atomic_state *state)
{
/* TODO: write common plane control register if available */
} }
static const struct drm_crtc_helper_funcs lcdc_crtc_helper_funcs = { static const struct drm_crtc_helper_funcs lcdc_crtc_helper_funcs = {
......
...@@ -593,6 +593,7 @@ static int atmel_hlcdc_dc_modeset_init(struct drm_device *dev) ...@@ -593,6 +593,7 @@ static int atmel_hlcdc_dc_modeset_init(struct drm_device *dev)
dev->mode_config.max_width = dc->desc->max_width; dev->mode_config.max_width = dc->desc->max_width;
dev->mode_config.max_height = dc->desc->max_height; dev->mode_config.max_height = dc->desc->max_height;
dev->mode_config.funcs = &mode_config_funcs; dev->mode_config.funcs = &mode_config_funcs;
dev->mode_config.async_page_flip = true;
return 0; return 0;
} }
......
...@@ -137,6 +137,7 @@ static int kmb_hw_init(struct drm_device *drm, unsigned long flags) ...@@ -137,6 +137,7 @@ static int kmb_hw_init(struct drm_device *drm, unsigned long flags)
/* Allocate LCD interrupt resources */ /* Allocate LCD interrupt resources */
irq_lcd = platform_get_irq(pdev, 0); irq_lcd = platform_get_irq(pdev, 0);
if (irq_lcd < 0) { if (irq_lcd < 0) {
ret = irq_lcd;
drm_err(&kmb->drm, "irq_lcd not found"); drm_err(&kmb->drm, "irq_lcd not found");
goto setup_fail; goto setup_fail;
} }
......
...@@ -546,7 +546,7 @@ nouveau_bo_sync_for_device(struct nouveau_bo *nvbo) ...@@ -546,7 +546,7 @@ nouveau_bo_sync_for_device(struct nouveau_bo *nvbo)
struct ttm_tt *ttm_dma = (struct ttm_tt *)nvbo->bo.ttm; struct ttm_tt *ttm_dma = (struct ttm_tt *)nvbo->bo.ttm;
int i, j; int i, j;
if (!ttm_dma) if (!ttm_dma || !ttm_dma->dma_address)
return; return;
if (!ttm_dma->pages) { if (!ttm_dma->pages) {
NV_DEBUG(drm, "ttm_dma 0x%p: pages NULL\n", ttm_dma); NV_DEBUG(drm, "ttm_dma 0x%p: pages NULL\n", ttm_dma);
...@@ -582,7 +582,7 @@ nouveau_bo_sync_for_cpu(struct nouveau_bo *nvbo) ...@@ -582,7 +582,7 @@ nouveau_bo_sync_for_cpu(struct nouveau_bo *nvbo)
struct ttm_tt *ttm_dma = (struct ttm_tt *)nvbo->bo.ttm; struct ttm_tt *ttm_dma = (struct ttm_tt *)nvbo->bo.ttm;
int i, j; int i, j;
if (!ttm_dma) if (!ttm_dma || !ttm_dma->dma_address)
return; return;
if (!ttm_dma->pages) { if (!ttm_dma->pages) {
NV_DEBUG(drm, "ttm_dma 0x%p: pages NULL\n", ttm_dma); NV_DEBUG(drm, "ttm_dma 0x%p: pages NULL\n", ttm_dma);
......
...@@ -93,7 +93,22 @@ int nouveau_gem_prime_pin(struct drm_gem_object *obj) ...@@ -93,7 +93,22 @@ int nouveau_gem_prime_pin(struct drm_gem_object *obj)
if (ret) if (ret)
return -EINVAL; return -EINVAL;
return 0; ret = ttm_bo_reserve(&nvbo->bo, false, false, NULL);
if (ret)
goto error;
if (nvbo->bo.moving)
ret = dma_fence_wait(nvbo->bo.moving, true);
ttm_bo_unreserve(&nvbo->bo);
if (ret)
goto error;
return ret;
error:
nouveau_bo_unpin(nvbo);
return ret;
} }
void nouveau_gem_prime_unpin(struct drm_gem_object *obj) void nouveau_gem_prime_unpin(struct drm_gem_object *obj)
......
...@@ -383,6 +383,7 @@ MODULE_DEVICE_TABLE(spi, ld9040_ids); ...@@ -383,6 +383,7 @@ MODULE_DEVICE_TABLE(spi, ld9040_ids);
static struct spi_driver ld9040_driver = { static struct spi_driver ld9040_driver = {
.probe = ld9040_probe, .probe = ld9040_probe,
.remove = ld9040_remove, .remove = ld9040_remove,
.id_table = ld9040_ids,
.driver = { .driver = {
.name = "panel-samsung-ld9040", .name = "panel-samsung-ld9040",
.of_match_table = ld9040_of_match, .of_match_table = ld9040_of_match,
......
...@@ -77,9 +77,19 @@ int radeon_gem_prime_pin(struct drm_gem_object *obj) ...@@ -77,9 +77,19 @@ int radeon_gem_prime_pin(struct drm_gem_object *obj)
/* pin buffer into GTT */ /* pin buffer into GTT */
ret = radeon_bo_pin(bo, RADEON_GEM_DOMAIN_GTT, NULL); ret = radeon_bo_pin(bo, RADEON_GEM_DOMAIN_GTT, NULL);
if (likely(ret == 0)) if (unlikely(ret))
bo->prime_shared_count++; goto error;
if (bo->tbo.moving) {
ret = dma_fence_wait(bo->tbo.moving, false);
if (unlikely(ret)) {
radeon_bo_unpin(bo);
goto error;
}
}
bo->prime_shared_count++;
error:
radeon_bo_unreserve(bo); radeon_bo_unreserve(bo);
return ret; return ret;
} }
......
...@@ -159,6 +159,8 @@ vc4_hdmi_connector_detect(struct drm_connector *connector, bool force) ...@@ -159,6 +159,8 @@ vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)
struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector); struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
bool connected = false; bool connected = false;
WARN_ON(pm_runtime_resume_and_get(&vc4_hdmi->pdev->dev));
if (vc4_hdmi->hpd_gpio) { if (vc4_hdmi->hpd_gpio) {
if (gpio_get_value_cansleep(vc4_hdmi->hpd_gpio) ^ if (gpio_get_value_cansleep(vc4_hdmi->hpd_gpio) ^
vc4_hdmi->hpd_active_low) vc4_hdmi->hpd_active_low)
...@@ -180,10 +182,12 @@ vc4_hdmi_connector_detect(struct drm_connector *connector, bool force) ...@@ -180,10 +182,12 @@ vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)
} }
} }
pm_runtime_put(&vc4_hdmi->pdev->dev);
return connector_status_connected; return connector_status_connected;
} }
cec_phys_addr_invalidate(vc4_hdmi->cec_adap); cec_phys_addr_invalidate(vc4_hdmi->cec_adap);
pm_runtime_put(&vc4_hdmi->pdev->dev);
return connector_status_disconnected; return connector_status_disconnected;
} }
...@@ -473,7 +477,6 @@ static void vc4_hdmi_encoder_post_crtc_powerdown(struct drm_encoder *encoder, ...@@ -473,7 +477,6 @@ static void vc4_hdmi_encoder_post_crtc_powerdown(struct drm_encoder *encoder,
HDMI_READ(HDMI_VID_CTL) & ~VC4_HD_VID_CTL_ENABLE); HDMI_READ(HDMI_VID_CTL) & ~VC4_HD_VID_CTL_ENABLE);
clk_disable_unprepare(vc4_hdmi->pixel_bvb_clock); clk_disable_unprepare(vc4_hdmi->pixel_bvb_clock);
clk_disable_unprepare(vc4_hdmi->hsm_clock);
clk_disable_unprepare(vc4_hdmi->pixel_clock); clk_disable_unprepare(vc4_hdmi->pixel_clock);
ret = pm_runtime_put(&vc4_hdmi->pdev->dev); ret = pm_runtime_put(&vc4_hdmi->pdev->dev);
...@@ -784,13 +787,6 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder, ...@@ -784,13 +787,6 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder,
return; return;
} }
ret = clk_prepare_enable(vc4_hdmi->hsm_clock);
if (ret) {
DRM_ERROR("Failed to turn on HSM clock: %d\n", ret);
clk_disable_unprepare(vc4_hdmi->pixel_clock);
return;
}
vc4_hdmi_cec_update_clk_div(vc4_hdmi); vc4_hdmi_cec_update_clk_div(vc4_hdmi);
/* /*
...@@ -801,7 +797,6 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder, ...@@ -801,7 +797,6 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder,
(hsm_rate > VC4_HSM_MID_CLOCK ? 150000000 : 75000000)); (hsm_rate > VC4_HSM_MID_CLOCK ? 150000000 : 75000000));
if (ret) { if (ret) {
DRM_ERROR("Failed to set pixel bvb clock rate: %d\n", ret); DRM_ERROR("Failed to set pixel bvb clock rate: %d\n", ret);
clk_disable_unprepare(vc4_hdmi->hsm_clock);
clk_disable_unprepare(vc4_hdmi->pixel_clock); clk_disable_unprepare(vc4_hdmi->pixel_clock);
return; return;
} }
...@@ -809,7 +804,6 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder, ...@@ -809,7 +804,6 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder,
ret = clk_prepare_enable(vc4_hdmi->pixel_bvb_clock); ret = clk_prepare_enable(vc4_hdmi->pixel_bvb_clock);
if (ret) { if (ret) {
DRM_ERROR("Failed to turn on pixel bvb clock: %d\n", ret); DRM_ERROR("Failed to turn on pixel bvb clock: %d\n", ret);
clk_disable_unprepare(vc4_hdmi->hsm_clock);
clk_disable_unprepare(vc4_hdmi->pixel_clock); clk_disable_unprepare(vc4_hdmi->pixel_clock);
return; return;
} }
...@@ -1929,6 +1923,29 @@ static int vc5_hdmi_init_resources(struct vc4_hdmi *vc4_hdmi) ...@@ -1929,6 +1923,29 @@ static int vc5_hdmi_init_resources(struct vc4_hdmi *vc4_hdmi)
return 0; return 0;
} }
#ifdef CONFIG_PM
static int vc4_hdmi_runtime_suspend(struct device *dev)
{
struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
clk_disable_unprepare(vc4_hdmi->hsm_clock);
return 0;
}
static int vc4_hdmi_runtime_resume(struct device *dev)
{
struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
int ret;
ret = clk_prepare_enable(vc4_hdmi->hsm_clock);
if (ret)
return ret;
return 0;
}
#endif
static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data) static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
{ {
const struct vc4_hdmi_variant *variant = of_device_get_match_data(dev); const struct vc4_hdmi_variant *variant = of_device_get_match_data(dev);
...@@ -2165,11 +2182,18 @@ static const struct of_device_id vc4_hdmi_dt_match[] = { ...@@ -2165,11 +2182,18 @@ static const struct of_device_id vc4_hdmi_dt_match[] = {
{} {}
}; };
static const struct dev_pm_ops vc4_hdmi_pm_ops = {
SET_RUNTIME_PM_OPS(vc4_hdmi_runtime_suspend,
vc4_hdmi_runtime_resume,
NULL)
};
struct platform_driver vc4_hdmi_driver = { struct platform_driver vc4_hdmi_driver = {
.probe = vc4_hdmi_dev_probe, .probe = vc4_hdmi_dev_probe,
.remove = vc4_hdmi_dev_remove, .remove = vc4_hdmi_dev_remove,
.driver = { .driver = {
.name = "vc4_hdmi", .name = "vc4_hdmi",
.of_match_table = vc4_hdmi_dt_match, .of_match_table = vc4_hdmi_dt_match,
.pm = &vc4_hdmi_pm_ops,
}, },
}; };
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册