diff options
Diffstat (limited to 'drivers/gpu')
66 files changed, 537 insertions, 282 deletions
diff --git a/drivers/gpu/drm/ast/ast_ttm.c b/drivers/gpu/drm/ast/ast_ttm.c index 98d670825a1a..6e8887fe6c1b 100644 --- a/drivers/gpu/drm/ast/ast_ttm.c +++ b/drivers/gpu/drm/ast/ast_ttm.c | |||
@@ -323,6 +323,7 @@ int ast_bo_create(struct drm_device *dev, int size, int align, | |||
323 | 323 | ||
324 | astbo->gem.driver_private = NULL; | 324 | astbo->gem.driver_private = NULL; |
325 | astbo->bo.bdev = &ast->ttm.bdev; | 325 | astbo->bo.bdev = &ast->ttm.bdev; |
326 | astbo->bo.bdev->dev_mapping = dev->dev_mapping; | ||
326 | 327 | ||
327 | ast_ttm_placement(astbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM); | 328 | ast_ttm_placement(astbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM); |
328 | 329 | ||
diff --git a/drivers/gpu/drm/cirrus/cirrus_ttm.c b/drivers/gpu/drm/cirrus/cirrus_ttm.c index 0047012045c2..69fd8f1ac8df 100644 --- a/drivers/gpu/drm/cirrus/cirrus_ttm.c +++ b/drivers/gpu/drm/cirrus/cirrus_ttm.c | |||
@@ -328,6 +328,7 @@ int cirrus_bo_create(struct drm_device *dev, int size, int align, | |||
328 | 328 | ||
329 | cirrusbo->gem.driver_private = NULL; | 329 | cirrusbo->gem.driver_private = NULL; |
330 | cirrusbo->bo.bdev = &cirrus->ttm.bdev; | 330 | cirrusbo->bo.bdev = &cirrus->ttm.bdev; |
331 | cirrusbo->bo.bdev->dev_mapping = dev->dev_mapping; | ||
331 | 332 | ||
332 | cirrus_ttm_placement(cirrusbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM); | 333 | cirrus_ttm_placement(cirrusbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM); |
333 | 334 | ||
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 8bcce7866d36..f92da0a32f0d 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
@@ -708,7 +708,10 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc, | |||
708 | /* Subtract time delta from raw timestamp to get final | 708 | /* Subtract time delta from raw timestamp to get final |
709 | * vblank_time timestamp for end of vblank. | 709 | * vblank_time timestamp for end of vblank. |
710 | */ | 710 | */ |
711 | etime = ktime_sub_ns(etime, delta_ns); | 711 | if (delta_ns < 0) |
712 | etime = ktime_add_ns(etime, -delta_ns); | ||
713 | else | ||
714 | etime = ktime_sub_ns(etime, delta_ns); | ||
712 | *vblank_time = ktime_to_timeval(etime); | 715 | *vblank_time = ktime_to_timeval(etime); |
713 | 716 | ||
714 | DRM_DEBUG("crtc %d : v %d p(%d,%d)@ %ld.%ld -> %ld.%ld [e %d us, %d rep]\n", | 717 | DRM_DEBUG("crtc %d : v %d p(%d,%d)@ %ld.%ld -> %ld.%ld [e %d us, %d rep]\n", |
diff --git a/drivers/gpu/drm/exynos/exynos_ddc.c b/drivers/gpu/drm/exynos/exynos_ddc.c index 95c75edef01a..30ef41bcd7b8 100644 --- a/drivers/gpu/drm/exynos/exynos_ddc.c +++ b/drivers/gpu/drm/exynos/exynos_ddc.c | |||
@@ -15,7 +15,6 @@ | |||
15 | 15 | ||
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/i2c.h> | 17 | #include <linux/i2c.h> |
18 | #include <linux/module.h> | ||
19 | 18 | ||
20 | 19 | ||
21 | #include "exynos_drm_drv.h" | 20 | #include "exynos_drm_drv.h" |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c index 61b094f689a7..6e047bd53e2f 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c | |||
@@ -12,7 +12,6 @@ | |||
12 | * | 12 | * |
13 | */ | 13 | */ |
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/module.h> | ||
16 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
17 | #include <linux/mfd/syscon.h> | 16 | #include <linux/mfd/syscon.h> |
18 | #include <linux/regmap.h> | 17 | #include <linux/regmap.h> |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 3e106beca5b6..1c263dac3c1c 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <drm/drmP.h> | 14 | #include <drm/drmP.h> |
15 | 15 | ||
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/module.h> | ||
18 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
19 | #include <linux/clk.h> | 18 | #include <linux/clk.h> |
20 | #include <linux/of_device.h> | 19 | #include <linux/of_device.h> |
@@ -130,7 +129,6 @@ static const struct of_device_id fimd_driver_dt_match[] = { | |||
130 | .data = &exynos5_fimd_driver_data }, | 129 | .data = &exynos5_fimd_driver_data }, |
131 | {}, | 130 | {}, |
132 | }; | 131 | }; |
133 | MODULE_DEVICE_TABLE(of, fimd_driver_dt_match); | ||
134 | #endif | 132 | #endif |
135 | 133 | ||
136 | static inline struct fimd_driver_data *drm_fimd_get_driver_data( | 134 | static inline struct fimd_driver_data *drm_fimd_get_driver_data( |
@@ -1082,7 +1080,6 @@ static struct platform_device_id fimd_driver_ids[] = { | |||
1082 | }, | 1080 | }, |
1083 | {}, | 1081 | {}, |
1084 | }; | 1082 | }; |
1085 | MODULE_DEVICE_TABLE(platform, fimd_driver_ids); | ||
1086 | 1083 | ||
1087 | static const struct dev_pm_ops fimd_pm_ops = { | 1084 | static const struct dev_pm_ops fimd_pm_ops = { |
1088 | SET_SYSTEM_SLEEP_PM_OPS(fimd_suspend, fimd_resume) | 1085 | SET_SYSTEM_SLEEP_PM_OPS(fimd_suspend, fimd_resume) |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c index 42a5a5466075..eddea4941483 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c | |||
@@ -8,7 +8,6 @@ | |||
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
11 | #include <linux/module.h> | ||
12 | #include <linux/clk.h> | 11 | #include <linux/clk.h> |
13 | #include <linux/err.h> | 12 | #include <linux/err.h> |
14 | #include <linux/interrupt.h> | 13 | #include <linux/interrupt.h> |
@@ -806,9 +805,20 @@ static void g2d_dma_start(struct g2d_data *g2d, | |||
806 | struct g2d_cmdlist_node *node = | 805 | struct g2d_cmdlist_node *node = |
807 | list_first_entry(&runqueue_node->run_cmdlist, | 806 | list_first_entry(&runqueue_node->run_cmdlist, |
808 | struct g2d_cmdlist_node, list); | 807 | struct g2d_cmdlist_node, list); |
808 | int ret; | ||
809 | |||
810 | ret = pm_runtime_get_sync(g2d->dev); | ||
811 | if (ret < 0) { | ||
812 | dev_warn(g2d->dev, "failed pm power on.\n"); | ||
813 | return; | ||
814 | } | ||
809 | 815 | ||
810 | pm_runtime_get_sync(g2d->dev); | 816 | ret = clk_prepare_enable(g2d->gate_clk); |
811 | clk_enable(g2d->gate_clk); | 817 | if (ret < 0) { |
818 | dev_warn(g2d->dev, "failed to enable clock.\n"); | ||
819 | pm_runtime_put_sync(g2d->dev); | ||
820 | return; | ||
821 | } | ||
812 | 822 | ||
813 | writel_relaxed(node->dma_addr, g2d->regs + G2D_DMA_SFR_BASE_ADDR); | 823 | writel_relaxed(node->dma_addr, g2d->regs + G2D_DMA_SFR_BASE_ADDR); |
814 | writel_relaxed(G2D_DMA_START, g2d->regs + G2D_DMA_COMMAND); | 824 | writel_relaxed(G2D_DMA_START, g2d->regs + G2D_DMA_COMMAND); |
@@ -861,7 +871,7 @@ static void g2d_runqueue_worker(struct work_struct *work) | |||
861 | runqueue_work); | 871 | runqueue_work); |
862 | 872 | ||
863 | mutex_lock(&g2d->runqueue_mutex); | 873 | mutex_lock(&g2d->runqueue_mutex); |
864 | clk_disable(g2d->gate_clk); | 874 | clk_disable_unprepare(g2d->gate_clk); |
865 | pm_runtime_put_sync(g2d->dev); | 875 | pm_runtime_put_sync(g2d->dev); |
866 | 876 | ||
867 | complete(&g2d->runqueue_node->complete); | 877 | complete(&g2d->runqueue_node->complete); |
@@ -1521,7 +1531,6 @@ static const struct of_device_id exynos_g2d_match[] = { | |||
1521 | { .compatible = "samsung,exynos5250-g2d" }, | 1531 | { .compatible = "samsung,exynos5250-g2d" }, |
1522 | {}, | 1532 | {}, |
1523 | }; | 1533 | }; |
1524 | MODULE_DEVICE_TABLE(of, exynos_g2d_match); | ||
1525 | #endif | 1534 | #endif |
1526 | 1535 | ||
1527 | struct platform_driver g2d_driver = { | 1536 | struct platform_driver g2d_driver = { |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c index 472e3b25e7f2..90b8a1a5344c 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c | |||
@@ -12,7 +12,6 @@ | |||
12 | * | 12 | * |
13 | */ | 13 | */ |
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/module.h> | ||
16 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
17 | #include <linux/clk.h> | 16 | #include <linux/clk.h> |
18 | #include <linux/pm_runtime.h> | 17 | #include <linux/pm_runtime.h> |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c index aaa550d622f0..8d3bc01d6834 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c | |||
@@ -15,7 +15,6 @@ | |||
15 | 15 | ||
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/wait.h> | 17 | #include <linux/wait.h> |
18 | #include <linux/module.h> | ||
19 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
20 | #include <linux/pm_runtime.h> | 19 | #include <linux/pm_runtime.h> |
21 | 20 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c index b1ef8e7ff9c9..d2b6ab4def93 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c | |||
@@ -12,7 +12,6 @@ | |||
12 | * | 12 | * |
13 | */ | 13 | */ |
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/module.h> | ||
16 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
17 | #include <linux/types.h> | 16 | #include <linux/types.h> |
18 | #include <linux/clk.h> | 17 | #include <linux/clk.h> |
@@ -342,10 +341,10 @@ int exynos_drm_ipp_get_property(struct drm_device *drm_dev, void *data, | |||
342 | */ | 341 | */ |
343 | ippdrv = ipp_find_obj(&ctx->ipp_idr, &ctx->ipp_lock, | 342 | ippdrv = ipp_find_obj(&ctx->ipp_idr, &ctx->ipp_lock, |
344 | prop_list->ipp_id); | 343 | prop_list->ipp_id); |
345 | if (!ippdrv) { | 344 | if (IS_ERR(ippdrv)) { |
346 | DRM_ERROR("not found ipp%d driver.\n", | 345 | DRM_ERROR("not found ipp%d driver.\n", |
347 | prop_list->ipp_id); | 346 | prop_list->ipp_id); |
348 | return -EINVAL; | 347 | return PTR_ERR(ippdrv); |
349 | } | 348 | } |
350 | 349 | ||
351 | prop_list = ippdrv->prop_list; | 350 | prop_list = ippdrv->prop_list; |
@@ -970,9 +969,9 @@ int exynos_drm_ipp_queue_buf(struct drm_device *drm_dev, void *data, | |||
970 | /* find command node */ | 969 | /* find command node */ |
971 | c_node = ipp_find_obj(&ctx->prop_idr, &ctx->prop_lock, | 970 | c_node = ipp_find_obj(&ctx->prop_idr, &ctx->prop_lock, |
972 | qbuf->prop_id); | 971 | qbuf->prop_id); |
973 | if (!c_node) { | 972 | if (IS_ERR(c_node)) { |
974 | DRM_ERROR("failed to get command node.\n"); | 973 | DRM_ERROR("failed to get command node.\n"); |
975 | return -EFAULT; | 974 | return PTR_ERR(c_node); |
976 | } | 975 | } |
977 | 976 | ||
978 | /* buffer control */ | 977 | /* buffer control */ |
@@ -1106,9 +1105,9 @@ int exynos_drm_ipp_cmd_ctrl(struct drm_device *drm_dev, void *data, | |||
1106 | 1105 | ||
1107 | c_node = ipp_find_obj(&ctx->prop_idr, &ctx->prop_lock, | 1106 | c_node = ipp_find_obj(&ctx->prop_idr, &ctx->prop_lock, |
1108 | cmd_ctrl->prop_id); | 1107 | cmd_ctrl->prop_id); |
1109 | if (!c_node) { | 1108 | if (IS_ERR(c_node)) { |
1110 | DRM_ERROR("invalid command node list.\n"); | 1109 | DRM_ERROR("invalid command node list.\n"); |
1111 | return -EINVAL; | 1110 | return PTR_ERR(c_node); |
1112 | } | 1111 | } |
1113 | 1112 | ||
1114 | if (!exynos_drm_ipp_check_valid(ippdrv->dev, cmd_ctrl->ctrl, | 1113 | if (!exynos_drm_ipp_check_valid(ippdrv->dev, cmd_ctrl->ctrl, |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_rotator.c b/drivers/gpu/drm/exynos/exynos_drm_rotator.c index 427640aa5148..49669aa24c45 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_rotator.c +++ b/drivers/gpu/drm/exynos/exynos_drm_rotator.c | |||
@@ -10,7 +10,6 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/module.h> | ||
14 | #include <linux/err.h> | 13 | #include <linux/err.h> |
15 | #include <linux/interrupt.h> | 14 | #include <linux/interrupt.h> |
16 | #include <linux/io.h> | 15 | #include <linux/io.h> |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index 41cc74d83e4e..c57c56519add 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <drm/drmP.h> | 13 | #include <drm/drmP.h> |
14 | 14 | ||
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/module.h> | ||
17 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
18 | 17 | ||
19 | #include <drm/exynos_drm.h> | 18 | #include <drm/exynos_drm.h> |
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 62ef5971ac3c..2f5c6942c968 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/spinlock.h> | 24 | #include <linux/spinlock.h> |
25 | #include <linux/wait.h> | 25 | #include <linux/wait.h> |
26 | #include <linux/i2c.h> | 26 | #include <linux/i2c.h> |
27 | #include <linux/module.h> | ||
28 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
29 | #include <linux/interrupt.h> | 28 | #include <linux/interrupt.h> |
30 | #include <linux/irq.h> | 29 | #include <linux/irq.h> |
diff --git a/drivers/gpu/drm/exynos/exynos_hdmiphy.c b/drivers/gpu/drm/exynos/exynos_hdmiphy.c index ef04255076c7..6e320ae9afed 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmiphy.c +++ b/drivers/gpu/drm/exynos/exynos_hdmiphy.c | |||
@@ -15,7 +15,6 @@ | |||
15 | 15 | ||
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/i2c.h> | 17 | #include <linux/i2c.h> |
18 | #include <linux/module.h> | ||
19 | 18 | ||
20 | #include "exynos_drm_drv.h" | 19 | #include "exynos_drm_drv.h" |
21 | #include "exynos_hdmi.h" | 20 | #include "exynos_hdmi.h" |
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index 42ffb71c63bc..c9a137caea41 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <linux/spinlock.h> | 23 | #include <linux/spinlock.h> |
24 | #include <linux/wait.h> | 24 | #include <linux/wait.h> |
25 | #include <linux/i2c.h> | 25 | #include <linux/i2c.h> |
26 | #include <linux/module.h> | ||
27 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
28 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
29 | #include <linux/irq.h> | 28 | #include <linux/irq.h> |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 66c63808fa35..f4669802a0fb 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -1594,6 +1594,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1594 | intel_detect_pch(dev); | 1594 | intel_detect_pch(dev); |
1595 | 1595 | ||
1596 | intel_irq_init(dev); | 1596 | intel_irq_init(dev); |
1597 | intel_pm_init(dev); | ||
1597 | intel_gt_sanitize(dev); | 1598 | intel_gt_sanitize(dev); |
1598 | intel_gt_init(dev); | 1599 | intel_gt_init(dev); |
1599 | 1600 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d2ee3343c943..1929bffc1c77 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -1582,6 +1582,7 @@ void i915_hangcheck_elapsed(unsigned long data); | |||
1582 | void i915_handle_error(struct drm_device *dev, bool wedged); | 1582 | void i915_handle_error(struct drm_device *dev, bool wedged); |
1583 | 1583 | ||
1584 | extern void intel_irq_init(struct drm_device *dev); | 1584 | extern void intel_irq_init(struct drm_device *dev); |
1585 | extern void intel_pm_init(struct drm_device *dev); | ||
1585 | extern void intel_hpd_init(struct drm_device *dev); | 1586 | extern void intel_hpd_init(struct drm_device *dev); |
1586 | extern void intel_gt_init(struct drm_device *dev); | 1587 | extern void intel_gt_init(struct drm_device *dev); |
1587 | extern void intel_gt_sanitize(struct drm_device *dev); | 1588 | extern void intel_gt_sanitize(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index f2326fc60ac9..6f514297c483 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -1856,10 +1856,16 @@ | |||
1856 | #define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2) | 1856 | #define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2) |
1857 | 1857 | ||
1858 | #define PORT_HOTPLUG_STAT (dev_priv->info->display_mmio_offset + 0x61114) | 1858 | #define PORT_HOTPLUG_STAT (dev_priv->info->display_mmio_offset + 0x61114) |
1859 | /* HDMI/DP bits are gen4+ */ | 1859 | /* |
1860 | #define PORTB_HOTPLUG_LIVE_STATUS (1 << 29) | 1860 | * HDMI/DP bits are gen4+ |
1861 | * | ||
1862 | * WARNING: Bspec for hpd status bits on gen4 seems to be completely confused. | ||
1863 | * Please check the detailed lore in the commit message for for experimental | ||
1864 | * evidence. | ||
1865 | */ | ||
1866 | #define PORTD_HOTPLUG_LIVE_STATUS (1 << 29) | ||
1861 | #define PORTC_HOTPLUG_LIVE_STATUS (1 << 28) | 1867 | #define PORTC_HOTPLUG_LIVE_STATUS (1 << 28) |
1862 | #define PORTD_HOTPLUG_LIVE_STATUS (1 << 27) | 1868 | #define PORTB_HOTPLUG_LIVE_STATUS (1 << 27) |
1863 | #define PORTD_HOTPLUG_INT_STATUS (3 << 21) | 1869 | #define PORTD_HOTPLUG_INT_STATUS (3 << 21) |
1864 | #define PORTC_HOTPLUG_INT_STATUS (3 << 19) | 1870 | #define PORTC_HOTPLUG_INT_STATUS (3 << 19) |
1865 | #define PORTB_HOTPLUG_INT_STATUS (3 << 17) | 1871 | #define PORTB_HOTPLUG_INT_STATUS (3 << 17) |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5fb305840db8..e38b45786653 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -8269,9 +8269,11 @@ check_crtc_state(struct drm_device *dev) | |||
8269 | 8269 | ||
8270 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, | 8270 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, |
8271 | base.head) { | 8271 | base.head) { |
8272 | enum pipe pipe; | ||
8272 | if (encoder->base.crtc != &crtc->base) | 8273 | if (encoder->base.crtc != &crtc->base) |
8273 | continue; | 8274 | continue; |
8274 | if (encoder->get_config) | 8275 | if (encoder->get_config && |
8276 | encoder->get_hw_state(encoder, &pipe)) | ||
8275 | encoder->get_config(encoder, &pipe_config); | 8277 | encoder->get_config(encoder, &pipe_config); |
8276 | } | 8278 | } |
8277 | 8279 | ||
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 67e2c1f1c9a8..5950888ae1d0 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
@@ -497,8 +497,11 @@ void intel_panel_set_backlight(struct drm_device *dev, u32 level, u32 max) | |||
497 | goto out; | 497 | goto out; |
498 | } | 498 | } |
499 | 499 | ||
500 | /* scale to hardware */ | 500 | /* scale to hardware, but be careful to not overflow */ |
501 | level = level * freq / max; | 501 | if (freq < max) |
502 | level = level * freq / max; | ||
503 | else | ||
504 | level = freq / max * level; | ||
502 | 505 | ||
503 | dev_priv->backlight.level = level; | 506 | dev_priv->backlight.level = level; |
504 | if (dev_priv->backlight.device) | 507 | if (dev_priv->backlight.device) |
@@ -515,6 +518,17 @@ void intel_panel_disable_backlight(struct drm_device *dev) | |||
515 | struct drm_i915_private *dev_priv = dev->dev_private; | 518 | struct drm_i915_private *dev_priv = dev->dev_private; |
516 | unsigned long flags; | 519 | unsigned long flags; |
517 | 520 | ||
521 | /* | ||
522 | * Do not disable backlight on the vgaswitcheroo path. When switching | ||
523 | * away from i915, the other client may depend on i915 to handle the | ||
524 | * backlight. This will leave the backlight on unnecessarily when | ||
525 | * another client is not activated. | ||
526 | */ | ||
527 | if (dev->switch_power_state == DRM_SWITCH_POWER_CHANGING) { | ||
528 | DRM_DEBUG_DRIVER("Skipping backlight disable on vga switch\n"); | ||
529 | return; | ||
530 | } | ||
531 | |||
518 | spin_lock_irqsave(&dev_priv->backlight.lock, flags); | 532 | spin_lock_irqsave(&dev_priv->backlight.lock, flags); |
519 | 533 | ||
520 | dev_priv->backlight.enabled = false; | 534 | dev_priv->backlight.enabled = false; |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 51a2a60f5bfc..b0e4a0bd1313 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -5063,8 +5063,26 @@ static void __intel_set_power_well(struct drm_device *dev, bool enable) | |||
5063 | } | 5063 | } |
5064 | } else { | 5064 | } else { |
5065 | if (enable_requested) { | 5065 | if (enable_requested) { |
5066 | unsigned long irqflags; | ||
5067 | enum pipe p; | ||
5068 | |||
5066 | I915_WRITE(HSW_PWR_WELL_DRIVER, 0); | 5069 | I915_WRITE(HSW_PWR_WELL_DRIVER, 0); |
5070 | POSTING_READ(HSW_PWR_WELL_DRIVER); | ||
5067 | DRM_DEBUG_KMS("Requesting to disable the power well\n"); | 5071 | DRM_DEBUG_KMS("Requesting to disable the power well\n"); |
5072 | |||
5073 | /* | ||
5074 | * After this, the registers on the pipes that are part | ||
5075 | * of the power well will become zero, so we have to | ||
5076 | * adjust our counters according to that. | ||
5077 | * | ||
5078 | * FIXME: Should we do this in general in | ||
5079 | * drm_vblank_post_modeset? | ||
5080 | */ | ||
5081 | spin_lock_irqsave(&dev->vbl_lock, irqflags); | ||
5082 | for_each_pipe(p) | ||
5083 | if (p != PIPE_A) | ||
5084 | dev->last_vblank[p] = 0; | ||
5085 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); | ||
5068 | } | 5086 | } |
5069 | } | 5087 | } |
5070 | } | 5088 | } |
@@ -5536,6 +5554,12 @@ void intel_gt_init(struct drm_device *dev) | |||
5536 | dev_priv->gt.force_wake_get = __gen6_gt_force_wake_get; | 5554 | dev_priv->gt.force_wake_get = __gen6_gt_force_wake_get; |
5537 | dev_priv->gt.force_wake_put = __gen6_gt_force_wake_put; | 5555 | dev_priv->gt.force_wake_put = __gen6_gt_force_wake_put; |
5538 | } | 5556 | } |
5557 | } | ||
5558 | |||
5559 | void intel_pm_init(struct drm_device *dev) | ||
5560 | { | ||
5561 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
5562 | |||
5539 | INIT_DELAYED_WORK(&dev_priv->rps.delayed_resume_work, | 5563 | INIT_DELAYED_WORK(&dev_priv->rps.delayed_resume_work, |
5540 | intel_gen6_powersave_work); | 5564 | intel_gen6_powersave_work); |
5541 | } | 5565 | } |
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index 251784aa2225..503a414cbdad 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c | |||
@@ -29,6 +29,7 @@ static void mga_crtc_load_lut(struct drm_crtc *crtc) | |||
29 | struct mga_crtc *mga_crtc = to_mga_crtc(crtc); | 29 | struct mga_crtc *mga_crtc = to_mga_crtc(crtc); |
30 | struct drm_device *dev = crtc->dev; | 30 | struct drm_device *dev = crtc->dev; |
31 | struct mga_device *mdev = dev->dev_private; | 31 | struct mga_device *mdev = dev->dev_private; |
32 | struct drm_framebuffer *fb = crtc->fb; | ||
32 | int i; | 33 | int i; |
33 | 34 | ||
34 | if (!crtc->enabled) | 35 | if (!crtc->enabled) |
@@ -36,6 +37,28 @@ static void mga_crtc_load_lut(struct drm_crtc *crtc) | |||
36 | 37 | ||
37 | WREG8(DAC_INDEX + MGA1064_INDEX, 0); | 38 | WREG8(DAC_INDEX + MGA1064_INDEX, 0); |
38 | 39 | ||
40 | if (fb && fb->bits_per_pixel == 16) { | ||
41 | int inc = (fb->depth == 15) ? 8 : 4; | ||
42 | u8 r, b; | ||
43 | for (i = 0; i < MGAG200_LUT_SIZE; i += inc) { | ||
44 | if (fb->depth == 16) { | ||
45 | if (i > (MGAG200_LUT_SIZE >> 1)) { | ||
46 | r = b = 0; | ||
47 | } else { | ||
48 | r = mga_crtc->lut_r[i << 1]; | ||
49 | b = mga_crtc->lut_b[i << 1]; | ||
50 | } | ||
51 | } else { | ||
52 | r = mga_crtc->lut_r[i]; | ||
53 | b = mga_crtc->lut_b[i]; | ||
54 | } | ||
55 | /* VGA registers */ | ||
56 | WREG8(DAC_INDEX + MGA1064_COL_PAL, r); | ||
57 | WREG8(DAC_INDEX + MGA1064_COL_PAL, mga_crtc->lut_g[i]); | ||
58 | WREG8(DAC_INDEX + MGA1064_COL_PAL, b); | ||
59 | } | ||
60 | return; | ||
61 | } | ||
39 | for (i = 0; i < MGAG200_LUT_SIZE; i++) { | 62 | for (i = 0; i < MGAG200_LUT_SIZE; i++) { |
40 | /* VGA registers */ | 63 | /* VGA registers */ |
41 | WREG8(DAC_INDEX + MGA1064_COL_PAL, mga_crtc->lut_r[i]); | 64 | WREG8(DAC_INDEX + MGA1064_COL_PAL, mga_crtc->lut_r[i]); |
@@ -877,7 +900,7 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, | |||
877 | 900 | ||
878 | pitch = crtc->fb->pitches[0] / (crtc->fb->bits_per_pixel / 8); | 901 | pitch = crtc->fb->pitches[0] / (crtc->fb->bits_per_pixel / 8); |
879 | if (crtc->fb->bits_per_pixel == 24) | 902 | if (crtc->fb->bits_per_pixel == 24) |
880 | pitch = pitch >> (4 - bppshift); | 903 | pitch = (pitch * 3) >> (4 - bppshift); |
881 | else | 904 | else |
882 | pitch = pitch >> (4 - bppshift); | 905 | pitch = pitch >> (4 - bppshift); |
883 | 906 | ||
@@ -1251,6 +1274,24 @@ static void mga_crtc_destroy(struct drm_crtc *crtc) | |||
1251 | kfree(mga_crtc); | 1274 | kfree(mga_crtc); |
1252 | } | 1275 | } |
1253 | 1276 | ||
1277 | static void mga_crtc_disable(struct drm_crtc *crtc) | ||
1278 | { | ||
1279 | int ret; | ||
1280 | DRM_DEBUG_KMS("\n"); | ||
1281 | mga_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); | ||
1282 | if (crtc->fb) { | ||
1283 | struct mga_framebuffer *mga_fb = to_mga_framebuffer(crtc->fb); | ||
1284 | struct drm_gem_object *obj = mga_fb->obj; | ||
1285 | struct mgag200_bo *bo = gem_to_mga_bo(obj); | ||
1286 | ret = mgag200_bo_reserve(bo, false); | ||
1287 | if (ret) | ||
1288 | return; | ||
1289 | mgag200_bo_push_sysram(bo); | ||
1290 | mgag200_bo_unreserve(bo); | ||
1291 | } | ||
1292 | crtc->fb = NULL; | ||
1293 | } | ||
1294 | |||
1254 | /* These provide the minimum set of functions required to handle a CRTC */ | 1295 | /* These provide the minimum set of functions required to handle a CRTC */ |
1255 | static const struct drm_crtc_funcs mga_crtc_funcs = { | 1296 | static const struct drm_crtc_funcs mga_crtc_funcs = { |
1256 | .cursor_set = mga_crtc_cursor_set, | 1297 | .cursor_set = mga_crtc_cursor_set, |
@@ -1261,6 +1302,7 @@ static const struct drm_crtc_funcs mga_crtc_funcs = { | |||
1261 | }; | 1302 | }; |
1262 | 1303 | ||
1263 | static const struct drm_crtc_helper_funcs mga_helper_funcs = { | 1304 | static const struct drm_crtc_helper_funcs mga_helper_funcs = { |
1305 | .disable = mga_crtc_disable, | ||
1264 | .dpms = mga_crtc_dpms, | 1306 | .dpms = mga_crtc_dpms, |
1265 | .mode_fixup = mga_crtc_mode_fixup, | 1307 | .mode_fixup = mga_crtc_mode_fixup, |
1266 | .mode_set = mga_crtc_mode_set, | 1308 | .mode_set = mga_crtc_mode_set, |
@@ -1581,6 +1623,8 @@ static struct drm_connector *mga_vga_init(struct drm_device *dev) | |||
1581 | 1623 | ||
1582 | drm_connector_helper_add(connector, &mga_vga_connector_helper_funcs); | 1624 | drm_connector_helper_add(connector, &mga_vga_connector_helper_funcs); |
1583 | 1625 | ||
1626 | drm_sysfs_connector_add(connector); | ||
1627 | |||
1584 | mga_connector->i2c = mgag200_i2c_create(dev); | 1628 | mga_connector->i2c = mgag200_i2c_create(dev); |
1585 | if (!mga_connector->i2c) | 1629 | if (!mga_connector->i2c) |
1586 | DRM_ERROR("failed to add ddc bus\n"); | 1630 | DRM_ERROR("failed to add ddc bus\n"); |
diff --git a/drivers/gpu/drm/mgag200/mgag200_ttm.c b/drivers/gpu/drm/mgag200/mgag200_ttm.c index 3acb2b044c7b..d70e4a92773b 100644 --- a/drivers/gpu/drm/mgag200/mgag200_ttm.c +++ b/drivers/gpu/drm/mgag200/mgag200_ttm.c | |||
@@ -323,6 +323,7 @@ int mgag200_bo_create(struct drm_device *dev, int size, int align, | |||
323 | 323 | ||
324 | mgabo->gem.driver_private = NULL; | 324 | mgabo->gem.driver_private = NULL; |
325 | mgabo->bo.bdev = &mdev->ttm.bdev; | 325 | mgabo->bo.bdev = &mdev->ttm.bdev; |
326 | mgabo->bo.bdev->dev_mapping = dev->dev_mapping; | ||
326 | 327 | ||
327 | mgag200_ttm_placement(mgabo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM); | 328 | mgag200_ttm_placement(mgabo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM); |
328 | 329 | ||
@@ -353,6 +354,7 @@ int mgag200_bo_pin(struct mgag200_bo *bo, u32 pl_flag, u64 *gpu_addr) | |||
353 | bo->pin_count++; | 354 | bo->pin_count++; |
354 | if (gpu_addr) | 355 | if (gpu_addr) |
355 | *gpu_addr = mgag200_bo_gpu_offset(bo); | 356 | *gpu_addr = mgag200_bo_gpu_offset(bo); |
357 | return 0; | ||
356 | } | 358 | } |
357 | 359 | ||
358 | mgag200_ttm_placement(bo, pl_flag); | 360 | mgag200_ttm_placement(bo, pl_flag); |
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/hdanva3.c b/drivers/gpu/drm/nouveau/core/engine/disp/hdanva3.c index 373dbcc523b2..a19e7d79b847 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/hdanva3.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/hdanva3.c | |||
@@ -36,6 +36,8 @@ nva3_hda_eld(struct nv50_disp_priv *priv, int or, u8 *data, u32 size) | |||
36 | if (data && data[0]) { | 36 | if (data && data[0]) { |
37 | for (i = 0; i < size; i++) | 37 | for (i = 0; i < size; i++) |
38 | nv_wr32(priv, 0x61c440 + soff, (i << 8) | data[i]); | 38 | nv_wr32(priv, 0x61c440 + soff, (i << 8) | data[i]); |
39 | for (; i < 0x60; i++) | ||
40 | nv_wr32(priv, 0x61c440 + soff, (i << 8)); | ||
39 | nv_mask(priv, 0x61c448 + soff, 0x80000003, 0x80000003); | 41 | nv_mask(priv, 0x61c448 + soff, 0x80000003, 0x80000003); |
40 | } else | 42 | } else |
41 | if (data) { | 43 | if (data) { |
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/hdanvd0.c b/drivers/gpu/drm/nouveau/core/engine/disp/hdanvd0.c index dc57e24fc1df..717639386ced 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/hdanvd0.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/hdanvd0.c | |||
@@ -41,6 +41,8 @@ nvd0_hda_eld(struct nv50_disp_priv *priv, int or, u8 *data, u32 size) | |||
41 | if (data && data[0]) { | 41 | if (data && data[0]) { |
42 | for (i = 0; i < size; i++) | 42 | for (i = 0; i < size; i++) |
43 | nv_wr32(priv, 0x10ec00 + soff, (i << 8) | data[i]); | 43 | nv_wr32(priv, 0x10ec00 + soff, (i << 8) | data[i]); |
44 | for (; i < 0x60; i++) | ||
45 | nv_wr32(priv, 0x10ec00 + soff, (i << 8)); | ||
44 | nv_mask(priv, 0x10ec10 + soff, 0x80000003, 0x80000003); | 46 | nv_mask(priv, 0x10ec10 + soff, 0x80000003, 0x80000003); |
45 | } else | 47 | } else |
46 | if (data) { | 48 | if (data) { |
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c index ab1e918469a8..526b75242899 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c | |||
@@ -47,14 +47,8 @@ int | |||
47 | nv50_sor_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size) | 47 | nv50_sor_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size) |
48 | { | 48 | { |
49 | struct nv50_disp_priv *priv = (void *)object->engine; | 49 | struct nv50_disp_priv *priv = (void *)object->engine; |
50 | struct nouveau_bios *bios = nouveau_bios(priv); | ||
51 | const u16 type = (mthd & NV50_DISP_SOR_MTHD_TYPE) >> 12; | ||
52 | const u8 head = (mthd & NV50_DISP_SOR_MTHD_HEAD) >> 3; | 50 | const u8 head = (mthd & NV50_DISP_SOR_MTHD_HEAD) >> 3; |
53 | const u8 link = (mthd & NV50_DISP_SOR_MTHD_LINK) >> 2; | ||
54 | const u8 or = (mthd & NV50_DISP_SOR_MTHD_OR); | 51 | const u8 or = (mthd & NV50_DISP_SOR_MTHD_OR); |
55 | const u16 mask = (0x0100 << head) | (0x0040 << link) | (0x0001 << or); | ||
56 | struct dcb_output outp; | ||
57 | u8 ver, hdr; | ||
58 | u32 data; | 52 | u32 data; |
59 | int ret = -EINVAL; | 53 | int ret = -EINVAL; |
60 | 54 | ||
@@ -62,8 +56,6 @@ nv50_sor_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size) | |||
62 | return -EINVAL; | 56 | return -EINVAL; |
63 | data = *(u32 *)args; | 57 | data = *(u32 *)args; |
64 | 58 | ||
65 | if (type && !dcb_outp_match(bios, type, mask, &ver, &hdr, &outp)) | ||
66 | return -ENODEV; | ||
67 | 59 | ||
68 | switch (mthd & ~0x3f) { | 60 | switch (mthd & ~0x3f) { |
69 | case NV50_DISP_SOR_PWR: | 61 | case NV50_DISP_SOR_PWR: |
diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c index 49ecbb859b25..c19004301309 100644 --- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c +++ b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c | |||
@@ -265,8 +265,8 @@ nv31_mpeg_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
265 | int | 265 | int |
266 | nv31_mpeg_init(struct nouveau_object *object) | 266 | nv31_mpeg_init(struct nouveau_object *object) |
267 | { | 267 | { |
268 | struct nouveau_engine *engine = nv_engine(object->engine); | 268 | struct nouveau_engine *engine = nv_engine(object); |
269 | struct nv31_mpeg_priv *priv = (void *)engine; | 269 | struct nv31_mpeg_priv *priv = (void *)object; |
270 | struct nouveau_fb *pfb = nouveau_fb(object); | 270 | struct nouveau_fb *pfb = nouveau_fb(object); |
271 | int ret, i; | 271 | int ret, i; |
272 | 272 | ||
@@ -284,7 +284,10 @@ nv31_mpeg_init(struct nouveau_object *object) | |||
284 | /* PMPEG init */ | 284 | /* PMPEG init */ |
285 | nv_wr32(priv, 0x00b32c, 0x00000000); | 285 | nv_wr32(priv, 0x00b32c, 0x00000000); |
286 | nv_wr32(priv, 0x00b314, 0x00000100); | 286 | nv_wr32(priv, 0x00b314, 0x00000100); |
287 | nv_wr32(priv, 0x00b220, nv44_graph_class(priv) ? 0x00000044 : 0x00000031); | 287 | if (nv_device(priv)->chipset >= 0x40 && nv44_graph_class(priv)) |
288 | nv_wr32(priv, 0x00b220, 0x00000044); | ||
289 | else | ||
290 | nv_wr32(priv, 0x00b220, 0x00000031); | ||
288 | nv_wr32(priv, 0x00b300, 0x02001ec1); | 291 | nv_wr32(priv, 0x00b300, 0x02001ec1); |
289 | nv_mask(priv, 0x00b32c, 0x00000001, 0x00000001); | 292 | nv_mask(priv, 0x00b32c, 0x00000001, 0x00000001); |
290 | 293 | ||
diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c index f7c581ad1991..dd6196072e9c 100644 --- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c +++ b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c | |||
@@ -61,6 +61,7 @@ nv40_mpeg_context_ctor(struct nouveau_object *parent, | |||
61 | if (ret) | 61 | if (ret) |
62 | return ret; | 62 | return ret; |
63 | 63 | ||
64 | nv_wo32(&chan->base.base, 0x78, 0x02001ec1); | ||
64 | return 0; | 65 | return 0; |
65 | } | 66 | } |
66 | 67 | ||
diff --git a/drivers/gpu/drm/nouveau/core/engine/xtensa.c b/drivers/gpu/drm/nouveau/core/engine/xtensa.c index 0639bc59d0a5..5f6ede7c4892 100644 --- a/drivers/gpu/drm/nouveau/core/engine/xtensa.c +++ b/drivers/gpu/drm/nouveau/core/engine/xtensa.c | |||
@@ -118,7 +118,13 @@ _nouveau_xtensa_init(struct nouveau_object *object) | |||
118 | return ret; | 118 | return ret; |
119 | } | 119 | } |
120 | 120 | ||
121 | ret = nouveau_gpuobj_new(object, NULL, fw->size, 0x1000, 0, | 121 | if (fw->size > 0x40000) { |
122 | nv_warn(xtensa, "firmware %s too large\n", name); | ||
123 | release_firmware(fw); | ||
124 | return -EINVAL; | ||
125 | } | ||
126 | |||
127 | ret = nouveau_gpuobj_new(object, NULL, 0x40000, 0x1000, 0, | ||
122 | &xtensa->gpu_fw); | 128 | &xtensa->gpu_fw); |
123 | if (ret) { | 129 | if (ret) { |
124 | release_firmware(fw); | 130 | release_firmware(fw); |
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/vm.h b/drivers/gpu/drm/nouveau/core/include/subdev/vm.h index f2e87b105666..fcf57fa309bf 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/vm.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/vm.h | |||
@@ -55,7 +55,7 @@ struct nouveau_vma { | |||
55 | struct nouveau_vm { | 55 | struct nouveau_vm { |
56 | struct nouveau_vmmgr *vmm; | 56 | struct nouveau_vmmgr *vmm; |
57 | struct nouveau_mm mm; | 57 | struct nouveau_mm mm; |
58 | int refcount; | 58 | struct kref refcount; |
59 | 59 | ||
60 | struct list_head pgd_list; | 60 | struct list_head pgd_list; |
61 | atomic_t engref[NVDEV_SUBDEV_NR]; | 61 | atomic_t engref[NVDEV_SUBDEV_NR]; |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h b/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h index 6c974dd83e8b..db9d6ddde52c 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h | |||
@@ -81,7 +81,7 @@ void nv44_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *); | |||
81 | void nv46_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size, | 81 | void nv46_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size, |
82 | u32 pitch, u32 flags, struct nouveau_fb_tile *); | 82 | u32 pitch, u32 flags, struct nouveau_fb_tile *); |
83 | 83 | ||
84 | void nv50_ram_put(struct nouveau_fb *, struct nouveau_mem **); | 84 | void __nv50_ram_put(struct nouveau_fb *, struct nouveau_mem *); |
85 | extern int nv50_fb_memtype[0x80]; | 85 | extern int nv50_fb_memtype[0x80]; |
86 | 86 | ||
87 | #endif | 87 | #endif |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c index af5aa7ee8ad9..903baff77fdd 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c | |||
@@ -27,17 +27,10 @@ | |||
27 | #include "priv.h" | 27 | #include "priv.h" |
28 | 28 | ||
29 | void | 29 | void |
30 | nv50_ram_put(struct nouveau_fb *pfb, struct nouveau_mem **pmem) | 30 | __nv50_ram_put(struct nouveau_fb *pfb, struct nouveau_mem *mem) |
31 | { | 31 | { |
32 | struct nouveau_mm_node *this; | 32 | struct nouveau_mm_node *this; |
33 | struct nouveau_mem *mem; | ||
34 | 33 | ||
35 | mem = *pmem; | ||
36 | *pmem = NULL; | ||
37 | if (unlikely(mem == NULL)) | ||
38 | return; | ||
39 | |||
40 | mutex_lock(&pfb->base.mutex); | ||
41 | while (!list_empty(&mem->regions)) { | 34 | while (!list_empty(&mem->regions)) { |
42 | this = list_first_entry(&mem->regions, typeof(*this), rl_entry); | 35 | this = list_first_entry(&mem->regions, typeof(*this), rl_entry); |
43 | 36 | ||
@@ -46,6 +39,19 @@ nv50_ram_put(struct nouveau_fb *pfb, struct nouveau_mem **pmem) | |||
46 | } | 39 | } |
47 | 40 | ||
48 | nouveau_mm_free(&pfb->tags, &mem->tag); | 41 | nouveau_mm_free(&pfb->tags, &mem->tag); |
42 | } | ||
43 | |||
44 | void | ||
45 | nv50_ram_put(struct nouveau_fb *pfb, struct nouveau_mem **pmem) | ||
46 | { | ||
47 | struct nouveau_mem *mem = *pmem; | ||
48 | |||
49 | *pmem = NULL; | ||
50 | if (unlikely(mem == NULL)) | ||
51 | return; | ||
52 | |||
53 | mutex_lock(&pfb->base.mutex); | ||
54 | __nv50_ram_put(pfb, mem); | ||
49 | mutex_unlock(&pfb->base.mutex); | 55 | mutex_unlock(&pfb->base.mutex); |
50 | 56 | ||
51 | kfree(mem); | 57 | kfree(mem); |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c index 9c3634acbb9d..cf97c4de4a6b 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c | |||
@@ -33,11 +33,19 @@ void | |||
33 | nvc0_ram_put(struct nouveau_fb *pfb, struct nouveau_mem **pmem) | 33 | nvc0_ram_put(struct nouveau_fb *pfb, struct nouveau_mem **pmem) |
34 | { | 34 | { |
35 | struct nouveau_ltcg *ltcg = nouveau_ltcg(pfb); | 35 | struct nouveau_ltcg *ltcg = nouveau_ltcg(pfb); |
36 | struct nouveau_mem *mem = *pmem; | ||
36 | 37 | ||
37 | if ((*pmem)->tag) | 38 | *pmem = NULL; |
38 | ltcg->tags_free(ltcg, &(*pmem)->tag); | 39 | if (unlikely(mem == NULL)) |
40 | return; | ||
39 | 41 | ||
40 | nv50_ram_put(pfb, pmem); | 42 | mutex_lock(&pfb->base.mutex); |
43 | if (mem->tag) | ||
44 | ltcg->tags_free(ltcg, &mem->tag); | ||
45 | __nv50_ram_put(pfb, mem); | ||
46 | mutex_unlock(&pfb->base.mutex); | ||
47 | |||
48 | kfree(mem); | ||
41 | } | 49 | } |
42 | 50 | ||
43 | int | 51 | int |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c index bf489dcf46e2..c4c1d415e7fe 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c | |||
@@ -103,7 +103,7 @@ nv50_gpio_intr(struct nouveau_subdev *subdev) | |||
103 | int i; | 103 | int i; |
104 | 104 | ||
105 | intr0 = nv_rd32(priv, 0xe054) & nv_rd32(priv, 0xe050); | 105 | intr0 = nv_rd32(priv, 0xe054) & nv_rd32(priv, 0xe050); |
106 | if (nv_device(priv)->chipset >= 0x90) | 106 | if (nv_device(priv)->chipset > 0x92) |
107 | intr1 = nv_rd32(priv, 0xe074) & nv_rd32(priv, 0xe070); | 107 | intr1 = nv_rd32(priv, 0xe074) & nv_rd32(priv, 0xe070); |
108 | 108 | ||
109 | hi = (intr0 & 0x0000ffff) | (intr1 << 16); | 109 | hi = (intr0 & 0x0000ffff) | (intr1 << 16); |
@@ -115,7 +115,7 @@ nv50_gpio_intr(struct nouveau_subdev *subdev) | |||
115 | } | 115 | } |
116 | 116 | ||
117 | nv_wr32(priv, 0xe054, intr0); | 117 | nv_wr32(priv, 0xe054, intr0); |
118 | if (nv_device(priv)->chipset >= 0x90) | 118 | if (nv_device(priv)->chipset > 0x92) |
119 | nv_wr32(priv, 0xe074, intr1); | 119 | nv_wr32(priv, 0xe074, intr1); |
120 | } | 120 | } |
121 | 121 | ||
@@ -146,7 +146,7 @@ nv50_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
146 | int ret; | 146 | int ret; |
147 | 147 | ||
148 | ret = nouveau_gpio_create(parent, engine, oclass, | 148 | ret = nouveau_gpio_create(parent, engine, oclass, |
149 | nv_device(parent)->chipset >= 0x90 ? 32 : 16, | 149 | nv_device(parent)->chipset > 0x92 ? 32 : 16, |
150 | &priv); | 150 | &priv); |
151 | *pobject = nv_object(priv); | 151 | *pobject = nv_object(priv); |
152 | if (ret) | 152 | if (ret) |
@@ -182,7 +182,7 @@ nv50_gpio_init(struct nouveau_object *object) | |||
182 | /* disable, and ack any pending gpio interrupts */ | 182 | /* disable, and ack any pending gpio interrupts */ |
183 | nv_wr32(priv, 0xe050, 0x00000000); | 183 | nv_wr32(priv, 0xe050, 0x00000000); |
184 | nv_wr32(priv, 0xe054, 0xffffffff); | 184 | nv_wr32(priv, 0xe054, 0xffffffff); |
185 | if (nv_device(priv)->chipset >= 0x90) { | 185 | if (nv_device(priv)->chipset > 0x92) { |
186 | nv_wr32(priv, 0xe070, 0x00000000); | 186 | nv_wr32(priv, 0xe070, 0x00000000); |
187 | nv_wr32(priv, 0xe074, 0xffffffff); | 187 | nv_wr32(priv, 0xe074, 0xffffffff); |
188 | } | 188 | } |
@@ -195,7 +195,7 @@ nv50_gpio_fini(struct nouveau_object *object, bool suspend) | |||
195 | { | 195 | { |
196 | struct nv50_gpio_priv *priv = (void *)object; | 196 | struct nv50_gpio_priv *priv = (void *)object; |
197 | nv_wr32(priv, 0xe050, 0x00000000); | 197 | nv_wr32(priv, 0xe050, 0x00000000); |
198 | if (nv_device(priv)->chipset >= 0x90) | 198 | if (nv_device(priv)->chipset > 0x92) |
199 | nv_wr32(priv, 0xe070, 0x00000000); | 199 | nv_wr32(priv, 0xe070, 0x00000000); |
200 | return nouveau_gpio_fini(&priv->base, suspend); | 200 | return nouveau_gpio_fini(&priv->base, suspend); |
201 | } | 201 | } |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c index 0cb322a5e72c..f25fc5fc7dd1 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c | |||
@@ -41,7 +41,7 @@ nv50_mc_intr[] = { | |||
41 | { 0x04000000, NVDEV_ENGINE_DISP }, | 41 | { 0x04000000, NVDEV_ENGINE_DISP }, |
42 | { 0x10000000, NVDEV_SUBDEV_BUS }, | 42 | { 0x10000000, NVDEV_SUBDEV_BUS }, |
43 | { 0x80000000, NVDEV_ENGINE_SW }, | 43 | { 0x80000000, NVDEV_ENGINE_SW }, |
44 | { 0x0000d101, NVDEV_SUBDEV_FB }, | 44 | { 0x0002d101, NVDEV_SUBDEV_FB }, |
45 | {}, | 45 | {}, |
46 | }; | 46 | }; |
47 | 47 | ||
diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/base.c b/drivers/gpu/drm/nouveau/core/subdev/vm/base.c index 67fcb6c852ac..ef3133e7575c 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/vm/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/vm/base.c | |||
@@ -361,7 +361,7 @@ nouveau_vm_create(struct nouveau_vmmgr *vmm, u64 offset, u64 length, | |||
361 | 361 | ||
362 | INIT_LIST_HEAD(&vm->pgd_list); | 362 | INIT_LIST_HEAD(&vm->pgd_list); |
363 | vm->vmm = vmm; | 363 | vm->vmm = vmm; |
364 | vm->refcount = 1; | 364 | kref_init(&vm->refcount); |
365 | vm->fpde = offset >> (vmm->pgt_bits + 12); | 365 | vm->fpde = offset >> (vmm->pgt_bits + 12); |
366 | vm->lpde = (offset + length - 1) >> (vmm->pgt_bits + 12); | 366 | vm->lpde = (offset + length - 1) >> (vmm->pgt_bits + 12); |
367 | 367 | ||
@@ -441,8 +441,9 @@ nouveau_vm_unlink(struct nouveau_vm *vm, struct nouveau_gpuobj *mpgd) | |||
441 | } | 441 | } |
442 | 442 | ||
443 | static void | 443 | static void |
444 | nouveau_vm_del(struct nouveau_vm *vm) | 444 | nouveau_vm_del(struct kref *kref) |
445 | { | 445 | { |
446 | struct nouveau_vm *vm = container_of(kref, typeof(*vm), refcount); | ||
446 | struct nouveau_vm_pgd *vpgd, *tmp; | 447 | struct nouveau_vm_pgd *vpgd, *tmp; |
447 | 448 | ||
448 | list_for_each_entry_safe(vpgd, tmp, &vm->pgd_list, head) { | 449 | list_for_each_entry_safe(vpgd, tmp, &vm->pgd_list, head) { |
@@ -458,27 +459,19 @@ int | |||
458 | nouveau_vm_ref(struct nouveau_vm *ref, struct nouveau_vm **ptr, | 459 | nouveau_vm_ref(struct nouveau_vm *ref, struct nouveau_vm **ptr, |
459 | struct nouveau_gpuobj *pgd) | 460 | struct nouveau_gpuobj *pgd) |
460 | { | 461 | { |
461 | struct nouveau_vm *vm; | 462 | if (ref) { |
462 | int ret; | 463 | int ret = nouveau_vm_link(ref, pgd); |
463 | |||
464 | vm = ref; | ||
465 | if (vm) { | ||
466 | ret = nouveau_vm_link(vm, pgd); | ||
467 | if (ret) | 464 | if (ret) |
468 | return ret; | 465 | return ret; |
469 | 466 | ||
470 | vm->refcount++; | 467 | kref_get(&ref->refcount); |
471 | } | 468 | } |
472 | 469 | ||
473 | vm = *ptr; | 470 | if (*ptr) { |
474 | *ptr = ref; | 471 | nouveau_vm_unlink(*ptr, pgd); |
475 | 472 | kref_put(&(*ptr)->refcount, nouveau_vm_del); | |
476 | if (vm) { | ||
477 | nouveau_vm_unlink(vm, pgd); | ||
478 | |||
479 | if (--vm->refcount == 0) | ||
480 | nouveau_vm_del(vm); | ||
481 | } | 473 | } |
482 | 474 | ||
475 | *ptr = ref; | ||
483 | return 0; | 476 | return 0; |
484 | } | 477 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 4e7ee5f4155c..af20fba3a1a4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c | |||
@@ -198,7 +198,12 @@ nouveau_bo_new(struct drm_device *dev, int size, int align, | |||
198 | size_t acc_size; | 198 | size_t acc_size; |
199 | int ret; | 199 | int ret; |
200 | int type = ttm_bo_type_device; | 200 | int type = ttm_bo_type_device; |
201 | int max_size = INT_MAX & ~((1 << drm->client.base.vm->vmm->lpg_shift) - 1); | 201 | int lpg_shift = 12; |
202 | int max_size; | ||
203 | |||
204 | if (drm->client.base.vm) | ||
205 | lpg_shift = drm->client.base.vm->vmm->lpg_shift; | ||
206 | max_size = INT_MAX & ~((1 << lpg_shift) - 1); | ||
202 | 207 | ||
203 | if (size <= 0 || size > max_size) { | 208 | if (size <= 0 || size > max_size) { |
204 | nv_warn(drm, "skipped size %x\n", (u32)size); | 209 | nv_warn(drm, "skipped size %x\n", (u32)size); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 4c1bc061fae2..8f6d63d7edd3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c | |||
@@ -398,7 +398,8 @@ void | |||
398 | nouveau_fbcon_output_poll_changed(struct drm_device *dev) | 398 | nouveau_fbcon_output_poll_changed(struct drm_device *dev) |
399 | { | 399 | { |
400 | struct nouveau_drm *drm = nouveau_drm(dev); | 400 | struct nouveau_drm *drm = nouveau_drm(dev); |
401 | drm_fb_helper_hotplug_event(&drm->fbcon->helper); | 401 | if (drm->fbcon) |
402 | drm_fb_helper_hotplug_event(&drm->fbcon->helper); | ||
402 | } | 403 | } |
403 | 404 | ||
404 | static int | 405 | static int |
diff --git a/drivers/gpu/drm/nouveau/nv17_fence.c b/drivers/gpu/drm/nouveau/nv17_fence.c index 8e47a9bae8c3..22aa9963ea6f 100644 --- a/drivers/gpu/drm/nouveau/nv17_fence.c +++ b/drivers/gpu/drm/nouveau/nv17_fence.c | |||
@@ -76,7 +76,7 @@ nv17_fence_context_new(struct nouveau_channel *chan) | |||
76 | struct ttm_mem_reg *mem = &priv->bo->bo.mem; | 76 | struct ttm_mem_reg *mem = &priv->bo->bo.mem; |
77 | struct nouveau_object *object; | 77 | struct nouveau_object *object; |
78 | u32 start = mem->start * PAGE_SIZE; | 78 | u32 start = mem->start * PAGE_SIZE; |
79 | u32 limit = mem->start + mem->size - 1; | 79 | u32 limit = start + mem->size - 1; |
80 | int ret = 0; | 80 | int ret = 0; |
81 | 81 | ||
82 | fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL); | 82 | fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL); |
diff --git a/drivers/gpu/drm/nouveau/nv50_fence.c b/drivers/gpu/drm/nouveau/nv50_fence.c index f9701e567db8..0ee363840035 100644 --- a/drivers/gpu/drm/nouveau/nv50_fence.c +++ b/drivers/gpu/drm/nouveau/nv50_fence.c | |||
@@ -39,6 +39,8 @@ nv50_fence_context_new(struct nouveau_channel *chan) | |||
39 | struct nv10_fence_chan *fctx; | 39 | struct nv10_fence_chan *fctx; |
40 | struct ttm_mem_reg *mem = &priv->bo->bo.mem; | 40 | struct ttm_mem_reg *mem = &priv->bo->bo.mem; |
41 | struct nouveau_object *object; | 41 | struct nouveau_object *object; |
42 | u32 start = mem->start * PAGE_SIZE; | ||
43 | u32 limit = start + mem->size - 1; | ||
42 | int ret, i; | 44 | int ret, i; |
43 | 45 | ||
44 | fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL); | 46 | fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL); |
@@ -51,26 +53,28 @@ nv50_fence_context_new(struct nouveau_channel *chan) | |||
51 | fctx->base.sync = nv17_fence_sync; | 53 | fctx->base.sync = nv17_fence_sync; |
52 | 54 | ||
53 | ret = nouveau_object_new(nv_object(chan->cli), chan->handle, | 55 | ret = nouveau_object_new(nv_object(chan->cli), chan->handle, |
54 | NvSema, 0x0002, | 56 | NvSema, 0x003d, |
55 | &(struct nv_dma_class) { | 57 | &(struct nv_dma_class) { |
56 | .flags = NV_DMA_TARGET_VRAM | | 58 | .flags = NV_DMA_TARGET_VRAM | |
57 | NV_DMA_ACCESS_RDWR, | 59 | NV_DMA_ACCESS_RDWR, |
58 | .start = mem->start * PAGE_SIZE, | 60 | .start = start, |
59 | .limit = mem->size - 1, | 61 | .limit = limit, |
60 | }, sizeof(struct nv_dma_class), | 62 | }, sizeof(struct nv_dma_class), |
61 | &object); | 63 | &object); |
62 | 64 | ||
63 | /* dma objects for display sync channel semaphore blocks */ | 65 | /* dma objects for display sync channel semaphore blocks */ |
64 | for (i = 0; !ret && i < dev->mode_config.num_crtc; i++) { | 66 | for (i = 0; !ret && i < dev->mode_config.num_crtc; i++) { |
65 | struct nouveau_bo *bo = nv50_display_crtc_sema(dev, i); | 67 | struct nouveau_bo *bo = nv50_display_crtc_sema(dev, i); |
68 | u32 start = bo->bo.mem.start * PAGE_SIZE; | ||
69 | u32 limit = start + bo->bo.mem.size - 1; | ||
66 | 70 | ||
67 | ret = nouveau_object_new(nv_object(chan->cli), chan->handle, | 71 | ret = nouveau_object_new(nv_object(chan->cli), chan->handle, |
68 | NvEvoSema0 + i, 0x003d, | 72 | NvEvoSema0 + i, 0x003d, |
69 | &(struct nv_dma_class) { | 73 | &(struct nv_dma_class) { |
70 | .flags = NV_DMA_TARGET_VRAM | | 74 | .flags = NV_DMA_TARGET_VRAM | |
71 | NV_DMA_ACCESS_RDWR, | 75 | NV_DMA_ACCESS_RDWR, |
72 | .start = bo->bo.offset, | 76 | .start = start, |
73 | .limit = bo->bo.offset + 0xfff, | 77 | .limit = limit, |
74 | }, sizeof(struct nv_dma_class), | 78 | }, sizeof(struct nv_dma_class), |
75 | &object); | 79 | &object); |
76 | } | 80 | } |
diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index fb441a790f3d..15da7ef344a4 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c | |||
@@ -1222,12 +1222,17 @@ int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params) | |||
1222 | int r; | 1222 | int r; |
1223 | 1223 | ||
1224 | mutex_lock(&ctx->mutex); | 1224 | mutex_lock(&ctx->mutex); |
1225 | /* reset data block */ | ||
1226 | ctx->data_block = 0; | ||
1225 | /* reset reg block */ | 1227 | /* reset reg block */ |
1226 | ctx->reg_block = 0; | 1228 | ctx->reg_block = 0; |
1227 | /* reset fb window */ | 1229 | /* reset fb window */ |
1228 | ctx->fb_base = 0; | 1230 | ctx->fb_base = 0; |
1229 | /* reset io mode */ | 1231 | /* reset io mode */ |
1230 | ctx->io_mode = ATOM_IO_MM; | 1232 | ctx->io_mode = ATOM_IO_MM; |
1233 | /* reset divmul */ | ||
1234 | ctx->divmul[0] = 0; | ||
1235 | ctx->divmul[1] = 0; | ||
1231 | r = atom_execute_table_locked(ctx, index, params); | 1236 | r = atom_execute_table_locked(ctx, index, params); |
1232 | mutex_unlock(&ctx->mutex); | 1237 | mutex_unlock(&ctx->mutex); |
1233 | return r; | 1238 | return r; |
diff --git a/drivers/gpu/drm/radeon/btc_dpm.c b/drivers/gpu/drm/radeon/btc_dpm.c index 0bfd55e08820..9953e1fbc46d 100644 --- a/drivers/gpu/drm/radeon/btc_dpm.c +++ b/drivers/gpu/drm/radeon/btc_dpm.c | |||
@@ -2548,9 +2548,6 @@ int btc_dpm_init(struct radeon_device *rdev) | |||
2548 | { | 2548 | { |
2549 | struct rv7xx_power_info *pi; | 2549 | struct rv7xx_power_info *pi; |
2550 | struct evergreen_power_info *eg_pi; | 2550 | struct evergreen_power_info *eg_pi; |
2551 | int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info); | ||
2552 | u16 data_offset, size; | ||
2553 | u8 frev, crev; | ||
2554 | struct atom_clock_dividers dividers; | 2551 | struct atom_clock_dividers dividers; |
2555 | int ret; | 2552 | int ret; |
2556 | 2553 | ||
@@ -2633,16 +2630,7 @@ int btc_dpm_init(struct radeon_device *rdev) | |||
2633 | eg_pi->vddci_control = | 2630 | eg_pi->vddci_control = |
2634 | radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0); | 2631 | radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0); |
2635 | 2632 | ||
2636 | if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size, | 2633 | rv770_get_engine_memory_ss(rdev); |
2637 | &frev, &crev, &data_offset)) { | ||
2638 | pi->sclk_ss = true; | ||
2639 | pi->mclk_ss = true; | ||
2640 | pi->dynamic_ss = true; | ||
2641 | } else { | ||
2642 | pi->sclk_ss = false; | ||
2643 | pi->mclk_ss = false; | ||
2644 | pi->dynamic_ss = true; | ||
2645 | } | ||
2646 | 2634 | ||
2647 | pi->asi = RV770_ASI_DFLT; | 2635 | pi->asi = RV770_ASI_DFLT; |
2648 | pi->pasi = CYPRESS_HASI_DFLT; | 2636 | pi->pasi = CYPRESS_HASI_DFLT; |
@@ -2659,8 +2647,7 @@ int btc_dpm_init(struct radeon_device *rdev) | |||
2659 | 2647 | ||
2660 | pi->dynamic_pcie_gen2 = true; | 2648 | pi->dynamic_pcie_gen2 = true; |
2661 | 2649 | ||
2662 | if (pi->gfx_clock_gating && | 2650 | if (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE) |
2663 | (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE)) | ||
2664 | pi->thermal_protection = true; | 2651 | pi->thermal_protection = true; |
2665 | else | 2652 | else |
2666 | pi->thermal_protection = false; | 2653 | pi->thermal_protection = false; |
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 6dacec4e2090..8928bd109c16 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c | |||
@@ -2587,9 +2587,11 @@ u32 cik_compute_ring_get_rptr(struct radeon_device *rdev, | |||
2587 | if (rdev->wb.enabled) { | 2587 | if (rdev->wb.enabled) { |
2588 | rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]); | 2588 | rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]); |
2589 | } else { | 2589 | } else { |
2590 | mutex_lock(&rdev->srbm_mutex); | ||
2590 | cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0); | 2591 | cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0); |
2591 | rptr = RREG32(CP_HQD_PQ_RPTR); | 2592 | rptr = RREG32(CP_HQD_PQ_RPTR); |
2592 | cik_srbm_select(rdev, 0, 0, 0, 0); | 2593 | cik_srbm_select(rdev, 0, 0, 0, 0); |
2594 | mutex_unlock(&rdev->srbm_mutex); | ||
2593 | } | 2595 | } |
2594 | rptr = (rptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift; | 2596 | rptr = (rptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift; |
2595 | 2597 | ||
@@ -2604,9 +2606,11 @@ u32 cik_compute_ring_get_wptr(struct radeon_device *rdev, | |||
2604 | if (rdev->wb.enabled) { | 2606 | if (rdev->wb.enabled) { |
2605 | wptr = le32_to_cpu(rdev->wb.wb[ring->wptr_offs/4]); | 2607 | wptr = le32_to_cpu(rdev->wb.wb[ring->wptr_offs/4]); |
2606 | } else { | 2608 | } else { |
2609 | mutex_lock(&rdev->srbm_mutex); | ||
2607 | cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0); | 2610 | cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0); |
2608 | wptr = RREG32(CP_HQD_PQ_WPTR); | 2611 | wptr = RREG32(CP_HQD_PQ_WPTR); |
2609 | cik_srbm_select(rdev, 0, 0, 0, 0); | 2612 | cik_srbm_select(rdev, 0, 0, 0, 0); |
2613 | mutex_unlock(&rdev->srbm_mutex); | ||
2610 | } | 2614 | } |
2611 | wptr = (wptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift; | 2615 | wptr = (wptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift; |
2612 | 2616 | ||
@@ -2897,6 +2901,7 @@ static int cik_cp_compute_resume(struct radeon_device *rdev) | |||
2897 | WREG32(CP_CPF_DEBUG, tmp); | 2901 | WREG32(CP_CPF_DEBUG, tmp); |
2898 | 2902 | ||
2899 | /* init the pipes */ | 2903 | /* init the pipes */ |
2904 | mutex_lock(&rdev->srbm_mutex); | ||
2900 | for (i = 0; i < (rdev->mec.num_pipe * rdev->mec.num_mec); i++) { | 2905 | for (i = 0; i < (rdev->mec.num_pipe * rdev->mec.num_mec); i++) { |
2901 | int me = (i < 4) ? 1 : 2; | 2906 | int me = (i < 4) ? 1 : 2; |
2902 | int pipe = (i < 4) ? i : (i - 4); | 2907 | int pipe = (i < 4) ? i : (i - 4); |
@@ -2919,6 +2924,7 @@ static int cik_cp_compute_resume(struct radeon_device *rdev) | |||
2919 | WREG32(CP_HPD_EOP_CONTROL, tmp); | 2924 | WREG32(CP_HPD_EOP_CONTROL, tmp); |
2920 | } | 2925 | } |
2921 | cik_srbm_select(rdev, 0, 0, 0, 0); | 2926 | cik_srbm_select(rdev, 0, 0, 0, 0); |
2927 | mutex_unlock(&rdev->srbm_mutex); | ||
2922 | 2928 | ||
2923 | /* init the queues. Just two for now. */ | 2929 | /* init the queues. Just two for now. */ |
2924 | for (i = 0; i < 2; i++) { | 2930 | for (i = 0; i < 2; i++) { |
@@ -2972,6 +2978,7 @@ static int cik_cp_compute_resume(struct radeon_device *rdev) | |||
2972 | mqd->static_thread_mgmt23[0] = 0xffffffff; | 2978 | mqd->static_thread_mgmt23[0] = 0xffffffff; |
2973 | mqd->static_thread_mgmt23[1] = 0xffffffff; | 2979 | mqd->static_thread_mgmt23[1] = 0xffffffff; |
2974 | 2980 | ||
2981 | mutex_lock(&rdev->srbm_mutex); | ||
2975 | cik_srbm_select(rdev, rdev->ring[idx].me, | 2982 | cik_srbm_select(rdev, rdev->ring[idx].me, |
2976 | rdev->ring[idx].pipe, | 2983 | rdev->ring[idx].pipe, |
2977 | rdev->ring[idx].queue, 0); | 2984 | rdev->ring[idx].queue, 0); |
@@ -3099,6 +3106,7 @@ static int cik_cp_compute_resume(struct radeon_device *rdev) | |||
3099 | WREG32(CP_HQD_ACTIVE, mqd->queue_state.cp_hqd_active); | 3106 | WREG32(CP_HQD_ACTIVE, mqd->queue_state.cp_hqd_active); |
3100 | 3107 | ||
3101 | cik_srbm_select(rdev, 0, 0, 0, 0); | 3108 | cik_srbm_select(rdev, 0, 0, 0, 0); |
3109 | mutex_unlock(&rdev->srbm_mutex); | ||
3102 | 3110 | ||
3103 | radeon_bo_kunmap(rdev->ring[idx].mqd_obj); | 3111 | radeon_bo_kunmap(rdev->ring[idx].mqd_obj); |
3104 | radeon_bo_unreserve(rdev->ring[idx].mqd_obj); | 3112 | radeon_bo_unreserve(rdev->ring[idx].mqd_obj); |
@@ -4320,6 +4328,7 @@ static int cik_pcie_gart_enable(struct radeon_device *rdev) | |||
4320 | 4328 | ||
4321 | /* XXX SH_MEM regs */ | 4329 | /* XXX SH_MEM regs */ |
4322 | /* where to put LDS, scratch, GPUVM in FSA64 space */ | 4330 | /* where to put LDS, scratch, GPUVM in FSA64 space */ |
4331 | mutex_lock(&rdev->srbm_mutex); | ||
4323 | for (i = 0; i < 16; i++) { | 4332 | for (i = 0; i < 16; i++) { |
4324 | cik_srbm_select(rdev, 0, 0, 0, i); | 4333 | cik_srbm_select(rdev, 0, 0, 0, i); |
4325 | /* CP and shaders */ | 4334 | /* CP and shaders */ |
@@ -4335,6 +4344,7 @@ static int cik_pcie_gart_enable(struct radeon_device *rdev) | |||
4335 | /* XXX SDMA RLC - todo */ | 4344 | /* XXX SDMA RLC - todo */ |
4336 | } | 4345 | } |
4337 | cik_srbm_select(rdev, 0, 0, 0, 0); | 4346 | cik_srbm_select(rdev, 0, 0, 0, 0); |
4347 | mutex_unlock(&rdev->srbm_mutex); | ||
4338 | 4348 | ||
4339 | cik_pcie_gart_tlb_flush(rdev); | 4349 | cik_pcie_gart_tlb_flush(rdev); |
4340 | DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", | 4350 | DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", |
@@ -5954,6 +5964,8 @@ static int cik_startup(struct radeon_device *rdev) | |||
5954 | struct radeon_ring *ring; | 5964 | struct radeon_ring *ring; |
5955 | int r; | 5965 | int r; |
5956 | 5966 | ||
5967 | cik_mc_program(rdev); | ||
5968 | |||
5957 | if (rdev->flags & RADEON_IS_IGP) { | 5969 | if (rdev->flags & RADEON_IS_IGP) { |
5958 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw || | 5970 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw || |
5959 | !rdev->mec_fw || !rdev->sdma_fw || !rdev->rlc_fw) { | 5971 | !rdev->mec_fw || !rdev->sdma_fw || !rdev->rlc_fw) { |
@@ -5985,7 +5997,6 @@ static int cik_startup(struct radeon_device *rdev) | |||
5985 | if (r) | 5997 | if (r) |
5986 | return r; | 5998 | return r; |
5987 | 5999 | ||
5988 | cik_mc_program(rdev); | ||
5989 | r = cik_pcie_gart_enable(rdev); | 6000 | r = cik_pcie_gart_enable(rdev); |
5990 | if (r) | 6001 | if (r) |
5991 | return r; | 6002 | return r; |
@@ -6194,7 +6205,7 @@ int cik_suspend(struct radeon_device *rdev) | |||
6194 | radeon_vm_manager_fini(rdev); | 6205 | radeon_vm_manager_fini(rdev); |
6195 | cik_cp_enable(rdev, false); | 6206 | cik_cp_enable(rdev, false); |
6196 | cik_sdma_enable(rdev, false); | 6207 | cik_sdma_enable(rdev, false); |
6197 | r600_uvd_rbc_stop(rdev); | 6208 | r600_uvd_stop(rdev); |
6198 | radeon_uvd_suspend(rdev); | 6209 | radeon_uvd_suspend(rdev); |
6199 | cik_irq_suspend(rdev); | 6210 | cik_irq_suspend(rdev); |
6200 | radeon_wb_disable(rdev); | 6211 | radeon_wb_disable(rdev); |
@@ -6358,6 +6369,7 @@ void cik_fini(struct radeon_device *rdev) | |||
6358 | radeon_vm_manager_fini(rdev); | 6369 | radeon_vm_manager_fini(rdev); |
6359 | radeon_ib_pool_fini(rdev); | 6370 | radeon_ib_pool_fini(rdev); |
6360 | radeon_irq_kms_fini(rdev); | 6371 | radeon_irq_kms_fini(rdev); |
6372 | r600_uvd_stop(rdev); | ||
6361 | radeon_uvd_fini(rdev); | 6373 | radeon_uvd_fini(rdev); |
6362 | cik_pcie_gart_fini(rdev); | 6374 | cik_pcie_gart_fini(rdev); |
6363 | r600_vram_scratch_fini(rdev); | 6375 | r600_vram_scratch_fini(rdev); |
@@ -6978,7 +6990,7 @@ int cik_uvd_resume(struct radeon_device *rdev) | |||
6978 | 6990 | ||
6979 | /* programm the VCPU memory controller bits 0-27 */ | 6991 | /* programm the VCPU memory controller bits 0-27 */ |
6980 | addr = rdev->uvd.gpu_addr >> 3; | 6992 | addr = rdev->uvd.gpu_addr >> 3; |
6981 | size = RADEON_GPU_PAGE_ALIGN(rdev->uvd.fw_size + 4) >> 3; | 6993 | size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 4) >> 3; |
6982 | WREG32(UVD_VCPU_CACHE_OFFSET0, addr); | 6994 | WREG32(UVD_VCPU_CACHE_OFFSET0, addr); |
6983 | WREG32(UVD_VCPU_CACHE_SIZE0, size); | 6995 | WREG32(UVD_VCPU_CACHE_SIZE0, size); |
6984 | 6996 | ||
diff --git a/drivers/gpu/drm/radeon/cypress_dpm.c b/drivers/gpu/drm/radeon/cypress_dpm.c index 9bcdd174780f..7e5d0b570a30 100644 --- a/drivers/gpu/drm/radeon/cypress_dpm.c +++ b/drivers/gpu/drm/radeon/cypress_dpm.c | |||
@@ -2038,9 +2038,6 @@ int cypress_dpm_init(struct radeon_device *rdev) | |||
2038 | { | 2038 | { |
2039 | struct rv7xx_power_info *pi; | 2039 | struct rv7xx_power_info *pi; |
2040 | struct evergreen_power_info *eg_pi; | 2040 | struct evergreen_power_info *eg_pi; |
2041 | int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info); | ||
2042 | uint16_t data_offset, size; | ||
2043 | uint8_t frev, crev; | ||
2044 | struct atom_clock_dividers dividers; | 2041 | struct atom_clock_dividers dividers; |
2045 | int ret; | 2042 | int ret; |
2046 | 2043 | ||
@@ -2092,16 +2089,7 @@ int cypress_dpm_init(struct radeon_device *rdev) | |||
2092 | eg_pi->vddci_control = | 2089 | eg_pi->vddci_control = |
2093 | radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0); | 2090 | radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0); |
2094 | 2091 | ||
2095 | if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size, | 2092 | rv770_get_engine_memory_ss(rdev); |
2096 | &frev, &crev, &data_offset)) { | ||
2097 | pi->sclk_ss = true; | ||
2098 | pi->mclk_ss = true; | ||
2099 | pi->dynamic_ss = true; | ||
2100 | } else { | ||
2101 | pi->sclk_ss = false; | ||
2102 | pi->mclk_ss = false; | ||
2103 | pi->dynamic_ss = true; | ||
2104 | } | ||
2105 | 2093 | ||
2106 | pi->asi = RV770_ASI_DFLT; | 2094 | pi->asi = RV770_ASI_DFLT; |
2107 | pi->pasi = CYPRESS_HASI_DFLT; | 2095 | pi->pasi = CYPRESS_HASI_DFLT; |
@@ -2122,8 +2110,7 @@ int cypress_dpm_init(struct radeon_device *rdev) | |||
2122 | 2110 | ||
2123 | pi->dynamic_pcie_gen2 = true; | 2111 | pi->dynamic_pcie_gen2 = true; |
2124 | 2112 | ||
2125 | if (pi->gfx_clock_gating && | 2113 | if (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE) |
2126 | (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE)) | ||
2127 | pi->thermal_protection = true; | 2114 | pi->thermal_protection = true; |
2128 | else | 2115 | else |
2129 | pi->thermal_protection = false; | 2116 | pi->thermal_protection = false; |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 038dcac7670c..d5b49e33315e 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -5106,6 +5106,8 @@ static int evergreen_startup(struct radeon_device *rdev) | |||
5106 | /* enable aspm */ | 5106 | /* enable aspm */ |
5107 | evergreen_program_aspm(rdev); | 5107 | evergreen_program_aspm(rdev); |
5108 | 5108 | ||
5109 | evergreen_mc_program(rdev); | ||
5110 | |||
5109 | if (ASIC_IS_DCE5(rdev)) { | 5111 | if (ASIC_IS_DCE5(rdev)) { |
5110 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) { | 5112 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) { |
5111 | r = ni_init_microcode(rdev); | 5113 | r = ni_init_microcode(rdev); |
@@ -5133,7 +5135,6 @@ static int evergreen_startup(struct radeon_device *rdev) | |||
5133 | if (r) | 5135 | if (r) |
5134 | return r; | 5136 | return r; |
5135 | 5137 | ||
5136 | evergreen_mc_program(rdev); | ||
5137 | if (rdev->flags & RADEON_IS_AGP) { | 5138 | if (rdev->flags & RADEON_IS_AGP) { |
5138 | evergreen_agp_enable(rdev); | 5139 | evergreen_agp_enable(rdev); |
5139 | } else { | 5140 | } else { |
@@ -5291,10 +5292,10 @@ int evergreen_resume(struct radeon_device *rdev) | |||
5291 | int evergreen_suspend(struct radeon_device *rdev) | 5292 | int evergreen_suspend(struct radeon_device *rdev) |
5292 | { | 5293 | { |
5293 | r600_audio_fini(rdev); | 5294 | r600_audio_fini(rdev); |
5295 | r600_uvd_stop(rdev); | ||
5294 | radeon_uvd_suspend(rdev); | 5296 | radeon_uvd_suspend(rdev); |
5295 | r700_cp_stop(rdev); | 5297 | r700_cp_stop(rdev); |
5296 | r600_dma_stop(rdev); | 5298 | r600_dma_stop(rdev); |
5297 | r600_uvd_rbc_stop(rdev); | ||
5298 | evergreen_irq_suspend(rdev); | 5299 | evergreen_irq_suspend(rdev); |
5299 | radeon_wb_disable(rdev); | 5300 | radeon_wb_disable(rdev); |
5300 | evergreen_pcie_gart_disable(rdev); | 5301 | evergreen_pcie_gart_disable(rdev); |
@@ -5429,6 +5430,7 @@ void evergreen_fini(struct radeon_device *rdev) | |||
5429 | radeon_ib_pool_fini(rdev); | 5430 | radeon_ib_pool_fini(rdev); |
5430 | radeon_irq_kms_fini(rdev); | 5431 | radeon_irq_kms_fini(rdev); |
5431 | evergreen_pcie_gart_fini(rdev); | 5432 | evergreen_pcie_gart_fini(rdev); |
5433 | r600_uvd_stop(rdev); | ||
5432 | radeon_uvd_fini(rdev); | 5434 | radeon_uvd_fini(rdev); |
5433 | r600_vram_scratch_fini(rdev); | 5435 | r600_vram_scratch_fini(rdev); |
5434 | radeon_gem_fini(rdev); | 5436 | radeon_gem_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index b0d3fb341417..b0e280058b9b 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c | |||
@@ -148,18 +148,40 @@ static void evergreen_audio_set_dto(struct drm_encoder *encoder, u32 clock) | |||
148 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 148 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
149 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | 149 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); |
150 | u32 base_rate = 24000; | 150 | u32 base_rate = 24000; |
151 | u32 max_ratio = clock / base_rate; | ||
152 | u32 dto_phase; | ||
153 | u32 dto_modulo = clock; | ||
154 | u32 wallclock_ratio; | ||
155 | u32 dto_cntl; | ||
151 | 156 | ||
152 | if (!dig || !dig->afmt) | 157 | if (!dig || !dig->afmt) |
153 | return; | 158 | return; |
154 | 159 | ||
160 | if (max_ratio >= 8) { | ||
161 | dto_phase = 192 * 1000; | ||
162 | wallclock_ratio = 3; | ||
163 | } else if (max_ratio >= 4) { | ||
164 | dto_phase = 96 * 1000; | ||
165 | wallclock_ratio = 2; | ||
166 | } else if (max_ratio >= 2) { | ||
167 | dto_phase = 48 * 1000; | ||
168 | wallclock_ratio = 1; | ||
169 | } else { | ||
170 | dto_phase = 24 * 1000; | ||
171 | wallclock_ratio = 0; | ||
172 | } | ||
173 | dto_cntl = RREG32(DCCG_AUDIO_DTO0_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK; | ||
174 | dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio); | ||
175 | WREG32(DCCG_AUDIO_DTO0_CNTL, dto_cntl); | ||
176 | |||
155 | /* XXX two dtos; generally use dto0 for hdmi */ | 177 | /* XXX two dtos; generally use dto0 for hdmi */ |
156 | /* Express [24MHz / target pixel clock] as an exact rational | 178 | /* Express [24MHz / target pixel clock] as an exact rational |
157 | * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE | 179 | * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE |
158 | * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator | 180 | * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator |
159 | */ | 181 | */ |
160 | WREG32(DCCG_AUDIO_DTO0_PHASE, base_rate * 100); | ||
161 | WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100); | ||
162 | WREG32(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL(radeon_crtc->crtc_id)); | 182 | WREG32(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL(radeon_crtc->crtc_id)); |
183 | WREG32(DCCG_AUDIO_DTO0_PHASE, dto_phase); | ||
184 | WREG32(DCCG_AUDIO_DTO0_MODULE, dto_modulo); | ||
163 | } | 185 | } |
164 | 186 | ||
165 | 187 | ||
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index a7baf67aef6c..0d582ac1dc31 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h | |||
@@ -497,6 +497,9 @@ | |||
497 | #define DCCG_AUDIO_DTO0_MODULE 0x05b4 | 497 | #define DCCG_AUDIO_DTO0_MODULE 0x05b4 |
498 | #define DCCG_AUDIO_DTO0_LOAD 0x05b8 | 498 | #define DCCG_AUDIO_DTO0_LOAD 0x05b8 |
499 | #define DCCG_AUDIO_DTO0_CNTL 0x05bc | 499 | #define DCCG_AUDIO_DTO0_CNTL 0x05bc |
500 | # define DCCG_AUDIO_DTO_WALLCLOCK_RATIO(x) (((x) & 7) << 0) | ||
501 | # define DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK 7 | ||
502 | # define DCCG_AUDIO_DTO_WALLCLOCK_RATIO_SHIFT 0 | ||
500 | 503 | ||
501 | #define DCCG_AUDIO_DTO1_PHASE 0x05c0 | 504 | #define DCCG_AUDIO_DTO1_PHASE 0x05c0 |
502 | #define DCCG_AUDIO_DTO1_MODULE 0x05c4 | 505 | #define DCCG_AUDIO_DTO1_MODULE 0x05c4 |
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 56bd4f3be4fe..ccb4f8b54852 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c | |||
@@ -794,9 +794,13 @@ int ni_init_microcode(struct radeon_device *rdev) | |||
794 | if ((rdev->family >= CHIP_BARTS) && (rdev->family <= CHIP_CAYMAN)) { | 794 | if ((rdev->family >= CHIP_BARTS) && (rdev->family <= CHIP_CAYMAN)) { |
795 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name); | 795 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name); |
796 | err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev); | 796 | err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev); |
797 | if (err) | 797 | if (err) { |
798 | goto out; | 798 | printk(KERN_ERR |
799 | if (rdev->smc_fw->size != smc_req_size) { | 799 | "smc: error loading firmware \"%s\"\n", |
800 | fw_name); | ||
801 | release_firmware(rdev->smc_fw); | ||
802 | rdev->smc_fw = NULL; | ||
803 | } else if (rdev->smc_fw->size != smc_req_size) { | ||
800 | printk(KERN_ERR | 804 | printk(KERN_ERR |
801 | "ni_mc: Bogus length %zu in firmware \"%s\"\n", | 805 | "ni_mc: Bogus length %zu in firmware \"%s\"\n", |
802 | rdev->mc_fw->size, fw_name); | 806 | rdev->mc_fw->size, fw_name); |
@@ -2079,6 +2083,8 @@ static int cayman_startup(struct radeon_device *rdev) | |||
2079 | /* enable aspm */ | 2083 | /* enable aspm */ |
2080 | evergreen_program_aspm(rdev); | 2084 | evergreen_program_aspm(rdev); |
2081 | 2085 | ||
2086 | evergreen_mc_program(rdev); | ||
2087 | |||
2082 | if (rdev->flags & RADEON_IS_IGP) { | 2088 | if (rdev->flags & RADEON_IS_IGP) { |
2083 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { | 2089 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { |
2084 | r = ni_init_microcode(rdev); | 2090 | r = ni_init_microcode(rdev); |
@@ -2107,7 +2113,6 @@ static int cayman_startup(struct radeon_device *rdev) | |||
2107 | if (r) | 2113 | if (r) |
2108 | return r; | 2114 | return r; |
2109 | 2115 | ||
2110 | evergreen_mc_program(rdev); | ||
2111 | r = cayman_pcie_gart_enable(rdev); | 2116 | r = cayman_pcie_gart_enable(rdev); |
2112 | if (r) | 2117 | if (r) |
2113 | return r; | 2118 | return r; |
@@ -2286,7 +2291,7 @@ int cayman_suspend(struct radeon_device *rdev) | |||
2286 | radeon_vm_manager_fini(rdev); | 2291 | radeon_vm_manager_fini(rdev); |
2287 | cayman_cp_enable(rdev, false); | 2292 | cayman_cp_enable(rdev, false); |
2288 | cayman_dma_stop(rdev); | 2293 | cayman_dma_stop(rdev); |
2289 | r600_uvd_rbc_stop(rdev); | 2294 | r600_uvd_stop(rdev); |
2290 | radeon_uvd_suspend(rdev); | 2295 | radeon_uvd_suspend(rdev); |
2291 | evergreen_irq_suspend(rdev); | 2296 | evergreen_irq_suspend(rdev); |
2292 | radeon_wb_disable(rdev); | 2297 | radeon_wb_disable(rdev); |
@@ -2418,6 +2423,7 @@ void cayman_fini(struct radeon_device *rdev) | |||
2418 | radeon_vm_manager_fini(rdev); | 2423 | radeon_vm_manager_fini(rdev); |
2419 | radeon_ib_pool_fini(rdev); | 2424 | radeon_ib_pool_fini(rdev); |
2420 | radeon_irq_kms_fini(rdev); | 2425 | radeon_irq_kms_fini(rdev); |
2426 | r600_uvd_stop(rdev); | ||
2421 | radeon_uvd_fini(rdev); | 2427 | radeon_uvd_fini(rdev); |
2422 | cayman_pcie_gart_fini(rdev); | 2428 | cayman_pcie_gart_fini(rdev); |
2423 | r600_vram_scratch_fini(rdev); | 2429 | r600_vram_scratch_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c index 559cf24d51af..f0f5f748938a 100644 --- a/drivers/gpu/drm/radeon/ni_dpm.c +++ b/drivers/gpu/drm/radeon/ni_dpm.c | |||
@@ -1054,10 +1054,6 @@ static int ni_restrict_performance_levels_before_switch(struct radeon_device *rd | |||
1054 | int ni_dpm_force_performance_level(struct radeon_device *rdev, | 1054 | int ni_dpm_force_performance_level(struct radeon_device *rdev, |
1055 | enum radeon_dpm_forced_level level) | 1055 | enum radeon_dpm_forced_level level) |
1056 | { | 1056 | { |
1057 | struct radeon_ps *rps = rdev->pm.dpm.current_ps; | ||
1058 | struct ni_ps *ps = ni_get_ps(rps); | ||
1059 | u32 levels; | ||
1060 | |||
1061 | if (level == RADEON_DPM_FORCED_LEVEL_HIGH) { | 1057 | if (level == RADEON_DPM_FORCED_LEVEL_HIGH) { |
1062 | if (ni_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, 0) != PPSMC_Result_OK) | 1058 | if (ni_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, 0) != PPSMC_Result_OK) |
1063 | return -EINVAL; | 1059 | return -EINVAL; |
@@ -1068,8 +1064,7 @@ int ni_dpm_force_performance_level(struct radeon_device *rdev, | |||
1068 | if (ni_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetForcedLevels, 0) != PPSMC_Result_OK) | 1064 | if (ni_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetForcedLevels, 0) != PPSMC_Result_OK) |
1069 | return -EINVAL; | 1065 | return -EINVAL; |
1070 | 1066 | ||
1071 | levels = ps->performance_level_count - 1; | 1067 | if (ni_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, 1) != PPSMC_Result_OK) |
1072 | if (ni_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, levels) != PPSMC_Result_OK) | ||
1073 | return -EINVAL; | 1068 | return -EINVAL; |
1074 | } else if (level == RADEON_DPM_FORCED_LEVEL_AUTO) { | 1069 | } else if (level == RADEON_DPM_FORCED_LEVEL_AUTO) { |
1075 | if (ni_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetForcedLevels, 0) != PPSMC_Result_OK) | 1070 | if (ni_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetForcedLevels, 0) != PPSMC_Result_OK) |
@@ -4072,9 +4067,6 @@ int ni_dpm_init(struct radeon_device *rdev) | |||
4072 | struct rv7xx_power_info *pi; | 4067 | struct rv7xx_power_info *pi; |
4073 | struct evergreen_power_info *eg_pi; | 4068 | struct evergreen_power_info *eg_pi; |
4074 | struct ni_power_info *ni_pi; | 4069 | struct ni_power_info *ni_pi; |
4075 | int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info); | ||
4076 | u16 data_offset, size; | ||
4077 | u8 frev, crev; | ||
4078 | struct atom_clock_dividers dividers; | 4070 | struct atom_clock_dividers dividers; |
4079 | int ret; | 4071 | int ret; |
4080 | 4072 | ||
@@ -4167,16 +4159,7 @@ int ni_dpm_init(struct radeon_device *rdev) | |||
4167 | eg_pi->vddci_control = | 4159 | eg_pi->vddci_control = |
4168 | radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0); | 4160 | radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0); |
4169 | 4161 | ||
4170 | if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size, | 4162 | rv770_get_engine_memory_ss(rdev); |
4171 | &frev, &crev, &data_offset)) { | ||
4172 | pi->sclk_ss = true; | ||
4173 | pi->mclk_ss = true; | ||
4174 | pi->dynamic_ss = true; | ||
4175 | } else { | ||
4176 | pi->sclk_ss = false; | ||
4177 | pi->mclk_ss = false; | ||
4178 | pi->dynamic_ss = true; | ||
4179 | } | ||
4180 | 4163 | ||
4181 | pi->asi = RV770_ASI_DFLT; | 4164 | pi->asi = RV770_ASI_DFLT; |
4182 | pi->pasi = CYPRESS_HASI_DFLT; | 4165 | pi->pasi = CYPRESS_HASI_DFLT; |
@@ -4193,8 +4176,7 @@ int ni_dpm_init(struct radeon_device *rdev) | |||
4193 | 4176 | ||
4194 | pi->dynamic_pcie_gen2 = true; | 4177 | pi->dynamic_pcie_gen2 = true; |
4195 | 4178 | ||
4196 | if (pi->gfx_clock_gating && | 4179 | if (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE) |
4197 | (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE)) | ||
4198 | pi->thermal_protection = true; | 4180 | pi->thermal_protection = true; |
4199 | else | 4181 | else |
4200 | pi->thermal_protection = false; | 4182 | pi->thermal_protection = false; |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 10f712e37003..e66e72077350 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -2299,9 +2299,13 @@ int r600_init_microcode(struct radeon_device *rdev) | |||
2299 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_HEMLOCK)) { | 2299 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_HEMLOCK)) { |
2300 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", smc_chip_name); | 2300 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", smc_chip_name); |
2301 | err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev); | 2301 | err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev); |
2302 | if (err) | 2302 | if (err) { |
2303 | goto out; | 2303 | printk(KERN_ERR |
2304 | if (rdev->smc_fw->size != smc_req_size) { | 2304 | "smc: error loading firmware \"%s\"\n", |
2305 | fw_name); | ||
2306 | release_firmware(rdev->smc_fw); | ||
2307 | rdev->smc_fw = NULL; | ||
2308 | } else if (rdev->smc_fw->size != smc_req_size) { | ||
2305 | printk(KERN_ERR | 2309 | printk(KERN_ERR |
2306 | "smc: Bogus length %zu in firmware \"%s\"\n", | 2310 | "smc: Bogus length %zu in firmware \"%s\"\n", |
2307 | rdev->smc_fw->size, fw_name); | 2311 | rdev->smc_fw->size, fw_name); |
@@ -2697,12 +2701,29 @@ int r600_uvd_rbc_start(struct radeon_device *rdev) | |||
2697 | return 0; | 2701 | return 0; |
2698 | } | 2702 | } |
2699 | 2703 | ||
2700 | void r600_uvd_rbc_stop(struct radeon_device *rdev) | 2704 | void r600_uvd_stop(struct radeon_device *rdev) |
2701 | { | 2705 | { |
2702 | struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; | 2706 | struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; |
2703 | 2707 | ||
2704 | /* force RBC into idle state */ | 2708 | /* force RBC into idle state */ |
2705 | WREG32(UVD_RBC_RB_CNTL, 0x11010101); | 2709 | WREG32(UVD_RBC_RB_CNTL, 0x11010101); |
2710 | |||
2711 | /* Stall UMC and register bus before resetting VCPU */ | ||
2712 | WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8)); | ||
2713 | WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3)); | ||
2714 | mdelay(1); | ||
2715 | |||
2716 | /* put VCPU into reset */ | ||
2717 | WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET); | ||
2718 | mdelay(5); | ||
2719 | |||
2720 | /* disable VCPU clock */ | ||
2721 | WREG32(UVD_VCPU_CNTL, 0x0); | ||
2722 | |||
2723 | /* Unstall UMC and register bus */ | ||
2724 | WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8)); | ||
2725 | WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3)); | ||
2726 | |||
2706 | ring->ready = false; | 2727 | ring->ready = false; |
2707 | } | 2728 | } |
2708 | 2729 | ||
@@ -2722,6 +2743,11 @@ int r600_uvd_init(struct radeon_device *rdev) | |||
2722 | /* disable interupt */ | 2743 | /* disable interupt */ |
2723 | WREG32_P(UVD_MASTINT_EN, 0, ~(1 << 1)); | 2744 | WREG32_P(UVD_MASTINT_EN, 0, ~(1 << 1)); |
2724 | 2745 | ||
2746 | /* Stall UMC and register bus before resetting VCPU */ | ||
2747 | WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8)); | ||
2748 | WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3)); | ||
2749 | mdelay(1); | ||
2750 | |||
2725 | /* put LMI, VCPU, RBC etc... into reset */ | 2751 | /* put LMI, VCPU, RBC etc... into reset */ |
2726 | WREG32(UVD_SOFT_RESET, LMI_SOFT_RESET | VCPU_SOFT_RESET | | 2752 | WREG32(UVD_SOFT_RESET, LMI_SOFT_RESET | VCPU_SOFT_RESET | |
2727 | LBSI_SOFT_RESET | RBC_SOFT_RESET | CSM_SOFT_RESET | | 2753 | LBSI_SOFT_RESET | RBC_SOFT_RESET | CSM_SOFT_RESET | |
@@ -2751,10 +2777,6 @@ int r600_uvd_init(struct radeon_device *rdev) | |||
2751 | WREG32(UVD_MPC_SET_ALU, 0); | 2777 | WREG32(UVD_MPC_SET_ALU, 0); |
2752 | WREG32(UVD_MPC_SET_MUX, 0x88); | 2778 | WREG32(UVD_MPC_SET_MUX, 0x88); |
2753 | 2779 | ||
2754 | /* Stall UMC */ | ||
2755 | WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8)); | ||
2756 | WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3)); | ||
2757 | |||
2758 | /* take all subblocks out of reset, except VCPU */ | 2780 | /* take all subblocks out of reset, except VCPU */ |
2759 | WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET); | 2781 | WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET); |
2760 | mdelay(5); | 2782 | mdelay(5); |
@@ -3312,6 +3334,8 @@ static int r600_startup(struct radeon_device *rdev) | |||
3312 | /* enable pcie gen2 link */ | 3334 | /* enable pcie gen2 link */ |
3313 | r600_pcie_gen2_enable(rdev); | 3335 | r600_pcie_gen2_enable(rdev); |
3314 | 3336 | ||
3337 | r600_mc_program(rdev); | ||
3338 | |||
3315 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { | 3339 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { |
3316 | r = r600_init_microcode(rdev); | 3340 | r = r600_init_microcode(rdev); |
3317 | if (r) { | 3341 | if (r) { |
@@ -3324,7 +3348,6 @@ static int r600_startup(struct radeon_device *rdev) | |||
3324 | if (r) | 3348 | if (r) |
3325 | return r; | 3349 | return r; |
3326 | 3350 | ||
3327 | r600_mc_program(rdev); | ||
3328 | if (rdev->flags & RADEON_IS_AGP) { | 3351 | if (rdev->flags & RADEON_IS_AGP) { |
3329 | r600_agp_enable(rdev); | 3352 | r600_agp_enable(rdev); |
3330 | } else { | 3353 | } else { |
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index f48240bb8c56..f264df5470f7 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c | |||
@@ -226,10 +226,29 @@ void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock) | |||
226 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 226 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
227 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 227 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
228 | u32 base_rate = 24000; | 228 | u32 base_rate = 24000; |
229 | u32 max_ratio = clock / base_rate; | ||
230 | u32 dto_phase; | ||
231 | u32 dto_modulo = clock; | ||
232 | u32 wallclock_ratio; | ||
233 | u32 dto_cntl; | ||
229 | 234 | ||
230 | if (!dig || !dig->afmt) | 235 | if (!dig || !dig->afmt) |
231 | return; | 236 | return; |
232 | 237 | ||
238 | if (max_ratio >= 8) { | ||
239 | dto_phase = 192 * 1000; | ||
240 | wallclock_ratio = 3; | ||
241 | } else if (max_ratio >= 4) { | ||
242 | dto_phase = 96 * 1000; | ||
243 | wallclock_ratio = 2; | ||
244 | } else if (max_ratio >= 2) { | ||
245 | dto_phase = 48 * 1000; | ||
246 | wallclock_ratio = 1; | ||
247 | } else { | ||
248 | dto_phase = 24 * 1000; | ||
249 | wallclock_ratio = 0; | ||
250 | } | ||
251 | |||
233 | /* there are two DTOs selected by DCCG_AUDIO_DTO_SELECT. | 252 | /* there are two DTOs selected by DCCG_AUDIO_DTO_SELECT. |
234 | * doesn't matter which one you use. Just use the first one. | 253 | * doesn't matter which one you use. Just use the first one. |
235 | */ | 254 | */ |
@@ -242,9 +261,21 @@ void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock) | |||
242 | /* according to the reg specs, this should DCE3.2 only, but in | 261 | /* according to the reg specs, this should DCE3.2 only, but in |
243 | * practice it seems to cover DCE3.0 as well. | 262 | * practice it seems to cover DCE3.0 as well. |
244 | */ | 263 | */ |
245 | WREG32(DCCG_AUDIO_DTO0_PHASE, base_rate * 100); | 264 | if (dig->dig_encoder == 0) { |
246 | WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100); | 265 | dto_cntl = RREG32(DCCG_AUDIO_DTO0_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK; |
247 | WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */ | 266 | dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio); |
267 | WREG32(DCCG_AUDIO_DTO0_CNTL, dto_cntl); | ||
268 | WREG32(DCCG_AUDIO_DTO0_PHASE, dto_phase); | ||
269 | WREG32(DCCG_AUDIO_DTO0_MODULE, dto_modulo); | ||
270 | WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */ | ||
271 | } else { | ||
272 | dto_cntl = RREG32(DCCG_AUDIO_DTO1_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK; | ||
273 | dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio); | ||
274 | WREG32(DCCG_AUDIO_DTO1_CNTL, dto_cntl); | ||
275 | WREG32(DCCG_AUDIO_DTO1_PHASE, dto_phase); | ||
276 | WREG32(DCCG_AUDIO_DTO1_MODULE, dto_modulo); | ||
277 | WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */ | ||
278 | } | ||
248 | } else { | 279 | } else { |
249 | /* according to the reg specs, this should be DCE2.0 and DCE3.0 */ | 280 | /* according to the reg specs, this should be DCE2.0 and DCE3.0 */ |
250 | WREG32(AUDIO_DTO, AUDIO_DTO_PHASE(base_rate / 10) | | 281 | WREG32(AUDIO_DTO, AUDIO_DTO_PHASE(base_rate / 10) | |
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index 8e3fe815edab..7c780839a7f4 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h | |||
@@ -933,6 +933,9 @@ | |||
933 | #define DCCG_AUDIO_DTO0_LOAD 0x051c | 933 | #define DCCG_AUDIO_DTO0_LOAD 0x051c |
934 | # define DTO_LOAD (1 << 31) | 934 | # define DTO_LOAD (1 << 31) |
935 | #define DCCG_AUDIO_DTO0_CNTL 0x0520 | 935 | #define DCCG_AUDIO_DTO0_CNTL 0x0520 |
936 | # define DCCG_AUDIO_DTO_WALLCLOCK_RATIO(x) (((x) & 7) << 0) | ||
937 | # define DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK 7 | ||
938 | # define DCCG_AUDIO_DTO_WALLCLOCK_RATIO_SHIFT 0 | ||
936 | 939 | ||
937 | #define DCCG_AUDIO_DTO1_PHASE 0x0524 | 940 | #define DCCG_AUDIO_DTO1_PHASE 0x0524 |
938 | #define DCCG_AUDIO_DTO1_MODULE 0x0528 | 941 | #define DCCG_AUDIO_DTO1_MODULE 0x0528 |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 2f08219c39b6..274b8e1b889f 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -1468,7 +1468,6 @@ struct radeon_uvd { | |||
1468 | void *cpu_addr; | 1468 | void *cpu_addr; |
1469 | uint64_t gpu_addr; | 1469 | uint64_t gpu_addr; |
1470 | void *saved_bo; | 1470 | void *saved_bo; |
1471 | unsigned fw_size; | ||
1472 | atomic_t handles[RADEON_MAX_UVD_HANDLES]; | 1471 | atomic_t handles[RADEON_MAX_UVD_HANDLES]; |
1473 | struct drm_file *filp[RADEON_MAX_UVD_HANDLES]; | 1472 | struct drm_file *filp[RADEON_MAX_UVD_HANDLES]; |
1474 | struct delayed_work idle_work; | 1473 | struct delayed_work idle_work; |
@@ -2066,6 +2065,7 @@ struct radeon_device { | |||
2066 | const struct firmware *mec_fw; /* CIK MEC firmware */ | 2065 | const struct firmware *mec_fw; /* CIK MEC firmware */ |
2067 | const struct firmware *sdma_fw; /* CIK SDMA firmware */ | 2066 | const struct firmware *sdma_fw; /* CIK SDMA firmware */ |
2068 | const struct firmware *smc_fw; /* SMC firmware */ | 2067 | const struct firmware *smc_fw; /* SMC firmware */ |
2068 | const struct firmware *uvd_fw; /* UVD firmware */ | ||
2069 | struct r600_blit r600_blit; | 2069 | struct r600_blit r600_blit; |
2070 | struct r600_vram_scratch vram_scratch; | 2070 | struct r600_vram_scratch vram_scratch; |
2071 | int msi_enabled; /* msi enabled */ | 2071 | int msi_enabled; /* msi enabled */ |
@@ -2095,6 +2095,8 @@ struct radeon_device { | |||
2095 | /* ACPI interface */ | 2095 | /* ACPI interface */ |
2096 | struct radeon_atif atif; | 2096 | struct radeon_atif atif; |
2097 | struct radeon_atcs atcs; | 2097 | struct radeon_atcs atcs; |
2098 | /* srbm instance registers */ | ||
2099 | struct mutex srbm_mutex; | ||
2098 | }; | 2100 | }; |
2099 | 2101 | ||
2100 | int radeon_device_init(struct radeon_device *rdev, | 2102 | int radeon_device_init(struct radeon_device *rdev, |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 902479fa737f..3d61d5aac18f 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -441,7 +441,7 @@ void rs780_dpm_debugfs_print_current_performance_level(struct radeon_device *rde | |||
441 | /* uvd */ | 441 | /* uvd */ |
442 | int r600_uvd_init(struct radeon_device *rdev); | 442 | int r600_uvd_init(struct radeon_device *rdev); |
443 | int r600_uvd_rbc_start(struct radeon_device *rdev); | 443 | int r600_uvd_rbc_start(struct radeon_device *rdev); |
444 | void r600_uvd_rbc_stop(struct radeon_device *rdev); | 444 | void r600_uvd_stop(struct radeon_device *rdev); |
445 | int r600_uvd_ib_test(struct radeon_device *rdev, struct radeon_ring *ring); | 445 | int r600_uvd_ib_test(struct radeon_device *rdev, struct radeon_ring *ring); |
446 | void r600_uvd_fence_emit(struct radeon_device *rdev, | 446 | void r600_uvd_fence_emit(struct radeon_device *rdev, |
447 | struct radeon_fence *fence); | 447 | struct radeon_fence *fence); |
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index e3f3e8841789..4ccd61f60eb6 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -2782,7 +2782,7 @@ int radeon_atom_get_clock_dividers(struct radeon_device *rdev, | |||
2782 | ATOM_PLL_CNTL_FLAG_PLL_POST_DIV_EN) ? true : false; | 2782 | ATOM_PLL_CNTL_FLAG_PLL_POST_DIV_EN) ? true : false; |
2783 | dividers->enable_dithen = (args.v3.ucCntlFlag & | 2783 | dividers->enable_dithen = (args.v3.ucCntlFlag & |
2784 | ATOM_PLL_CNTL_FLAG_FRACTION_DISABLE) ? false : true; | 2784 | ATOM_PLL_CNTL_FLAG_FRACTION_DISABLE) ? false : true; |
2785 | dividers->fb_div = le16_to_cpu(args.v3.ulFbDiv.usFbDiv); | 2785 | dividers->whole_fb_div = le16_to_cpu(args.v3.ulFbDiv.usFbDiv); |
2786 | dividers->frac_fb_div = le16_to_cpu(args.v3.ulFbDiv.usFbDivFrac); | 2786 | dividers->frac_fb_div = le16_to_cpu(args.v3.ulFbDiv.usFbDivFrac); |
2787 | dividers->ref_div = args.v3.ucRefDiv; | 2787 | dividers->ref_div = args.v3.ucRefDiv; |
2788 | dividers->vco_mode = (args.v3.ucCntlFlag & | 2788 | dividers->vco_mode = (args.v3.ucCntlFlag & |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 82335e38ec4f..63398ae1dbf5 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -1163,6 +1163,7 @@ int radeon_device_init(struct radeon_device *rdev, | |||
1163 | mutex_init(&rdev->gem.mutex); | 1163 | mutex_init(&rdev->gem.mutex); |
1164 | mutex_init(&rdev->pm.mutex); | 1164 | mutex_init(&rdev->pm.mutex); |
1165 | mutex_init(&rdev->gpu_clock_mutex); | 1165 | mutex_init(&rdev->gpu_clock_mutex); |
1166 | mutex_init(&rdev->srbm_mutex); | ||
1166 | init_rwsem(&rdev->pm.mclk_lock); | 1167 | init_rwsem(&rdev->pm.mclk_lock); |
1167 | init_rwsem(&rdev->exclusive_lock); | 1168 | init_rwsem(&rdev->exclusive_lock); |
1168 | init_waitqueue_head(&rdev->irq.vblank_queue); | 1169 | init_waitqueue_head(&rdev->irq.vblank_queue); |
@@ -1519,6 +1520,7 @@ int radeon_gpu_reset(struct radeon_device *rdev) | |||
1519 | radeon_save_bios_scratch_regs(rdev); | 1520 | radeon_save_bios_scratch_regs(rdev); |
1520 | /* block TTM */ | 1521 | /* block TTM */ |
1521 | resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev); | 1522 | resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev); |
1523 | radeon_pm_suspend(rdev); | ||
1522 | radeon_suspend(rdev); | 1524 | radeon_suspend(rdev); |
1523 | 1525 | ||
1524 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { | 1526 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { |
@@ -1564,6 +1566,7 @@ retry: | |||
1564 | } | 1566 | } |
1565 | } | 1567 | } |
1566 | 1568 | ||
1569 | radeon_pm_resume(rdev); | ||
1567 | drm_helper_resume_force_mode(rdev->ddev); | 1570 | drm_helper_resume_force_mode(rdev->ddev); |
1568 | 1571 | ||
1569 | ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched); | 1572 | ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched); |
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 7ddb0efe2408..ddb8f8e04eb5 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c | |||
@@ -782,7 +782,7 @@ int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring) | |||
782 | 782 | ||
783 | } else { | 783 | } else { |
784 | /* put fence directly behind firmware */ | 784 | /* put fence directly behind firmware */ |
785 | index = ALIGN(rdev->uvd.fw_size, 8); | 785 | index = ALIGN(rdev->uvd_fw->size, 8); |
786 | rdev->fence_drv[ring].cpu_addr = rdev->uvd.cpu_addr + index; | 786 | rdev->fence_drv[ring].cpu_addr = rdev->uvd.cpu_addr + index; |
787 | rdev->fence_drv[ring].gpu_addr = rdev->uvd.gpu_addr + index; | 787 | rdev->fence_drv[ring].gpu_addr = rdev->uvd.gpu_addr + index; |
788 | } | 788 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index 6a51d943ccf4..b990b1a2bd50 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c | |||
@@ -207,7 +207,6 @@ void radeon_gart_table_vram_free(struct radeon_device *rdev) | |||
207 | if (rdev->gart.robj == NULL) { | 207 | if (rdev->gart.robj == NULL) { |
208 | return; | 208 | return; |
209 | } | 209 | } |
210 | radeon_gart_table_vram_unpin(rdev); | ||
211 | radeon_bo_unref(&rdev->gart.robj); | 210 | radeon_bo_unref(&rdev->gart.robj); |
212 | } | 211 | } |
213 | 212 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index f374c467aaca..c557850cd345 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
@@ -1176,7 +1176,14 @@ int radeon_pm_init(struct radeon_device *rdev) | |||
1176 | case CHIP_VERDE: | 1176 | case CHIP_VERDE: |
1177 | case CHIP_OLAND: | 1177 | case CHIP_OLAND: |
1178 | case CHIP_HAINAN: | 1178 | case CHIP_HAINAN: |
1179 | if (radeon_dpm == 1) | 1179 | /* DPM requires the RLC, RV770+ dGPU requires SMC */ |
1180 | if (!rdev->rlc_fw) | ||
1181 | rdev->pm.pm_method = PM_METHOD_PROFILE; | ||
1182 | else if ((rdev->family >= CHIP_RV770) && | ||
1183 | (!(rdev->flags & RADEON_IS_IGP)) && | ||
1184 | (!rdev->smc_fw)) | ||
1185 | rdev->pm.pm_method = PM_METHOD_PROFILE; | ||
1186 | else if (radeon_dpm == 1) | ||
1180 | rdev->pm.pm_method = PM_METHOD_DPM; | 1187 | rdev->pm.pm_method = PM_METHOD_DPM; |
1181 | else | 1188 | else |
1182 | rdev->pm.pm_method = PM_METHOD_PROFILE; | 1189 | rdev->pm.pm_method = PM_METHOD_PROFILE; |
diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index 414fd145d20e..f1c15754e73c 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c | |||
@@ -56,7 +56,6 @@ static void radeon_uvd_idle_work_handler(struct work_struct *work); | |||
56 | 56 | ||
57 | int radeon_uvd_init(struct radeon_device *rdev) | 57 | int radeon_uvd_init(struct radeon_device *rdev) |
58 | { | 58 | { |
59 | const struct firmware *fw; | ||
60 | unsigned long bo_size; | 59 | unsigned long bo_size; |
61 | const char *fw_name; | 60 | const char *fw_name; |
62 | int i, r; | 61 | int i, r; |
@@ -105,14 +104,14 @@ int radeon_uvd_init(struct radeon_device *rdev) | |||
105 | return -EINVAL; | 104 | return -EINVAL; |
106 | } | 105 | } |
107 | 106 | ||
108 | r = request_firmware(&fw, fw_name, rdev->dev); | 107 | r = request_firmware(&rdev->uvd_fw, fw_name, rdev->dev); |
109 | if (r) { | 108 | if (r) { |
110 | dev_err(rdev->dev, "radeon_uvd: Can't load firmware \"%s\"\n", | 109 | dev_err(rdev->dev, "radeon_uvd: Can't load firmware \"%s\"\n", |
111 | fw_name); | 110 | fw_name); |
112 | return r; | 111 | return r; |
113 | } | 112 | } |
114 | 113 | ||
115 | bo_size = RADEON_GPU_PAGE_ALIGN(fw->size + 8) + | 114 | bo_size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 8) + |
116 | RADEON_UVD_STACK_SIZE + RADEON_UVD_HEAP_SIZE; | 115 | RADEON_UVD_STACK_SIZE + RADEON_UVD_HEAP_SIZE; |
117 | r = radeon_bo_create(rdev, bo_size, PAGE_SIZE, true, | 116 | r = radeon_bo_create(rdev, bo_size, PAGE_SIZE, true, |
118 | RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->uvd.vcpu_bo); | 117 | RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->uvd.vcpu_bo); |
@@ -145,12 +144,6 @@ int radeon_uvd_init(struct radeon_device *rdev) | |||
145 | 144 | ||
146 | radeon_bo_unreserve(rdev->uvd.vcpu_bo); | 145 | radeon_bo_unreserve(rdev->uvd.vcpu_bo); |
147 | 146 | ||
148 | rdev->uvd.fw_size = fw->size; | ||
149 | memset(rdev->uvd.cpu_addr, 0, bo_size); | ||
150 | memcpy(rdev->uvd.cpu_addr, fw->data, fw->size); | ||
151 | |||
152 | release_firmware(fw); | ||
153 | |||
154 | for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { | 147 | for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { |
155 | atomic_set(&rdev->uvd.handles[i], 0); | 148 | atomic_set(&rdev->uvd.handles[i], 0); |
156 | rdev->uvd.filp[i] = NULL; | 149 | rdev->uvd.filp[i] = NULL; |
@@ -174,33 +167,60 @@ void radeon_uvd_fini(struct radeon_device *rdev) | |||
174 | } | 167 | } |
175 | 168 | ||
176 | radeon_bo_unref(&rdev->uvd.vcpu_bo); | 169 | radeon_bo_unref(&rdev->uvd.vcpu_bo); |
170 | |||
171 | release_firmware(rdev->uvd_fw); | ||
177 | } | 172 | } |
178 | 173 | ||
179 | int radeon_uvd_suspend(struct radeon_device *rdev) | 174 | int radeon_uvd_suspend(struct radeon_device *rdev) |
180 | { | 175 | { |
181 | unsigned size; | 176 | unsigned size; |
177 | void *ptr; | ||
178 | int i; | ||
182 | 179 | ||
183 | if (rdev->uvd.vcpu_bo == NULL) | 180 | if (rdev->uvd.vcpu_bo == NULL) |
184 | return 0; | 181 | return 0; |
185 | 182 | ||
183 | for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) | ||
184 | if (atomic_read(&rdev->uvd.handles[i])) | ||
185 | break; | ||
186 | |||
187 | if (i == RADEON_MAX_UVD_HANDLES) | ||
188 | return 0; | ||
189 | |||
186 | size = radeon_bo_size(rdev->uvd.vcpu_bo); | 190 | size = radeon_bo_size(rdev->uvd.vcpu_bo); |
191 | size -= rdev->uvd_fw->size; | ||
192 | |||
193 | ptr = rdev->uvd.cpu_addr; | ||
194 | ptr += rdev->uvd_fw->size; | ||
195 | |||
187 | rdev->uvd.saved_bo = kmalloc(size, GFP_KERNEL); | 196 | rdev->uvd.saved_bo = kmalloc(size, GFP_KERNEL); |
188 | memcpy(rdev->uvd.saved_bo, rdev->uvd.cpu_addr, size); | 197 | memcpy(rdev->uvd.saved_bo, ptr, size); |
189 | 198 | ||
190 | return 0; | 199 | return 0; |
191 | } | 200 | } |
192 | 201 | ||
193 | int radeon_uvd_resume(struct radeon_device *rdev) | 202 | int radeon_uvd_resume(struct radeon_device *rdev) |
194 | { | 203 | { |
204 | unsigned size; | ||
205 | void *ptr; | ||
206 | |||
195 | if (rdev->uvd.vcpu_bo == NULL) | 207 | if (rdev->uvd.vcpu_bo == NULL) |
196 | return -EINVAL; | 208 | return -EINVAL; |
197 | 209 | ||
210 | memcpy(rdev->uvd.cpu_addr, rdev->uvd_fw->data, rdev->uvd_fw->size); | ||
211 | |||
212 | size = radeon_bo_size(rdev->uvd.vcpu_bo); | ||
213 | size -= rdev->uvd_fw->size; | ||
214 | |||
215 | ptr = rdev->uvd.cpu_addr; | ||
216 | ptr += rdev->uvd_fw->size; | ||
217 | |||
198 | if (rdev->uvd.saved_bo != NULL) { | 218 | if (rdev->uvd.saved_bo != NULL) { |
199 | unsigned size = radeon_bo_size(rdev->uvd.vcpu_bo); | 219 | memcpy(ptr, rdev->uvd.saved_bo, size); |
200 | memcpy(rdev->uvd.cpu_addr, rdev->uvd.saved_bo, size); | ||
201 | kfree(rdev->uvd.saved_bo); | 220 | kfree(rdev->uvd.saved_bo); |
202 | rdev->uvd.saved_bo = NULL; | 221 | rdev->uvd.saved_bo = NULL; |
203 | } | 222 | } else |
223 | memset(ptr, 0, size); | ||
204 | 224 | ||
205 | return 0; | 225 | return 0; |
206 | } | 226 | } |
@@ -215,8 +235,8 @@ void radeon_uvd_free_handles(struct radeon_device *rdev, struct drm_file *filp) | |||
215 | { | 235 | { |
216 | int i, r; | 236 | int i, r; |
217 | for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { | 237 | for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { |
218 | if (rdev->uvd.filp[i] == filp) { | 238 | uint32_t handle = atomic_read(&rdev->uvd.handles[i]); |
219 | uint32_t handle = atomic_read(&rdev->uvd.handles[i]); | 239 | if (handle != 0 && rdev->uvd.filp[i] == filp) { |
220 | struct radeon_fence *fence; | 240 | struct radeon_fence *fence; |
221 | 241 | ||
222 | r = radeon_uvd_get_destroy_msg(rdev, | 242 | r = radeon_uvd_get_destroy_msg(rdev, |
@@ -337,8 +357,10 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo, | |||
337 | } | 357 | } |
338 | 358 | ||
339 | r = radeon_bo_kmap(bo, &ptr); | 359 | r = radeon_bo_kmap(bo, &ptr); |
340 | if (r) | 360 | if (r) { |
361 | DRM_ERROR("Failed mapping the UVD message (%d)!\n", r); | ||
341 | return r; | 362 | return r; |
363 | } | ||
342 | 364 | ||
343 | msg = ptr + offset; | 365 | msg = ptr + offset; |
344 | 366 | ||
@@ -364,8 +386,14 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo, | |||
364 | radeon_bo_kunmap(bo); | 386 | radeon_bo_kunmap(bo); |
365 | return 0; | 387 | return 0; |
366 | } else { | 388 | } else { |
367 | /* it's a create msg, no special handling needed */ | ||
368 | radeon_bo_kunmap(bo); | 389 | radeon_bo_kunmap(bo); |
390 | |||
391 | if (msg_type != 0) { | ||
392 | DRM_ERROR("Illegal UVD message type (%d)!\n", msg_type); | ||
393 | return -EINVAL; | ||
394 | } | ||
395 | |||
396 | /* it's a create msg, no special handling needed */ | ||
369 | } | 397 | } |
370 | 398 | ||
371 | /* create or decode, validate the handle */ | 399 | /* create or decode, validate the handle */ |
@@ -388,7 +416,7 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo, | |||
388 | 416 | ||
389 | static int radeon_uvd_cs_reloc(struct radeon_cs_parser *p, | 417 | static int radeon_uvd_cs_reloc(struct radeon_cs_parser *p, |
390 | int data0, int data1, | 418 | int data0, int data1, |
391 | unsigned buf_sizes[]) | 419 | unsigned buf_sizes[], bool *has_msg_cmd) |
392 | { | 420 | { |
393 | struct radeon_cs_chunk *relocs_chunk; | 421 | struct radeon_cs_chunk *relocs_chunk; |
394 | struct radeon_cs_reloc *reloc; | 422 | struct radeon_cs_reloc *reloc; |
@@ -417,7 +445,7 @@ static int radeon_uvd_cs_reloc(struct radeon_cs_parser *p, | |||
417 | 445 | ||
418 | if (cmd < 0x4) { | 446 | if (cmd < 0x4) { |
419 | if ((end - start) < buf_sizes[cmd]) { | 447 | if ((end - start) < buf_sizes[cmd]) { |
420 | DRM_ERROR("buffer to small (%d / %d)!\n", | 448 | DRM_ERROR("buffer (%d) to small (%d / %d)!\n", cmd, |
421 | (unsigned)(end - start), buf_sizes[cmd]); | 449 | (unsigned)(end - start), buf_sizes[cmd]); |
422 | return -EINVAL; | 450 | return -EINVAL; |
423 | } | 451 | } |
@@ -442,9 +470,17 @@ static int radeon_uvd_cs_reloc(struct radeon_cs_parser *p, | |||
442 | } | 470 | } |
443 | 471 | ||
444 | if (cmd == 0) { | 472 | if (cmd == 0) { |
473 | if (*has_msg_cmd) { | ||
474 | DRM_ERROR("More than one message in a UVD-IB!\n"); | ||
475 | return -EINVAL; | ||
476 | } | ||
477 | *has_msg_cmd = true; | ||
445 | r = radeon_uvd_cs_msg(p, reloc->robj, offset, buf_sizes); | 478 | r = radeon_uvd_cs_msg(p, reloc->robj, offset, buf_sizes); |
446 | if (r) | 479 | if (r) |
447 | return r; | 480 | return r; |
481 | } else if (!*has_msg_cmd) { | ||
482 | DRM_ERROR("Message needed before other commands are send!\n"); | ||
483 | return -EINVAL; | ||
448 | } | 484 | } |
449 | 485 | ||
450 | return 0; | 486 | return 0; |
@@ -453,7 +489,8 @@ static int radeon_uvd_cs_reloc(struct radeon_cs_parser *p, | |||
453 | static int radeon_uvd_cs_reg(struct radeon_cs_parser *p, | 489 | static int radeon_uvd_cs_reg(struct radeon_cs_parser *p, |
454 | struct radeon_cs_packet *pkt, | 490 | struct radeon_cs_packet *pkt, |
455 | int *data0, int *data1, | 491 | int *data0, int *data1, |
456 | unsigned buf_sizes[]) | 492 | unsigned buf_sizes[], |
493 | bool *has_msg_cmd) | ||
457 | { | 494 | { |
458 | int i, r; | 495 | int i, r; |
459 | 496 | ||
@@ -467,7 +504,8 @@ static int radeon_uvd_cs_reg(struct radeon_cs_parser *p, | |||
467 | *data1 = p->idx; | 504 | *data1 = p->idx; |
468 | break; | 505 | break; |
469 | case UVD_GPCOM_VCPU_CMD: | 506 | case UVD_GPCOM_VCPU_CMD: |
470 | r = radeon_uvd_cs_reloc(p, *data0, *data1, buf_sizes); | 507 | r = radeon_uvd_cs_reloc(p, *data0, *data1, |
508 | buf_sizes, has_msg_cmd); | ||
471 | if (r) | 509 | if (r) |
472 | return r; | 510 | return r; |
473 | break; | 511 | break; |
@@ -488,6 +526,9 @@ int radeon_uvd_cs_parse(struct radeon_cs_parser *p) | |||
488 | struct radeon_cs_packet pkt; | 526 | struct radeon_cs_packet pkt; |
489 | int r, data0 = 0, data1 = 0; | 527 | int r, data0 = 0, data1 = 0; |
490 | 528 | ||
529 | /* does the IB has a msg command */ | ||
530 | bool has_msg_cmd = false; | ||
531 | |||
491 | /* minimum buffer sizes */ | 532 | /* minimum buffer sizes */ |
492 | unsigned buf_sizes[] = { | 533 | unsigned buf_sizes[] = { |
493 | [0x00000000] = 2048, | 534 | [0x00000000] = 2048, |
@@ -514,8 +555,8 @@ int radeon_uvd_cs_parse(struct radeon_cs_parser *p) | |||
514 | return r; | 555 | return r; |
515 | switch (pkt.type) { | 556 | switch (pkt.type) { |
516 | case RADEON_PACKET_TYPE0: | 557 | case RADEON_PACKET_TYPE0: |
517 | r = radeon_uvd_cs_reg(p, &pkt, &data0, | 558 | r = radeon_uvd_cs_reg(p, &pkt, &data0, &data1, |
518 | &data1, buf_sizes); | 559 | buf_sizes, &has_msg_cmd); |
519 | if (r) | 560 | if (r) |
520 | return r; | 561 | return r; |
521 | break; | 562 | break; |
@@ -527,6 +568,12 @@ int radeon_uvd_cs_parse(struct radeon_cs_parser *p) | |||
527 | return -EINVAL; | 568 | return -EINVAL; |
528 | } | 569 | } |
529 | } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw); | 570 | } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw); |
571 | |||
572 | if (!has_msg_cmd) { | ||
573 | DRM_ERROR("UVD-IBs need a msg command!\n"); | ||
574 | return -EINVAL; | ||
575 | } | ||
576 | |||
530 | return 0; | 577 | return 0; |
531 | } | 578 | } |
532 | 579 | ||
diff --git a/drivers/gpu/drm/radeon/rv6xx_dpm.c b/drivers/gpu/drm/radeon/rv6xx_dpm.c index 363018c60412..bdd888b4db2b 100644 --- a/drivers/gpu/drm/radeon/rv6xx_dpm.c +++ b/drivers/gpu/drm/radeon/rv6xx_dpm.c | |||
@@ -1944,9 +1944,7 @@ static int rv6xx_parse_power_table(struct radeon_device *rdev) | |||
1944 | 1944 | ||
1945 | int rv6xx_dpm_init(struct radeon_device *rdev) | 1945 | int rv6xx_dpm_init(struct radeon_device *rdev) |
1946 | { | 1946 | { |
1947 | int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info); | 1947 | struct radeon_atom_ss ss; |
1948 | uint16_t data_offset, size; | ||
1949 | uint8_t frev, crev; | ||
1950 | struct atom_clock_dividers dividers; | 1948 | struct atom_clock_dividers dividers; |
1951 | struct rv6xx_power_info *pi; | 1949 | struct rv6xx_power_info *pi; |
1952 | int ret; | 1950 | int ret; |
@@ -1989,16 +1987,18 @@ int rv6xx_dpm_init(struct radeon_device *rdev) | |||
1989 | 1987 | ||
1990 | pi->gfx_clock_gating = true; | 1988 | pi->gfx_clock_gating = true; |
1991 | 1989 | ||
1992 | if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size, | 1990 | pi->sclk_ss = radeon_atombios_get_asic_ss_info(rdev, &ss, |
1993 | &frev, &crev, &data_offset)) { | 1991 | ASIC_INTERNAL_ENGINE_SS, 0); |
1994 | pi->sclk_ss = true; | 1992 | pi->mclk_ss = radeon_atombios_get_asic_ss_info(rdev, &ss, |
1995 | pi->mclk_ss = true; | 1993 | ASIC_INTERNAL_MEMORY_SS, 0); |
1994 | |||
1995 | /* Disable sclk ss, causes hangs on a lot of systems */ | ||
1996 | pi->sclk_ss = false; | ||
1997 | |||
1998 | if (pi->sclk_ss || pi->mclk_ss) | ||
1996 | pi->dynamic_ss = true; | 1999 | pi->dynamic_ss = true; |
1997 | } else { | 2000 | else |
1998 | pi->sclk_ss = false; | ||
1999 | pi->mclk_ss = false; | ||
2000 | pi->dynamic_ss = false; | 2001 | pi->dynamic_ss = false; |
2001 | } | ||
2002 | 2002 | ||
2003 | pi->dynamic_pcie_gen2 = true; | 2003 | pi->dynamic_pcie_gen2 = true; |
2004 | 2004 | ||
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 30ea14e8854c..bcc68ec204ad 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
@@ -813,7 +813,7 @@ int rv770_uvd_resume(struct radeon_device *rdev) | |||
813 | 813 | ||
814 | /* programm the VCPU memory controller bits 0-27 */ | 814 | /* programm the VCPU memory controller bits 0-27 */ |
815 | addr = rdev->uvd.gpu_addr >> 3; | 815 | addr = rdev->uvd.gpu_addr >> 3; |
816 | size = RADEON_GPU_PAGE_ALIGN(rdev->uvd.fw_size + 4) >> 3; | 816 | size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 4) >> 3; |
817 | WREG32(UVD_VCPU_CACHE_OFFSET0, addr); | 817 | WREG32(UVD_VCPU_CACHE_OFFSET0, addr); |
818 | WREG32(UVD_VCPU_CACHE_SIZE0, size); | 818 | WREG32(UVD_VCPU_CACHE_SIZE0, size); |
819 | 819 | ||
@@ -1829,6 +1829,8 @@ static int rv770_startup(struct radeon_device *rdev) | |||
1829 | /* enable pcie gen2 link */ | 1829 | /* enable pcie gen2 link */ |
1830 | rv770_pcie_gen2_enable(rdev); | 1830 | rv770_pcie_gen2_enable(rdev); |
1831 | 1831 | ||
1832 | rv770_mc_program(rdev); | ||
1833 | |||
1832 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { | 1834 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { |
1833 | r = r600_init_microcode(rdev); | 1835 | r = r600_init_microcode(rdev); |
1834 | if (r) { | 1836 | if (r) { |
@@ -1841,7 +1843,6 @@ static int rv770_startup(struct radeon_device *rdev) | |||
1841 | if (r) | 1843 | if (r) |
1842 | return r; | 1844 | return r; |
1843 | 1845 | ||
1844 | rv770_mc_program(rdev); | ||
1845 | if (rdev->flags & RADEON_IS_AGP) { | 1846 | if (rdev->flags & RADEON_IS_AGP) { |
1846 | rv770_agp_enable(rdev); | 1847 | rv770_agp_enable(rdev); |
1847 | } else { | 1848 | } else { |
@@ -1983,6 +1984,7 @@ int rv770_resume(struct radeon_device *rdev) | |||
1983 | int rv770_suspend(struct radeon_device *rdev) | 1984 | int rv770_suspend(struct radeon_device *rdev) |
1984 | { | 1985 | { |
1985 | r600_audio_fini(rdev); | 1986 | r600_audio_fini(rdev); |
1987 | r600_uvd_stop(rdev); | ||
1986 | radeon_uvd_suspend(rdev); | 1988 | radeon_uvd_suspend(rdev); |
1987 | r700_cp_stop(rdev); | 1989 | r700_cp_stop(rdev); |
1988 | r600_dma_stop(rdev); | 1990 | r600_dma_stop(rdev); |
@@ -2098,6 +2100,7 @@ void rv770_fini(struct radeon_device *rdev) | |||
2098 | radeon_ib_pool_fini(rdev); | 2100 | radeon_ib_pool_fini(rdev); |
2099 | radeon_irq_kms_fini(rdev); | 2101 | radeon_irq_kms_fini(rdev); |
2100 | rv770_pcie_gart_fini(rdev); | 2102 | rv770_pcie_gart_fini(rdev); |
2103 | r600_uvd_stop(rdev); | ||
2101 | radeon_uvd_fini(rdev); | 2104 | radeon_uvd_fini(rdev); |
2102 | r600_vram_scratch_fini(rdev); | 2105 | r600_vram_scratch_fini(rdev); |
2103 | radeon_gem_fini(rdev); | 2106 | radeon_gem_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/rv770_dpm.c b/drivers/gpu/drm/radeon/rv770_dpm.c index 2d347925f77d..094c67a29d0d 100644 --- a/drivers/gpu/drm/radeon/rv770_dpm.c +++ b/drivers/gpu/drm/radeon/rv770_dpm.c | |||
@@ -2319,12 +2319,25 @@ int rv7xx_parse_power_table(struct radeon_device *rdev) | |||
2319 | return 0; | 2319 | return 0; |
2320 | } | 2320 | } |
2321 | 2321 | ||
2322 | void rv770_get_engine_memory_ss(struct radeon_device *rdev) | ||
2323 | { | ||
2324 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); | ||
2325 | struct radeon_atom_ss ss; | ||
2326 | |||
2327 | pi->sclk_ss = radeon_atombios_get_asic_ss_info(rdev, &ss, | ||
2328 | ASIC_INTERNAL_ENGINE_SS, 0); | ||
2329 | pi->mclk_ss = radeon_atombios_get_asic_ss_info(rdev, &ss, | ||
2330 | ASIC_INTERNAL_MEMORY_SS, 0); | ||
2331 | |||
2332 | if (pi->sclk_ss || pi->mclk_ss) | ||
2333 | pi->dynamic_ss = true; | ||
2334 | else | ||
2335 | pi->dynamic_ss = false; | ||
2336 | } | ||
2337 | |||
2322 | int rv770_dpm_init(struct radeon_device *rdev) | 2338 | int rv770_dpm_init(struct radeon_device *rdev) |
2323 | { | 2339 | { |
2324 | struct rv7xx_power_info *pi; | 2340 | struct rv7xx_power_info *pi; |
2325 | int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info); | ||
2326 | uint16_t data_offset, size; | ||
2327 | uint8_t frev, crev; | ||
2328 | struct atom_clock_dividers dividers; | 2341 | struct atom_clock_dividers dividers; |
2329 | int ret; | 2342 | int ret; |
2330 | 2343 | ||
@@ -2369,16 +2382,7 @@ int rv770_dpm_init(struct radeon_device *rdev) | |||
2369 | pi->mvdd_control = | 2382 | pi->mvdd_control = |
2370 | radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC, 0); | 2383 | radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC, 0); |
2371 | 2384 | ||
2372 | if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size, | 2385 | rv770_get_engine_memory_ss(rdev); |
2373 | &frev, &crev, &data_offset)) { | ||
2374 | pi->sclk_ss = true; | ||
2375 | pi->mclk_ss = true; | ||
2376 | pi->dynamic_ss = true; | ||
2377 | } else { | ||
2378 | pi->sclk_ss = false; | ||
2379 | pi->mclk_ss = false; | ||
2380 | pi->dynamic_ss = false; | ||
2381 | } | ||
2382 | 2386 | ||
2383 | pi->asi = RV770_ASI_DFLT; | 2387 | pi->asi = RV770_ASI_DFLT; |
2384 | pi->pasi = RV770_HASI_DFLT; | 2388 | pi->pasi = RV770_HASI_DFLT; |
@@ -2393,8 +2397,7 @@ int rv770_dpm_init(struct radeon_device *rdev) | |||
2393 | 2397 | ||
2394 | pi->dynamic_pcie_gen2 = true; | 2398 | pi->dynamic_pcie_gen2 = true; |
2395 | 2399 | ||
2396 | if (pi->gfx_clock_gating && | 2400 | if (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE) |
2397 | (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE)) | ||
2398 | pi->thermal_protection = true; | 2401 | pi->thermal_protection = true; |
2399 | else | 2402 | else |
2400 | pi->thermal_protection = false; | 2403 | pi->thermal_protection = false; |
diff --git a/drivers/gpu/drm/radeon/rv770_dpm.h b/drivers/gpu/drm/radeon/rv770_dpm.h index 96b1b2a62a8a..9244effc6b59 100644 --- a/drivers/gpu/drm/radeon/rv770_dpm.h +++ b/drivers/gpu/drm/radeon/rv770_dpm.h | |||
@@ -275,6 +275,7 @@ void rv770_set_uvd_clock_before_set_eng_clock(struct radeon_device *rdev, | |||
275 | void rv770_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev, | 275 | void rv770_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev, |
276 | struct radeon_ps *new_ps, | 276 | struct radeon_ps *new_ps, |
277 | struct radeon_ps *old_ps); | 277 | struct radeon_ps *old_ps); |
278 | void rv770_get_engine_memory_ss(struct radeon_device *rdev); | ||
278 | 279 | ||
279 | /* smc */ | 280 | /* smc */ |
280 | int rv770_read_smc_soft_register(struct radeon_device *rdev, | 281 | int rv770_read_smc_soft_register(struct radeon_device *rdev, |
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index d325280e2f9f..daa8d2df8ec5 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
@@ -1663,9 +1663,13 @@ static int si_init_microcode(struct radeon_device *rdev) | |||
1663 | 1663 | ||
1664 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name); | 1664 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name); |
1665 | err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev); | 1665 | err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev); |
1666 | if (err) | 1666 | if (err) { |
1667 | goto out; | 1667 | printk(KERN_ERR |
1668 | if (rdev->smc_fw->size != smc_req_size) { | 1668 | "smc: error loading firmware \"%s\"\n", |
1669 | fw_name); | ||
1670 | release_firmware(rdev->smc_fw); | ||
1671 | rdev->smc_fw = NULL; | ||
1672 | } else if (rdev->smc_fw->size != smc_req_size) { | ||
1669 | printk(KERN_ERR | 1673 | printk(KERN_ERR |
1670 | "si_smc: Bogus length %zu in firmware \"%s\"\n", | 1674 | "si_smc: Bogus length %zu in firmware \"%s\"\n", |
1671 | rdev->smc_fw->size, fw_name); | 1675 | rdev->smc_fw->size, fw_name); |
@@ -5215,14 +5219,12 @@ static void si_enable_mc_ls(struct radeon_device *rdev, | |||
5215 | 5219 | ||
5216 | static void si_init_cg(struct radeon_device *rdev) | 5220 | static void si_init_cg(struct radeon_device *rdev) |
5217 | { | 5221 | { |
5218 | bool has_uvd = true; | ||
5219 | |||
5220 | si_enable_mgcg(rdev, true); | 5222 | si_enable_mgcg(rdev, true); |
5221 | si_enable_cgcg(rdev, true); | 5223 | si_enable_cgcg(rdev, false); |
5222 | /* disable MC LS on Tahiti */ | 5224 | /* disable MC LS on Tahiti */ |
5223 | if (rdev->family == CHIP_TAHITI) | 5225 | if (rdev->family == CHIP_TAHITI) |
5224 | si_enable_mc_ls(rdev, false); | 5226 | si_enable_mc_ls(rdev, false); |
5225 | if (has_uvd) { | 5227 | if (rdev->has_uvd) { |
5226 | si_enable_uvd_mgcg(rdev, true); | 5228 | si_enable_uvd_mgcg(rdev, true); |
5227 | si_init_uvd_internal_cg(rdev); | 5229 | si_init_uvd_internal_cg(rdev); |
5228 | } | 5230 | } |
@@ -5230,9 +5232,7 @@ static void si_init_cg(struct radeon_device *rdev) | |||
5230 | 5232 | ||
5231 | static void si_fini_cg(struct radeon_device *rdev) | 5233 | static void si_fini_cg(struct radeon_device *rdev) |
5232 | { | 5234 | { |
5233 | bool has_uvd = true; | 5235 | if (rdev->has_uvd) |
5234 | |||
5235 | if (has_uvd) | ||
5236 | si_enable_uvd_mgcg(rdev, false); | 5236 | si_enable_uvd_mgcg(rdev, false); |
5237 | si_enable_cgcg(rdev, false); | 5237 | si_enable_cgcg(rdev, false); |
5238 | si_enable_mgcg(rdev, false); | 5238 | si_enable_mgcg(rdev, false); |
@@ -5241,11 +5241,11 @@ static void si_fini_cg(struct radeon_device *rdev) | |||
5241 | static void si_init_pg(struct radeon_device *rdev) | 5241 | static void si_init_pg(struct radeon_device *rdev) |
5242 | { | 5242 | { |
5243 | bool has_pg = false; | 5243 | bool has_pg = false; |
5244 | 5244 | #if 0 | |
5245 | /* only cape verde supports PG */ | 5245 | /* only cape verde supports PG */ |
5246 | if (rdev->family == CHIP_VERDE) | 5246 | if (rdev->family == CHIP_VERDE) |
5247 | has_pg = true; | 5247 | has_pg = true; |
5248 | 5248 | #endif | |
5249 | if (has_pg) { | 5249 | if (has_pg) { |
5250 | si_init_ao_cu_mask(rdev); | 5250 | si_init_ao_cu_mask(rdev); |
5251 | si_init_dma_pg(rdev); | 5251 | si_init_dma_pg(rdev); |
@@ -6422,6 +6422,8 @@ static int si_startup(struct radeon_device *rdev) | |||
6422 | /* enable aspm */ | 6422 | /* enable aspm */ |
6423 | si_program_aspm(rdev); | 6423 | si_program_aspm(rdev); |
6424 | 6424 | ||
6425 | si_mc_program(rdev); | ||
6426 | |||
6425 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw || | 6427 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw || |
6426 | !rdev->rlc_fw || !rdev->mc_fw) { | 6428 | !rdev->rlc_fw || !rdev->mc_fw) { |
6427 | r = si_init_microcode(rdev); | 6429 | r = si_init_microcode(rdev); |
@@ -6441,7 +6443,6 @@ static int si_startup(struct radeon_device *rdev) | |||
6441 | if (r) | 6443 | if (r) |
6442 | return r; | 6444 | return r; |
6443 | 6445 | ||
6444 | si_mc_program(rdev); | ||
6445 | r = si_pcie_gart_enable(rdev); | 6446 | r = si_pcie_gart_enable(rdev); |
6446 | if (r) | 6447 | if (r) |
6447 | return r; | 6448 | return r; |
@@ -6625,7 +6626,7 @@ int si_suspend(struct radeon_device *rdev) | |||
6625 | si_cp_enable(rdev, false); | 6626 | si_cp_enable(rdev, false); |
6626 | cayman_dma_stop(rdev); | 6627 | cayman_dma_stop(rdev); |
6627 | if (rdev->has_uvd) { | 6628 | if (rdev->has_uvd) { |
6628 | r600_uvd_rbc_stop(rdev); | 6629 | r600_uvd_stop(rdev); |
6629 | radeon_uvd_suspend(rdev); | 6630 | radeon_uvd_suspend(rdev); |
6630 | } | 6631 | } |
6631 | si_irq_suspend(rdev); | 6632 | si_irq_suspend(rdev); |
@@ -6767,8 +6768,10 @@ void si_fini(struct radeon_device *rdev) | |||
6767 | radeon_vm_manager_fini(rdev); | 6768 | radeon_vm_manager_fini(rdev); |
6768 | radeon_ib_pool_fini(rdev); | 6769 | radeon_ib_pool_fini(rdev); |
6769 | radeon_irq_kms_fini(rdev); | 6770 | radeon_irq_kms_fini(rdev); |
6770 | if (rdev->has_uvd) | 6771 | if (rdev->has_uvd) { |
6772 | r600_uvd_stop(rdev); | ||
6771 | radeon_uvd_fini(rdev); | 6773 | radeon_uvd_fini(rdev); |
6774 | } | ||
6772 | si_pcie_gart_fini(rdev); | 6775 | si_pcie_gart_fini(rdev); |
6773 | r600_vram_scratch_fini(rdev); | 6776 | r600_vram_scratch_fini(rdev); |
6774 | radeon_gem_fini(rdev); | 6777 | radeon_gem_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index 73aaa2e4c312..88699e3cd868 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c | |||
@@ -37,8 +37,6 @@ | |||
37 | 37 | ||
38 | #define SMC_RAM_END 0x20000 | 38 | #define SMC_RAM_END 0x20000 |
39 | 39 | ||
40 | #define DDR3_DRAM_ROWS 0x2000 | ||
41 | |||
42 | #define SCLK_MIN_DEEPSLEEP_FREQ 1350 | 40 | #define SCLK_MIN_DEEPSLEEP_FREQ 1350 |
43 | 41 | ||
44 | static const struct si_cac_config_reg cac_weights_tahiti[] = | 42 | static const struct si_cac_config_reg cac_weights_tahiti[] = |
@@ -1767,8 +1765,9 @@ static void si_calculate_leakage_for_v_and_t_formula(const struct ni_leakage_coe | |||
1767 | { | 1765 | { |
1768 | s64 kt, kv, leakage_w, i_leakage, vddc; | 1766 | s64 kt, kv, leakage_w, i_leakage, vddc; |
1769 | s64 temperature, t_slope, t_intercept, av, bv, t_ref; | 1767 | s64 temperature, t_slope, t_intercept, av, bv, t_ref; |
1768 | s64 tmp; | ||
1770 | 1769 | ||
1771 | i_leakage = drm_int2fixp(ileakage / 100); | 1770 | i_leakage = div64_s64(drm_int2fixp(ileakage), 100); |
1772 | vddc = div64_s64(drm_int2fixp(v), 1000); | 1771 | vddc = div64_s64(drm_int2fixp(v), 1000); |
1773 | temperature = div64_s64(drm_int2fixp(t), 1000); | 1772 | temperature = div64_s64(drm_int2fixp(t), 1000); |
1774 | 1773 | ||
@@ -1778,8 +1777,9 @@ static void si_calculate_leakage_for_v_and_t_formula(const struct ni_leakage_coe | |||
1778 | bv = div64_s64(drm_int2fixp(coeff->bv), 100000000); | 1777 | bv = div64_s64(drm_int2fixp(coeff->bv), 100000000); |
1779 | t_ref = drm_int2fixp(coeff->t_ref); | 1778 | t_ref = drm_int2fixp(coeff->t_ref); |
1780 | 1779 | ||
1781 | kt = drm_fixp_div(drm_fixp_exp(drm_fixp_mul(drm_fixp_mul(t_slope, vddc) + t_intercept, temperature)), | 1780 | tmp = drm_fixp_mul(t_slope, vddc) + t_intercept; |
1782 | drm_fixp_exp(drm_fixp_mul(drm_fixp_mul(t_slope, vddc) + t_intercept, t_ref))); | 1781 | kt = drm_fixp_exp(drm_fixp_mul(tmp, temperature)); |
1782 | kt = drm_fixp_div(kt, drm_fixp_exp(drm_fixp_mul(tmp, t_ref))); | ||
1783 | kv = drm_fixp_mul(av, drm_fixp_exp(drm_fixp_mul(bv, vddc))); | 1783 | kv = drm_fixp_mul(av, drm_fixp_exp(drm_fixp_mul(bv, vddc))); |
1784 | 1784 | ||
1785 | leakage_w = drm_fixp_mul(drm_fixp_mul(drm_fixp_mul(i_leakage, kt), kv), vddc); | 1785 | leakage_w = drm_fixp_mul(drm_fixp_mul(drm_fixp_mul(i_leakage, kt), kv), vddc); |
@@ -1931,6 +1931,7 @@ static void si_initialize_powertune_defaults(struct radeon_device *rdev) | |||
1931 | si_pi->cac_override = cac_override_pitcairn; | 1931 | si_pi->cac_override = cac_override_pitcairn; |
1932 | si_pi->powertune_data = &powertune_data_pitcairn; | 1932 | si_pi->powertune_data = &powertune_data_pitcairn; |
1933 | si_pi->dte_data = dte_data_pitcairn; | 1933 | si_pi->dte_data = dte_data_pitcairn; |
1934 | break; | ||
1934 | } | 1935 | } |
1935 | } else if (rdev->family == CHIP_VERDE) { | 1936 | } else if (rdev->family == CHIP_VERDE) { |
1936 | si_pi->lcac_config = lcac_cape_verde; | 1937 | si_pi->lcac_config = lcac_cape_verde; |
@@ -1941,6 +1942,7 @@ static void si_initialize_powertune_defaults(struct radeon_device *rdev) | |||
1941 | case 0x683B: | 1942 | case 0x683B: |
1942 | case 0x683F: | 1943 | case 0x683F: |
1943 | case 0x6829: | 1944 | case 0x6829: |
1945 | case 0x6835: | ||
1944 | si_pi->cac_weights = cac_weights_cape_verde_pro; | 1946 | si_pi->cac_weights = cac_weights_cape_verde_pro; |
1945 | si_pi->dte_data = dte_data_cape_verde; | 1947 | si_pi->dte_data = dte_data_cape_verde; |
1946 | break; | 1948 | break; |
@@ -2901,7 +2903,8 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev, | |||
2901 | { | 2903 | { |
2902 | struct ni_ps *ps = ni_get_ps(rps); | 2904 | struct ni_ps *ps = ni_get_ps(rps); |
2903 | struct radeon_clock_and_voltage_limits *max_limits; | 2905 | struct radeon_clock_and_voltage_limits *max_limits; |
2904 | bool disable_mclk_switching; | 2906 | bool disable_mclk_switching = false; |
2907 | bool disable_sclk_switching = false; | ||
2905 | u32 mclk, sclk; | 2908 | u32 mclk, sclk; |
2906 | u16 vddc, vddci; | 2909 | u16 vddc, vddci; |
2907 | int i; | 2910 | int i; |
@@ -2909,8 +2912,11 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev, | |||
2909 | if ((rdev->pm.dpm.new_active_crtc_count > 1) || | 2912 | if ((rdev->pm.dpm.new_active_crtc_count > 1) || |
2910 | ni_dpm_vblank_too_short(rdev)) | 2913 | ni_dpm_vblank_too_short(rdev)) |
2911 | disable_mclk_switching = true; | 2914 | disable_mclk_switching = true; |
2912 | else | 2915 | |
2913 | disable_mclk_switching = false; | 2916 | if (rps->vclk || rps->dclk) { |
2917 | disable_mclk_switching = true; | ||
2918 | disable_sclk_switching = true; | ||
2919 | } | ||
2914 | 2920 | ||
2915 | if (rdev->pm.dpm.ac_power) | 2921 | if (rdev->pm.dpm.ac_power) |
2916 | max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac; | 2922 | max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac; |
@@ -2938,27 +2944,43 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev, | |||
2938 | 2944 | ||
2939 | if (disable_mclk_switching) { | 2945 | if (disable_mclk_switching) { |
2940 | mclk = ps->performance_levels[ps->performance_level_count - 1].mclk; | 2946 | mclk = ps->performance_levels[ps->performance_level_count - 1].mclk; |
2941 | sclk = ps->performance_levels[0].sclk; | ||
2942 | vddc = ps->performance_levels[0].vddc; | ||
2943 | vddci = ps->performance_levels[ps->performance_level_count - 1].vddci; | 2947 | vddci = ps->performance_levels[ps->performance_level_count - 1].vddci; |
2944 | } else { | 2948 | } else { |
2945 | sclk = ps->performance_levels[0].sclk; | ||
2946 | mclk = ps->performance_levels[0].mclk; | 2949 | mclk = ps->performance_levels[0].mclk; |
2947 | vddc = ps->performance_levels[0].vddc; | ||
2948 | vddci = ps->performance_levels[0].vddci; | 2950 | vddci = ps->performance_levels[0].vddci; |
2949 | } | 2951 | } |
2950 | 2952 | ||
2953 | if (disable_sclk_switching) { | ||
2954 | sclk = ps->performance_levels[ps->performance_level_count - 1].sclk; | ||
2955 | vddc = ps->performance_levels[ps->performance_level_count - 1].vddc; | ||
2956 | } else { | ||
2957 | sclk = ps->performance_levels[0].sclk; | ||
2958 | vddc = ps->performance_levels[0].vddc; | ||
2959 | } | ||
2960 | |||
2951 | /* adjusted low state */ | 2961 | /* adjusted low state */ |
2952 | ps->performance_levels[0].sclk = sclk; | 2962 | ps->performance_levels[0].sclk = sclk; |
2953 | ps->performance_levels[0].mclk = mclk; | 2963 | ps->performance_levels[0].mclk = mclk; |
2954 | ps->performance_levels[0].vddc = vddc; | 2964 | ps->performance_levels[0].vddc = vddc; |
2955 | ps->performance_levels[0].vddci = vddci; | 2965 | ps->performance_levels[0].vddci = vddci; |
2956 | 2966 | ||
2957 | for (i = 1; i < ps->performance_level_count; i++) { | 2967 | if (disable_sclk_switching) { |
2958 | if (ps->performance_levels[i].sclk < ps->performance_levels[i - 1].sclk) | 2968 | sclk = ps->performance_levels[0].sclk; |
2959 | ps->performance_levels[i].sclk = ps->performance_levels[i - 1].sclk; | 2969 | for (i = 1; i < ps->performance_level_count; i++) { |
2960 | if (ps->performance_levels[i].vddc < ps->performance_levels[i - 1].vddc) | 2970 | if (sclk < ps->performance_levels[i].sclk) |
2961 | ps->performance_levels[i].vddc = ps->performance_levels[i - 1].vddc; | 2971 | sclk = ps->performance_levels[i].sclk; |
2972 | } | ||
2973 | for (i = 0; i < ps->performance_level_count; i++) { | ||
2974 | ps->performance_levels[i].sclk = sclk; | ||
2975 | ps->performance_levels[i].vddc = vddc; | ||
2976 | } | ||
2977 | } else { | ||
2978 | for (i = 1; i < ps->performance_level_count; i++) { | ||
2979 | if (ps->performance_levels[i].sclk < ps->performance_levels[i - 1].sclk) | ||
2980 | ps->performance_levels[i].sclk = ps->performance_levels[i - 1].sclk; | ||
2981 | if (ps->performance_levels[i].vddc < ps->performance_levels[i - 1].vddc) | ||
2982 | ps->performance_levels[i].vddc = ps->performance_levels[i - 1].vddc; | ||
2983 | } | ||
2962 | } | 2984 | } |
2963 | 2985 | ||
2964 | if (disable_mclk_switching) { | 2986 | if (disable_mclk_switching) { |
@@ -3237,10 +3259,10 @@ int si_dpm_force_performance_level(struct radeon_device *rdev, | |||
3237 | { | 3259 | { |
3238 | struct radeon_ps *rps = rdev->pm.dpm.current_ps; | 3260 | struct radeon_ps *rps = rdev->pm.dpm.current_ps; |
3239 | struct ni_ps *ps = ni_get_ps(rps); | 3261 | struct ni_ps *ps = ni_get_ps(rps); |
3240 | u32 levels; | 3262 | u32 levels = ps->performance_level_count; |
3241 | 3263 | ||
3242 | if (level == RADEON_DPM_FORCED_LEVEL_HIGH) { | 3264 | if (level == RADEON_DPM_FORCED_LEVEL_HIGH) { |
3243 | if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, 0) != PPSMC_Result_OK) | 3265 | if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, levels) != PPSMC_Result_OK) |
3244 | return -EINVAL; | 3266 | return -EINVAL; |
3245 | 3267 | ||
3246 | if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetForcedLevels, 1) != PPSMC_Result_OK) | 3268 | if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetForcedLevels, 1) != PPSMC_Result_OK) |
@@ -3249,14 +3271,13 @@ int si_dpm_force_performance_level(struct radeon_device *rdev, | |||
3249 | if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetForcedLevels, 0) != PPSMC_Result_OK) | 3271 | if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetForcedLevels, 0) != PPSMC_Result_OK) |
3250 | return -EINVAL; | 3272 | return -EINVAL; |
3251 | 3273 | ||
3252 | levels = ps->performance_level_count - 1; | 3274 | if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, 1) != PPSMC_Result_OK) |
3253 | if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, levels) != PPSMC_Result_OK) | ||
3254 | return -EINVAL; | 3275 | return -EINVAL; |
3255 | } else if (level == RADEON_DPM_FORCED_LEVEL_AUTO) { | 3276 | } else if (level == RADEON_DPM_FORCED_LEVEL_AUTO) { |
3256 | if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetForcedLevels, 0) != PPSMC_Result_OK) | 3277 | if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetForcedLevels, 0) != PPSMC_Result_OK) |
3257 | return -EINVAL; | 3278 | return -EINVAL; |
3258 | 3279 | ||
3259 | if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, 0) != PPSMC_Result_OK) | 3280 | if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, levels) != PPSMC_Result_OK) |
3260 | return -EINVAL; | 3281 | return -EINVAL; |
3261 | } | 3282 | } |
3262 | 3283 | ||
@@ -3620,8 +3641,12 @@ static void si_enable_display_gap(struct radeon_device *rdev) | |||
3620 | { | 3641 | { |
3621 | u32 tmp = RREG32(CG_DISPLAY_GAP_CNTL); | 3642 | u32 tmp = RREG32(CG_DISPLAY_GAP_CNTL); |
3622 | 3643 | ||
3644 | tmp &= ~(DISP1_GAP_MASK | DISP2_GAP_MASK); | ||
3645 | tmp |= (DISP1_GAP(R600_PM_DISPLAY_GAP_IGNORE) | | ||
3646 | DISP2_GAP(R600_PM_DISPLAY_GAP_IGNORE)); | ||
3647 | |||
3623 | tmp &= ~(DISP1_GAP_MCHG_MASK | DISP2_GAP_MCHG_MASK); | 3648 | tmp &= ~(DISP1_GAP_MCHG_MASK | DISP2_GAP_MCHG_MASK); |
3624 | tmp |= (DISP1_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE) | | 3649 | tmp |= (DISP1_GAP_MCHG(R600_PM_DISPLAY_GAP_VBLANK) | |
3625 | DISP2_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE)); | 3650 | DISP2_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE)); |
3626 | WREG32(CG_DISPLAY_GAP_CNTL, tmp); | 3651 | WREG32(CG_DISPLAY_GAP_CNTL, tmp); |
3627 | } | 3652 | } |
@@ -4036,16 +4061,15 @@ static int si_force_switch_to_arb_f0(struct radeon_device *rdev) | |||
4036 | static u32 si_calculate_memory_refresh_rate(struct radeon_device *rdev, | 4061 | static u32 si_calculate_memory_refresh_rate(struct radeon_device *rdev, |
4037 | u32 engine_clock) | 4062 | u32 engine_clock) |
4038 | { | 4063 | { |
4039 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); | ||
4040 | u32 dram_rows; | 4064 | u32 dram_rows; |
4041 | u32 dram_refresh_rate; | 4065 | u32 dram_refresh_rate; |
4042 | u32 mc_arb_rfsh_rate; | 4066 | u32 mc_arb_rfsh_rate; |
4043 | u32 tmp = (RREG32(MC_ARB_RAMCFG) & NOOFROWS_MASK) >> NOOFROWS_SHIFT; | 4067 | u32 tmp = (RREG32(MC_ARB_RAMCFG) & NOOFROWS_MASK) >> NOOFROWS_SHIFT; |
4044 | 4068 | ||
4045 | if (pi->mem_gddr5) | 4069 | if (tmp >= 4) |
4046 | dram_rows = 1 << (tmp + 10); | 4070 | dram_rows = 16384; |
4047 | else | 4071 | else |
4048 | dram_rows = DDR3_DRAM_ROWS; | 4072 | dram_rows = 1 << (tmp + 10); |
4049 | 4073 | ||
4050 | dram_refresh_rate = 1 << ((RREG32(MC_SEQ_MISC0) & 0x3) + 3); | 4074 | dram_refresh_rate = 1 << ((RREG32(MC_SEQ_MISC0) & 0x3) + 3); |
4051 | mc_arb_rfsh_rate = ((engine_clock * 10) * dram_refresh_rate / dram_rows - 32) / 64; | 4075 | mc_arb_rfsh_rate = ((engine_clock * 10) * dram_refresh_rate / dram_rows - 32) / 64; |
@@ -6013,16 +6037,11 @@ int si_dpm_set_power_state(struct radeon_device *rdev) | |||
6013 | return ret; | 6037 | return ret; |
6014 | } | 6038 | } |
6015 | 6039 | ||
6016 | #if 0 | ||
6017 | /* XXX */ | ||
6018 | ret = si_dpm_force_performance_level(rdev, RADEON_DPM_FORCED_LEVEL_AUTO); | 6040 | ret = si_dpm_force_performance_level(rdev, RADEON_DPM_FORCED_LEVEL_AUTO); |
6019 | if (ret) { | 6041 | if (ret) { |
6020 | DRM_ERROR("si_dpm_force_performance_level failed\n"); | 6042 | DRM_ERROR("si_dpm_force_performance_level failed\n"); |
6021 | return ret; | 6043 | return ret; |
6022 | } | 6044 | } |
6023 | #else | ||
6024 | rdev->pm.dpm.forced_level = RADEON_DPM_FORCED_LEVEL_AUTO; | ||
6025 | #endif | ||
6026 | 6045 | ||
6027 | return 0; | 6046 | return 0; |
6028 | } | 6047 | } |
@@ -6254,9 +6273,6 @@ int si_dpm_init(struct radeon_device *rdev) | |||
6254 | struct evergreen_power_info *eg_pi; | 6273 | struct evergreen_power_info *eg_pi; |
6255 | struct ni_power_info *ni_pi; | 6274 | struct ni_power_info *ni_pi; |
6256 | struct si_power_info *si_pi; | 6275 | struct si_power_info *si_pi; |
6257 | int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info); | ||
6258 | u16 data_offset, size; | ||
6259 | u8 frev, crev; | ||
6260 | struct atom_clock_dividers dividers; | 6276 | struct atom_clock_dividers dividers; |
6261 | int ret; | 6277 | int ret; |
6262 | u32 mask; | 6278 | u32 mask; |
@@ -6347,16 +6363,7 @@ int si_dpm_init(struct radeon_device *rdev) | |||
6347 | si_pi->vddc_phase_shed_control = | 6363 | si_pi->vddc_phase_shed_control = |
6348 | radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, VOLTAGE_OBJ_PHASE_LUT); | 6364 | radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, VOLTAGE_OBJ_PHASE_LUT); |
6349 | 6365 | ||
6350 | if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size, | 6366 | rv770_get_engine_memory_ss(rdev); |
6351 | &frev, &crev, &data_offset)) { | ||
6352 | pi->sclk_ss = true; | ||
6353 | pi->mclk_ss = true; | ||
6354 | pi->dynamic_ss = true; | ||
6355 | } else { | ||
6356 | pi->sclk_ss = false; | ||
6357 | pi->mclk_ss = false; | ||
6358 | pi->dynamic_ss = true; | ||
6359 | } | ||
6360 | 6367 | ||
6361 | pi->asi = RV770_ASI_DFLT; | 6368 | pi->asi = RV770_ASI_DFLT; |
6362 | pi->pasi = CYPRESS_HASI_DFLT; | 6369 | pi->pasi = CYPRESS_HASI_DFLT; |
@@ -6367,8 +6374,7 @@ int si_dpm_init(struct radeon_device *rdev) | |||
6367 | eg_pi->sclk_deep_sleep = true; | 6374 | eg_pi->sclk_deep_sleep = true; |
6368 | si_pi->sclk_deep_sleep_above_low = false; | 6375 | si_pi->sclk_deep_sleep_above_low = false; |
6369 | 6376 | ||
6370 | if (pi->gfx_clock_gating && | 6377 | if (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE) |
6371 | (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE)) | ||
6372 | pi->thermal_protection = true; | 6378 | pi->thermal_protection = true; |
6373 | else | 6379 | else |
6374 | pi->thermal_protection = false; | 6380 | pi->thermal_protection = false; |