diff options
author | Dave Airlie <airlied@redhat.com> | 2012-05-02 04:21:50 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2012-05-02 04:22:29 -0400 |
commit | 5bc69bf9aeb73547cad8e1ce683a103fe9728282 (patch) | |
tree | d3ef275532fc4391cb645f8b4d45d39d7fbb73f4 /drivers/gpu | |
parent | c6543a6e64ad8e456674a1c4a01dd024e38b665f (diff) | |
parent | a85d4bcb8a0cd5b3c754f98ff91ef2b9b3a73bc5 (diff) |
Merge tag 'drm-intel-next-2012-04-23' of git://people.freedesktop.org/~danvet/drm-intel into drm-core-next
Daniel Vetter writes:
A new drm-intel-next pull. Highlights:
- More gmbus patches from Daniel Kurtz, I think gmbus is now ready, all
known issues fixed.
- Fencing cleanup and pipelined fencing removal from Chris.
- rc6 residency interface from Ben, useful for powertop.
- Cleanups and code reorg around the ringbuffer code (Ben&me).
- Use hw semaphores in the pageflip code from Ben.
- More vlv stuff from Jesse, unfortunately his vlv cpu is doa, so less
merged than I've hoped for - we still have the unused function warning :(
- More hsw patches from Eugeni, again, not yet enabled fully.
- intel_pm.c refactoring from Eugeni.
- Ironlake sprite support from Chris.
- And various smaller improvements/fixes all over the place.
Note that this pull request also contains a backmerge of -rc3 to sort out
a few things in -next. I've also had to frob the shortlog a bit to exclude
anything that -rc3 brings in with this pull.
Regression wise we have a few strange bugs going on, but for all of them
closer inspection revealed that they've been pre-existing, just now
slightly more likely to be hit. And for most of them we have a patch
already. Otherwise QA has not reported any regressions, and I'm also not
aware of anything bad happening in 3.4.
* tag 'drm-intel-next-2012-04-23' of git://people.freedesktop.org/~danvet/drm-intel: (420 commits)
drm/i915: rc6 residency (fix the fix)
drm/i915/tv: fix open-coded ARRAY_SIZE.
drm/i915: invalidate render cache on gen2
drm/i915: Silence the change of LVDS sync polarity
drm/i915: add generic power management initialization
drm/i915: move clock gating functionality into intel_pm module
drm/i915: move emon functionality into intel_pm module
drm/i915: move drps, rps and rc6-related functions to intel_pm
drm/i915: fix line breaks in intel_pm
drm/i915: move watermarks settings into intel_pm module
drm/i915: move fbc-related functionality into intel_pm module
drm/i915: Refactor get_fence() to use the common fence writing routine
drm/i915: Refactor fence clearing to use the common fence writing routine
drm/i915: Refactor put_fence() to use the common fence writing routine
drm/i915: Prepare to consolidate fence writing
drm/i915: Remove the unsightly "optimisation" from flush_fence()
drm/i915: Simplify fence finding
drm/i915: Discard the unused obj->last_fenced_ring
drm/i915: Remove unused ring->setup_seqno
drm/i915: Remove fence pipelining
...
Diffstat (limited to 'drivers/gpu')
48 files changed, 4588 insertions, 4247 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_buf.c b/drivers/gpu/drm/exynos/exynos_drm_buf.c index 4a3a5f72ed4a..de8d2090bce3 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_buf.c +++ b/drivers/gpu/drm/exynos/exynos_drm_buf.c | |||
@@ -34,14 +34,14 @@ | |||
34 | static int lowlevel_buffer_allocate(struct drm_device *dev, | 34 | static int lowlevel_buffer_allocate(struct drm_device *dev, |
35 | unsigned int flags, struct exynos_drm_gem_buf *buf) | 35 | unsigned int flags, struct exynos_drm_gem_buf *buf) |
36 | { | 36 | { |
37 | dma_addr_t start_addr, end_addr; | 37 | dma_addr_t start_addr; |
38 | unsigned int npages, page_size, i = 0; | 38 | unsigned int npages, page_size, i = 0; |
39 | struct scatterlist *sgl; | 39 | struct scatterlist *sgl; |
40 | int ret = 0; | 40 | int ret = 0; |
41 | 41 | ||
42 | DRM_DEBUG_KMS("%s\n", __FILE__); | 42 | DRM_DEBUG_KMS("%s\n", __FILE__); |
43 | 43 | ||
44 | if (flags & EXYNOS_BO_NONCONTIG) { | 44 | if (IS_NONCONTIG_BUFFER(flags)) { |
45 | DRM_DEBUG_KMS("not support allocation type.\n"); | 45 | DRM_DEBUG_KMS("not support allocation type.\n"); |
46 | return -EINVAL; | 46 | return -EINVAL; |
47 | } | 47 | } |
@@ -52,13 +52,13 @@ static int lowlevel_buffer_allocate(struct drm_device *dev, | |||
52 | } | 52 | } |
53 | 53 | ||
54 | if (buf->size >= SZ_1M) { | 54 | if (buf->size >= SZ_1M) { |
55 | npages = (buf->size >> SECTION_SHIFT) + 1; | 55 | npages = buf->size >> SECTION_SHIFT; |
56 | page_size = SECTION_SIZE; | 56 | page_size = SECTION_SIZE; |
57 | } else if (buf->size >= SZ_64K) { | 57 | } else if (buf->size >= SZ_64K) { |
58 | npages = (buf->size >> 16) + 1; | 58 | npages = buf->size >> 16; |
59 | page_size = SZ_64K; | 59 | page_size = SZ_64K; |
60 | } else { | 60 | } else { |
61 | npages = (buf->size >> PAGE_SHIFT) + 1; | 61 | npages = buf->size >> PAGE_SHIFT; |
62 | page_size = PAGE_SIZE; | 62 | page_size = PAGE_SIZE; |
63 | } | 63 | } |
64 | 64 | ||
@@ -76,26 +76,13 @@ static int lowlevel_buffer_allocate(struct drm_device *dev, | |||
76 | return -ENOMEM; | 76 | return -ENOMEM; |
77 | } | 77 | } |
78 | 78 | ||
79 | buf->kvaddr = dma_alloc_writecombine(dev->dev, buf->size, | 79 | buf->kvaddr = dma_alloc_writecombine(dev->dev, buf->size, |
80 | &buf->dma_addr, GFP_KERNEL); | 80 | &buf->dma_addr, GFP_KERNEL); |
81 | if (!buf->kvaddr) { | 81 | if (!buf->kvaddr) { |
82 | DRM_ERROR("failed to allocate buffer.\n"); | 82 | DRM_ERROR("failed to allocate buffer.\n"); |
83 | ret = -ENOMEM; | 83 | ret = -ENOMEM; |
84 | goto err1; | 84 | goto err1; |
85 | } | 85 | } |
86 | |||
87 | start_addr = buf->dma_addr; | ||
88 | end_addr = buf->dma_addr + buf->size; | ||
89 | |||
90 | buf->pages = kzalloc(sizeof(struct page) * npages, GFP_KERNEL); | ||
91 | if (!buf->pages) { | ||
92 | DRM_ERROR("failed to allocate pages.\n"); | ||
93 | ret = -ENOMEM; | ||
94 | goto err2; | ||
95 | } | ||
96 | |||
97 | start_addr = buf->dma_addr; | ||
98 | end_addr = buf->dma_addr + buf->size; | ||
99 | 86 | ||
100 | buf->pages = kzalloc(sizeof(struct page) * npages, GFP_KERNEL); | 87 | buf->pages = kzalloc(sizeof(struct page) * npages, GFP_KERNEL); |
101 | if (!buf->pages) { | 88 | if (!buf->pages) { |
@@ -105,23 +92,17 @@ static int lowlevel_buffer_allocate(struct drm_device *dev, | |||
105 | } | 92 | } |
106 | 93 | ||
107 | sgl = buf->sgt->sgl; | 94 | sgl = buf->sgt->sgl; |
95 | start_addr = buf->dma_addr; | ||
108 | 96 | ||
109 | while (i < npages) { | 97 | while (i < npages) { |
110 | buf->pages[i] = phys_to_page(start_addr); | 98 | buf->pages[i] = phys_to_page(start_addr); |
111 | sg_set_page(sgl, buf->pages[i], page_size, 0); | 99 | sg_set_page(sgl, buf->pages[i], page_size, 0); |
112 | sg_dma_address(sgl) = start_addr; | 100 | sg_dma_address(sgl) = start_addr; |
113 | start_addr += page_size; | 101 | start_addr += page_size; |
114 | if (end_addr - start_addr < page_size) | ||
115 | break; | ||
116 | sgl = sg_next(sgl); | 102 | sgl = sg_next(sgl); |
117 | i++; | 103 | i++; |
118 | } | 104 | } |
119 | 105 | ||
120 | buf->pages[i] = phys_to_page(start_addr); | ||
121 | |||
122 | sgl = sg_next(sgl); | ||
123 | sg_set_page(sgl, buf->pages[i+1], end_addr - start_addr, 0); | ||
124 | |||
125 | DRM_DEBUG_KMS("vaddr(0x%lx), dma_addr(0x%lx), size(0x%lx)\n", | 106 | DRM_DEBUG_KMS("vaddr(0x%lx), dma_addr(0x%lx), size(0x%lx)\n", |
126 | (unsigned long)buf->kvaddr, | 107 | (unsigned long)buf->kvaddr, |
127 | (unsigned long)buf->dma_addr, | 108 | (unsigned long)buf->dma_addr, |
@@ -150,7 +131,7 @@ static void lowlevel_buffer_deallocate(struct drm_device *dev, | |||
150 | * non-continuous memory would be released by exynos | 131 | * non-continuous memory would be released by exynos |
151 | * gem framework. | 132 | * gem framework. |
152 | */ | 133 | */ |
153 | if (flags & EXYNOS_BO_NONCONTIG) { | 134 | if (IS_NONCONTIG_BUFFER(flags)) { |
154 | DRM_DEBUG_KMS("not support allocation type.\n"); | 135 | DRM_DEBUG_KMS("not support allocation type.\n"); |
155 | return; | 136 | return; |
156 | } | 137 | } |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_core.c b/drivers/gpu/drm/exynos/exynos_drm_core.c index 411832e8e17a..eaf630dc5dba 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_core.c +++ b/drivers/gpu/drm/exynos/exynos_drm_core.c | |||
@@ -54,16 +54,18 @@ static int exynos_drm_subdrv_probe(struct drm_device *dev, | |||
54 | * | 54 | * |
55 | * P.S. note that this driver is considered for modularization. | 55 | * P.S. note that this driver is considered for modularization. |
56 | */ | 56 | */ |
57 | ret = subdrv->probe(dev, subdrv->manager.dev); | 57 | ret = subdrv->probe(dev, subdrv->dev); |
58 | if (ret) | 58 | if (ret) |
59 | return ret; | 59 | return ret; |
60 | } | 60 | } |
61 | 61 | ||
62 | if (subdrv->is_local) | 62 | if (!subdrv->manager) |
63 | return 0; | 63 | return 0; |
64 | 64 | ||
65 | subdrv->manager->dev = subdrv->dev; | ||
66 | |||
65 | /* create and initialize a encoder for this sub driver. */ | 67 | /* create and initialize a encoder for this sub driver. */ |
66 | encoder = exynos_drm_encoder_create(dev, &subdrv->manager, | 68 | encoder = exynos_drm_encoder_create(dev, subdrv->manager, |
67 | (1 << MAX_CRTC) - 1); | 69 | (1 << MAX_CRTC) - 1); |
68 | if (!encoder) { | 70 | if (!encoder) { |
69 | DRM_ERROR("failed to create encoder\n"); | 71 | DRM_ERROR("failed to create encoder\n"); |
@@ -186,7 +188,7 @@ int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file) | |||
186 | 188 | ||
187 | list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) { | 189 | list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) { |
188 | if (subdrv->open) { | 190 | if (subdrv->open) { |
189 | ret = subdrv->open(dev, subdrv->manager.dev, file); | 191 | ret = subdrv->open(dev, subdrv->dev, file); |
190 | if (ret) | 192 | if (ret) |
191 | goto err; | 193 | goto err; |
192 | } | 194 | } |
@@ -197,7 +199,7 @@ int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file) | |||
197 | err: | 199 | err: |
198 | list_for_each_entry_reverse(subdrv, &subdrv->list, list) { | 200 | list_for_each_entry_reverse(subdrv, &subdrv->list, list) { |
199 | if (subdrv->close) | 201 | if (subdrv->close) |
200 | subdrv->close(dev, subdrv->manager.dev, file); | 202 | subdrv->close(dev, subdrv->dev, file); |
201 | } | 203 | } |
202 | return ret; | 204 | return ret; |
203 | } | 205 | } |
@@ -209,7 +211,7 @@ void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file) | |||
209 | 211 | ||
210 | list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) { | 212 | list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) { |
211 | if (subdrv->close) | 213 | if (subdrv->close) |
212 | subdrv->close(dev, subdrv->manager.dev, file); | 214 | subdrv->close(dev, subdrv->dev, file); |
213 | } | 215 | } |
214 | } | 216 | } |
215 | EXPORT_SYMBOL_GPL(exynos_drm_subdrv_close); | 217 | EXPORT_SYMBOL_GPL(exynos_drm_subdrv_close); |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index fbd0a232c93d..1d814175cd49 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h | |||
@@ -225,24 +225,25 @@ struct exynos_drm_private { | |||
225 | * Exynos drm sub driver structure. | 225 | * Exynos drm sub driver structure. |
226 | * | 226 | * |
227 | * @list: sub driver has its own list object to register to exynos drm driver. | 227 | * @list: sub driver has its own list object to register to exynos drm driver. |
228 | * @dev: pointer to device object for subdrv device driver. | ||
228 | * @drm_dev: pointer to drm_device and this pointer would be set | 229 | * @drm_dev: pointer to drm_device and this pointer would be set |
229 | * when sub driver calls exynos_drm_subdrv_register(). | 230 | * when sub driver calls exynos_drm_subdrv_register(). |
230 | * @is_local: appear encoder and connector disrelated device. | 231 | * @manager: subdrv has its own manager to control a hardware appropriately |
232 | * and we can access a hardware drawing on this manager. | ||
231 | * @probe: this callback would be called by exynos drm driver after | 233 | * @probe: this callback would be called by exynos drm driver after |
232 | * subdrv is registered to it. | 234 | * subdrv is registered to it. |
233 | * @remove: this callback is used to release resources created | 235 | * @remove: this callback is used to release resources created |
234 | * by probe callback. | 236 | * by probe callback. |
235 | * @open: this would be called with drm device file open. | 237 | * @open: this would be called with drm device file open. |
236 | * @close: this would be called with drm device file close. | 238 | * @close: this would be called with drm device file close. |
237 | * @manager: subdrv has its own manager to control a hardware appropriately | ||
238 | * and we can access a hardware drawing on this manager. | ||
239 | * @encoder: encoder object owned by this sub driver. | 239 | * @encoder: encoder object owned by this sub driver. |
240 | * @connector: connector object owned by this sub driver. | 240 | * @connector: connector object owned by this sub driver. |
241 | */ | 241 | */ |
242 | struct exynos_drm_subdrv { | 242 | struct exynos_drm_subdrv { |
243 | struct list_head list; | 243 | struct list_head list; |
244 | struct device *dev; | ||
244 | struct drm_device *drm_dev; | 245 | struct drm_device *drm_dev; |
245 | bool is_local; | 246 | struct exynos_drm_manager *manager; |
246 | 247 | ||
247 | int (*probe)(struct drm_device *drm_dev, struct device *dev); | 248 | int (*probe)(struct drm_device *drm_dev, struct device *dev); |
248 | void (*remove)(struct drm_device *dev); | 249 | void (*remove)(struct drm_device *dev); |
@@ -251,7 +252,6 @@ struct exynos_drm_subdrv { | |||
251 | void (*close)(struct drm_device *drm_dev, struct device *dev, | 252 | void (*close)(struct drm_device *drm_dev, struct device *dev, |
252 | struct drm_file *file); | 253 | struct drm_file *file); |
253 | 254 | ||
254 | struct exynos_drm_manager manager; | ||
255 | struct drm_encoder *encoder; | 255 | struct drm_encoder *encoder; |
256 | struct drm_connector *connector; | 256 | struct drm_connector *connector; |
257 | }; | 257 | }; |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index ecb6db229700..29fdbfeb43cb 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c | |||
@@ -172,7 +172,7 @@ static void fimd_dpms(struct device *subdrv_dev, int mode) | |||
172 | static void fimd_apply(struct device *subdrv_dev) | 172 | static void fimd_apply(struct device *subdrv_dev) |
173 | { | 173 | { |
174 | struct fimd_context *ctx = get_fimd_context(subdrv_dev); | 174 | struct fimd_context *ctx = get_fimd_context(subdrv_dev); |
175 | struct exynos_drm_manager *mgr = &ctx->subdrv.manager; | 175 | struct exynos_drm_manager *mgr = ctx->subdrv.manager; |
176 | struct exynos_drm_manager_ops *mgr_ops = mgr->ops; | 176 | struct exynos_drm_manager_ops *mgr_ops = mgr->ops; |
177 | struct exynos_drm_overlay_ops *ovl_ops = mgr->overlay_ops; | 177 | struct exynos_drm_overlay_ops *ovl_ops = mgr->overlay_ops; |
178 | struct fimd_win_data *win_data; | 178 | struct fimd_win_data *win_data; |
@@ -577,6 +577,13 @@ static struct exynos_drm_overlay_ops fimd_overlay_ops = { | |||
577 | .disable = fimd_win_disable, | 577 | .disable = fimd_win_disable, |
578 | }; | 578 | }; |
579 | 579 | ||
580 | static struct exynos_drm_manager fimd_manager = { | ||
581 | .pipe = -1, | ||
582 | .ops = &fimd_manager_ops, | ||
583 | .overlay_ops = &fimd_overlay_ops, | ||
584 | .display_ops = &fimd_display_ops, | ||
585 | }; | ||
586 | |||
580 | static void fimd_finish_pageflip(struct drm_device *drm_dev, int crtc) | 587 | static void fimd_finish_pageflip(struct drm_device *drm_dev, int crtc) |
581 | { | 588 | { |
582 | struct exynos_drm_private *dev_priv = drm_dev->dev_private; | 589 | struct exynos_drm_private *dev_priv = drm_dev->dev_private; |
@@ -628,7 +635,7 @@ static irqreturn_t fimd_irq_handler(int irq, void *dev_id) | |||
628 | struct fimd_context *ctx = (struct fimd_context *)dev_id; | 635 | struct fimd_context *ctx = (struct fimd_context *)dev_id; |
629 | struct exynos_drm_subdrv *subdrv = &ctx->subdrv; | 636 | struct exynos_drm_subdrv *subdrv = &ctx->subdrv; |
630 | struct drm_device *drm_dev = subdrv->drm_dev; | 637 | struct drm_device *drm_dev = subdrv->drm_dev; |
631 | struct exynos_drm_manager *manager = &subdrv->manager; | 638 | struct exynos_drm_manager *manager = subdrv->manager; |
632 | u32 val; | 639 | u32 val; |
633 | 640 | ||
634 | val = readl(ctx->regs + VIDINTCON1); | 641 | val = readl(ctx->regs + VIDINTCON1); |
@@ -744,7 +751,7 @@ static void fimd_clear_win(struct fimd_context *ctx, int win) | |||
744 | static int fimd_power_on(struct fimd_context *ctx, bool enable) | 751 | static int fimd_power_on(struct fimd_context *ctx, bool enable) |
745 | { | 752 | { |
746 | struct exynos_drm_subdrv *subdrv = &ctx->subdrv; | 753 | struct exynos_drm_subdrv *subdrv = &ctx->subdrv; |
747 | struct device *dev = subdrv->manager.dev; | 754 | struct device *dev = subdrv->dev; |
748 | 755 | ||
749 | DRM_DEBUG_KMS("%s\n", __FILE__); | 756 | DRM_DEBUG_KMS("%s\n", __FILE__); |
750 | 757 | ||
@@ -867,13 +874,10 @@ static int __devinit fimd_probe(struct platform_device *pdev) | |||
867 | 874 | ||
868 | subdrv = &ctx->subdrv; | 875 | subdrv = &ctx->subdrv; |
869 | 876 | ||
877 | subdrv->dev = dev; | ||
878 | subdrv->manager = &fimd_manager; | ||
870 | subdrv->probe = fimd_subdrv_probe; | 879 | subdrv->probe = fimd_subdrv_probe; |
871 | subdrv->remove = fimd_subdrv_remove; | 880 | subdrv->remove = fimd_subdrv_remove; |
872 | subdrv->manager.pipe = -1; | ||
873 | subdrv->manager.ops = &fimd_manager_ops; | ||
874 | subdrv->manager.overlay_ops = &fimd_overlay_ops; | ||
875 | subdrv->manager.display_ops = &fimd_display_ops; | ||
876 | subdrv->manager.dev = dev; | ||
877 | 881 | ||
878 | mutex_init(&ctx->lock); | 882 | mutex_init(&ctx->lock); |
879 | 883 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index fa1aa94a3d8e..26d51979116b 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c | |||
@@ -56,9 +56,28 @@ static unsigned int convert_to_vm_err_msg(int msg) | |||
56 | return out_msg; | 56 | return out_msg; |
57 | } | 57 | } |
58 | 58 | ||
59 | static unsigned int mask_gem_flags(unsigned int flags) | 59 | static int check_gem_flags(unsigned int flags) |
60 | { | 60 | { |
61 | return flags &= EXYNOS_BO_NONCONTIG; | 61 | if (flags & ~(EXYNOS_BO_MASK)) { |
62 | DRM_ERROR("invalid flags.\n"); | ||
63 | return -EINVAL; | ||
64 | } | ||
65 | |||
66 | return 0; | ||
67 | } | ||
68 | |||
69 | static unsigned long roundup_gem_size(unsigned long size, unsigned int flags) | ||
70 | { | ||
71 | if (!IS_NONCONTIG_BUFFER(flags)) { | ||
72 | if (size >= SZ_1M) | ||
73 | return roundup(size, SECTION_SIZE); | ||
74 | else if (size >= SZ_64K) | ||
75 | return roundup(size, SZ_64K); | ||
76 | else | ||
77 | goto out; | ||
78 | } | ||
79 | out: | ||
80 | return roundup(size, PAGE_SIZE); | ||
62 | } | 81 | } |
63 | 82 | ||
64 | static struct page **exynos_gem_get_pages(struct drm_gem_object *obj, | 83 | static struct page **exynos_gem_get_pages(struct drm_gem_object *obj, |
@@ -319,10 +338,17 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev, | |||
319 | struct exynos_drm_gem_buf *buf; | 338 | struct exynos_drm_gem_buf *buf; |
320 | int ret; | 339 | int ret; |
321 | 340 | ||
322 | size = roundup(size, PAGE_SIZE); | 341 | if (!size) { |
323 | DRM_DEBUG_KMS("%s: size = 0x%lx\n", __FILE__, size); | 342 | DRM_ERROR("invalid size.\n"); |
343 | return ERR_PTR(-EINVAL); | ||
344 | } | ||
324 | 345 | ||
325 | flags = mask_gem_flags(flags); | 346 | size = roundup_gem_size(size, flags); |
347 | DRM_DEBUG_KMS("%s\n", __FILE__); | ||
348 | |||
349 | ret = check_gem_flags(flags); | ||
350 | if (ret) | ||
351 | return ERR_PTR(ret); | ||
326 | 352 | ||
327 | buf = exynos_drm_init_buf(dev, size); | 353 | buf = exynos_drm_init_buf(dev, size); |
328 | if (!buf) | 354 | if (!buf) |
@@ -331,7 +357,7 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev, | |||
331 | exynos_gem_obj = exynos_drm_gem_init(dev, size); | 357 | exynos_gem_obj = exynos_drm_gem_init(dev, size); |
332 | if (!exynos_gem_obj) { | 358 | if (!exynos_gem_obj) { |
333 | ret = -ENOMEM; | 359 | ret = -ENOMEM; |
334 | goto err; | 360 | goto err_fini_buf; |
335 | } | 361 | } |
336 | 362 | ||
337 | exynos_gem_obj->buffer = buf; | 363 | exynos_gem_obj->buffer = buf; |
@@ -347,18 +373,19 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev, | |||
347 | ret = exynos_drm_gem_get_pages(&exynos_gem_obj->base); | 373 | ret = exynos_drm_gem_get_pages(&exynos_gem_obj->base); |
348 | if (ret < 0) { | 374 | if (ret < 0) { |
349 | drm_gem_object_release(&exynos_gem_obj->base); | 375 | drm_gem_object_release(&exynos_gem_obj->base); |
350 | goto err; | 376 | goto err_fini_buf; |
351 | } | 377 | } |
352 | } else { | 378 | } else { |
353 | ret = exynos_drm_alloc_buf(dev, buf, flags); | 379 | ret = exynos_drm_alloc_buf(dev, buf, flags); |
354 | if (ret < 0) { | 380 | if (ret < 0) { |
355 | drm_gem_object_release(&exynos_gem_obj->base); | 381 | drm_gem_object_release(&exynos_gem_obj->base); |
356 | goto err; | 382 | goto err_fini_buf; |
357 | } | 383 | } |
358 | } | 384 | } |
359 | 385 | ||
360 | return exynos_gem_obj; | 386 | return exynos_gem_obj; |
361 | err: | 387 | |
388 | err_fini_buf: | ||
362 | exynos_drm_fini_buf(dev, buf); | 389 | exynos_drm_fini_buf(dev, buf); |
363 | return ERR_PTR(ret); | 390 | return ERR_PTR(ret); |
364 | } | 391 | } |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h index e40fbad8b705..4ed842039505 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.h +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h | |||
@@ -29,6 +29,8 @@ | |||
29 | #define to_exynos_gem_obj(x) container_of(x,\ | 29 | #define to_exynos_gem_obj(x) container_of(x,\ |
30 | struct exynos_drm_gem_obj, base) | 30 | struct exynos_drm_gem_obj, base) |
31 | 31 | ||
32 | #define IS_NONCONTIG_BUFFER(f) (f & EXYNOS_BO_NONCONTIG) | ||
33 | |||
32 | /* | 34 | /* |
33 | * exynos drm gem buffer structure. | 35 | * exynos drm gem buffer structure. |
34 | * | 36 | * |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c index 14eb26b0ba1c..3424463676e0 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c | |||
@@ -30,9 +30,8 @@ | |||
30 | struct drm_hdmi_context, subdrv); | 30 | struct drm_hdmi_context, subdrv); |
31 | 31 | ||
32 | /* these callback points shoud be set by specific drivers. */ | 32 | /* these callback points shoud be set by specific drivers. */ |
33 | static struct exynos_hdmi_display_ops *hdmi_display_ops; | 33 | static struct exynos_hdmi_ops *hdmi_ops; |
34 | static struct exynos_hdmi_manager_ops *hdmi_manager_ops; | 34 | static struct exynos_mixer_ops *mixer_ops; |
35 | static struct exynos_hdmi_overlay_ops *hdmi_overlay_ops; | ||
36 | 35 | ||
37 | struct drm_hdmi_context { | 36 | struct drm_hdmi_context { |
38 | struct exynos_drm_subdrv subdrv; | 37 | struct exynos_drm_subdrv subdrv; |
@@ -40,31 +39,20 @@ struct drm_hdmi_context { | |||
40 | struct exynos_drm_hdmi_context *mixer_ctx; | 39 | struct exynos_drm_hdmi_context *mixer_ctx; |
41 | }; | 40 | }; |
42 | 41 | ||
43 | void exynos_drm_display_ops_register(struct exynos_hdmi_display_ops | 42 | void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops) |
44 | *display_ops) | ||
45 | { | 43 | { |
46 | DRM_DEBUG_KMS("%s\n", __FILE__); | 44 | DRM_DEBUG_KMS("%s\n", __FILE__); |
47 | 45 | ||
48 | if (display_ops) | 46 | if (ops) |
49 | hdmi_display_ops = display_ops; | 47 | hdmi_ops = ops; |
50 | } | 48 | } |
51 | 49 | ||
52 | void exynos_drm_manager_ops_register(struct exynos_hdmi_manager_ops | 50 | void exynos_mixer_ops_register(struct exynos_mixer_ops *ops) |
53 | *manager_ops) | ||
54 | { | 51 | { |
55 | DRM_DEBUG_KMS("%s\n", __FILE__); | 52 | DRM_DEBUG_KMS("%s\n", __FILE__); |
56 | 53 | ||
57 | if (manager_ops) | 54 | if (ops) |
58 | hdmi_manager_ops = manager_ops; | 55 | mixer_ops = ops; |
59 | } | ||
60 | |||
61 | void exynos_drm_overlay_ops_register(struct exynos_hdmi_overlay_ops | ||
62 | *overlay_ops) | ||
63 | { | ||
64 | DRM_DEBUG_KMS("%s\n", __FILE__); | ||
65 | |||
66 | if (overlay_ops) | ||
67 | hdmi_overlay_ops = overlay_ops; | ||
68 | } | 56 | } |
69 | 57 | ||
70 | static bool drm_hdmi_is_connected(struct device *dev) | 58 | static bool drm_hdmi_is_connected(struct device *dev) |
@@ -73,8 +61,8 @@ static bool drm_hdmi_is_connected(struct device *dev) | |||
73 | 61 | ||
74 | DRM_DEBUG_KMS("%s\n", __FILE__); | 62 | DRM_DEBUG_KMS("%s\n", __FILE__); |
75 | 63 | ||
76 | if (hdmi_display_ops && hdmi_display_ops->is_connected) | 64 | if (hdmi_ops && hdmi_ops->is_connected) |
77 | return hdmi_display_ops->is_connected(ctx->hdmi_ctx->ctx); | 65 | return hdmi_ops->is_connected(ctx->hdmi_ctx->ctx); |
78 | 66 | ||
79 | return false; | 67 | return false; |
80 | } | 68 | } |
@@ -86,9 +74,9 @@ static int drm_hdmi_get_edid(struct device *dev, | |||
86 | 74 | ||
87 | DRM_DEBUG_KMS("%s\n", __FILE__); | 75 | DRM_DEBUG_KMS("%s\n", __FILE__); |
88 | 76 | ||
89 | if (hdmi_display_ops && hdmi_display_ops->get_edid) | 77 | if (hdmi_ops && hdmi_ops->get_edid) |
90 | return hdmi_display_ops->get_edid(ctx->hdmi_ctx->ctx, | 78 | return hdmi_ops->get_edid(ctx->hdmi_ctx->ctx, connector, edid, |
91 | connector, edid, len); | 79 | len); |
92 | 80 | ||
93 | return 0; | 81 | return 0; |
94 | } | 82 | } |
@@ -99,9 +87,8 @@ static int drm_hdmi_check_timing(struct device *dev, void *timing) | |||
99 | 87 | ||
100 | DRM_DEBUG_KMS("%s\n", __FILE__); | 88 | DRM_DEBUG_KMS("%s\n", __FILE__); |
101 | 89 | ||
102 | if (hdmi_display_ops && hdmi_display_ops->check_timing) | 90 | if (hdmi_ops && hdmi_ops->check_timing) |
103 | return hdmi_display_ops->check_timing(ctx->hdmi_ctx->ctx, | 91 | return hdmi_ops->check_timing(ctx->hdmi_ctx->ctx, timing); |
104 | timing); | ||
105 | 92 | ||
106 | return 0; | 93 | return 0; |
107 | } | 94 | } |
@@ -112,8 +99,8 @@ static int drm_hdmi_power_on(struct device *dev, int mode) | |||
112 | 99 | ||
113 | DRM_DEBUG_KMS("%s\n", __FILE__); | 100 | DRM_DEBUG_KMS("%s\n", __FILE__); |
114 | 101 | ||
115 | if (hdmi_display_ops && hdmi_display_ops->power_on) | 102 | if (hdmi_ops && hdmi_ops->power_on) |
116 | return hdmi_display_ops->power_on(ctx->hdmi_ctx->ctx, mode); | 103 | return hdmi_ops->power_on(ctx->hdmi_ctx->ctx, mode); |
117 | 104 | ||
118 | return 0; | 105 | return 0; |
119 | } | 106 | } |
@@ -130,13 +117,13 @@ static int drm_hdmi_enable_vblank(struct device *subdrv_dev) | |||
130 | { | 117 | { |
131 | struct drm_hdmi_context *ctx = to_context(subdrv_dev); | 118 | struct drm_hdmi_context *ctx = to_context(subdrv_dev); |
132 | struct exynos_drm_subdrv *subdrv = &ctx->subdrv; | 119 | struct exynos_drm_subdrv *subdrv = &ctx->subdrv; |
133 | struct exynos_drm_manager *manager = &subdrv->manager; | 120 | struct exynos_drm_manager *manager = subdrv->manager; |
134 | 121 | ||
135 | DRM_DEBUG_KMS("%s\n", __FILE__); | 122 | DRM_DEBUG_KMS("%s\n", __FILE__); |
136 | 123 | ||
137 | if (hdmi_overlay_ops && hdmi_overlay_ops->enable_vblank) | 124 | if (mixer_ops && mixer_ops->enable_vblank) |
138 | return hdmi_overlay_ops->enable_vblank(ctx->mixer_ctx->ctx, | 125 | return mixer_ops->enable_vblank(ctx->mixer_ctx->ctx, |
139 | manager->pipe); | 126 | manager->pipe); |
140 | 127 | ||
141 | return 0; | 128 | return 0; |
142 | } | 129 | } |
@@ -147,8 +134,8 @@ static void drm_hdmi_disable_vblank(struct device *subdrv_dev) | |||
147 | 134 | ||
148 | DRM_DEBUG_KMS("%s\n", __FILE__); | 135 | DRM_DEBUG_KMS("%s\n", __FILE__); |
149 | 136 | ||
150 | if (hdmi_overlay_ops && hdmi_overlay_ops->disable_vblank) | 137 | if (mixer_ops && mixer_ops->disable_vblank) |
151 | return hdmi_overlay_ops->disable_vblank(ctx->mixer_ctx->ctx); | 138 | return mixer_ops->disable_vblank(ctx->mixer_ctx->ctx); |
152 | } | 139 | } |
153 | 140 | ||
154 | static void drm_hdmi_mode_fixup(struct device *subdrv_dev, | 141 | static void drm_hdmi_mode_fixup(struct device *subdrv_dev, |
@@ -160,9 +147,9 @@ static void drm_hdmi_mode_fixup(struct device *subdrv_dev, | |||
160 | 147 | ||
161 | DRM_DEBUG_KMS("%s\n", __FILE__); | 148 | DRM_DEBUG_KMS("%s\n", __FILE__); |
162 | 149 | ||
163 | if (hdmi_manager_ops && hdmi_manager_ops->mode_fixup) | 150 | if (hdmi_ops && hdmi_ops->mode_fixup) |
164 | hdmi_manager_ops->mode_fixup(ctx->hdmi_ctx->ctx, connector, | 151 | hdmi_ops->mode_fixup(ctx->hdmi_ctx->ctx, connector, mode, |
165 | mode, adjusted_mode); | 152 | adjusted_mode); |
166 | } | 153 | } |
167 | 154 | ||
168 | static void drm_hdmi_mode_set(struct device *subdrv_dev, void *mode) | 155 | static void drm_hdmi_mode_set(struct device *subdrv_dev, void *mode) |
@@ -171,8 +158,8 @@ static void drm_hdmi_mode_set(struct device *subdrv_dev, void *mode) | |||
171 | 158 | ||
172 | DRM_DEBUG_KMS("%s\n", __FILE__); | 159 | DRM_DEBUG_KMS("%s\n", __FILE__); |
173 | 160 | ||
174 | if (hdmi_manager_ops && hdmi_manager_ops->mode_set) | 161 | if (hdmi_ops && hdmi_ops->mode_set) |
175 | hdmi_manager_ops->mode_set(ctx->hdmi_ctx->ctx, mode); | 162 | hdmi_ops->mode_set(ctx->hdmi_ctx->ctx, mode); |
176 | } | 163 | } |
177 | 164 | ||
178 | static void drm_hdmi_get_max_resol(struct device *subdrv_dev, | 165 | static void drm_hdmi_get_max_resol(struct device *subdrv_dev, |
@@ -182,9 +169,8 @@ static void drm_hdmi_get_max_resol(struct device *subdrv_dev, | |||
182 | 169 | ||
183 | DRM_DEBUG_KMS("%s\n", __FILE__); | 170 | DRM_DEBUG_KMS("%s\n", __FILE__); |
184 | 171 | ||
185 | if (hdmi_manager_ops && hdmi_manager_ops->get_max_resol) | 172 | if (hdmi_ops && hdmi_ops->get_max_resol) |
186 | hdmi_manager_ops->get_max_resol(ctx->hdmi_ctx->ctx, width, | 173 | hdmi_ops->get_max_resol(ctx->hdmi_ctx->ctx, width, height); |
187 | height); | ||
188 | } | 174 | } |
189 | 175 | ||
190 | static void drm_hdmi_commit(struct device *subdrv_dev) | 176 | static void drm_hdmi_commit(struct device *subdrv_dev) |
@@ -193,8 +179,8 @@ static void drm_hdmi_commit(struct device *subdrv_dev) | |||
193 | 179 | ||
194 | DRM_DEBUG_KMS("%s\n", __FILE__); | 180 | DRM_DEBUG_KMS("%s\n", __FILE__); |
195 | 181 | ||
196 | if (hdmi_manager_ops && hdmi_manager_ops->commit) | 182 | if (hdmi_ops && hdmi_ops->commit) |
197 | hdmi_manager_ops->commit(ctx->hdmi_ctx->ctx); | 183 | hdmi_ops->commit(ctx->hdmi_ctx->ctx); |
198 | } | 184 | } |
199 | 185 | ||
200 | static void drm_hdmi_dpms(struct device *subdrv_dev, int mode) | 186 | static void drm_hdmi_dpms(struct device *subdrv_dev, int mode) |
@@ -209,8 +195,8 @@ static void drm_hdmi_dpms(struct device *subdrv_dev, int mode) | |||
209 | case DRM_MODE_DPMS_STANDBY: | 195 | case DRM_MODE_DPMS_STANDBY: |
210 | case DRM_MODE_DPMS_SUSPEND: | 196 | case DRM_MODE_DPMS_SUSPEND: |
211 | case DRM_MODE_DPMS_OFF: | 197 | case DRM_MODE_DPMS_OFF: |
212 | if (hdmi_manager_ops && hdmi_manager_ops->disable) | 198 | if (hdmi_ops && hdmi_ops->disable) |
213 | hdmi_manager_ops->disable(ctx->hdmi_ctx->ctx); | 199 | hdmi_ops->disable(ctx->hdmi_ctx->ctx); |
214 | break; | 200 | break; |
215 | default: | 201 | default: |
216 | DRM_DEBUG_KMS("unkown dps mode: %d\n", mode); | 202 | DRM_DEBUG_KMS("unkown dps mode: %d\n", mode); |
@@ -235,8 +221,8 @@ static void drm_mixer_mode_set(struct device *subdrv_dev, | |||
235 | 221 | ||
236 | DRM_DEBUG_KMS("%s\n", __FILE__); | 222 | DRM_DEBUG_KMS("%s\n", __FILE__); |
237 | 223 | ||
238 | if (hdmi_overlay_ops && hdmi_overlay_ops->win_mode_set) | 224 | if (mixer_ops && mixer_ops->win_mode_set) |
239 | hdmi_overlay_ops->win_mode_set(ctx->mixer_ctx->ctx, overlay); | 225 | mixer_ops->win_mode_set(ctx->mixer_ctx->ctx, overlay); |
240 | } | 226 | } |
241 | 227 | ||
242 | static void drm_mixer_commit(struct device *subdrv_dev, int zpos) | 228 | static void drm_mixer_commit(struct device *subdrv_dev, int zpos) |
@@ -245,8 +231,8 @@ static void drm_mixer_commit(struct device *subdrv_dev, int zpos) | |||
245 | 231 | ||
246 | DRM_DEBUG_KMS("%s\n", __FILE__); | 232 | DRM_DEBUG_KMS("%s\n", __FILE__); |
247 | 233 | ||
248 | if (hdmi_overlay_ops && hdmi_overlay_ops->win_commit) | 234 | if (mixer_ops && mixer_ops->win_commit) |
249 | hdmi_overlay_ops->win_commit(ctx->mixer_ctx->ctx, zpos); | 235 | mixer_ops->win_commit(ctx->mixer_ctx->ctx, zpos); |
250 | } | 236 | } |
251 | 237 | ||
252 | static void drm_mixer_disable(struct device *subdrv_dev, int zpos) | 238 | static void drm_mixer_disable(struct device *subdrv_dev, int zpos) |
@@ -255,8 +241,8 @@ static void drm_mixer_disable(struct device *subdrv_dev, int zpos) | |||
255 | 241 | ||
256 | DRM_DEBUG_KMS("%s\n", __FILE__); | 242 | DRM_DEBUG_KMS("%s\n", __FILE__); |
257 | 243 | ||
258 | if (hdmi_overlay_ops && hdmi_overlay_ops->win_disable) | 244 | if (mixer_ops && mixer_ops->win_disable) |
259 | hdmi_overlay_ops->win_disable(ctx->mixer_ctx->ctx, zpos); | 245 | mixer_ops->win_disable(ctx->mixer_ctx->ctx, zpos); |
260 | } | 246 | } |
261 | 247 | ||
262 | static struct exynos_drm_overlay_ops drm_hdmi_overlay_ops = { | 248 | static struct exynos_drm_overlay_ops drm_hdmi_overlay_ops = { |
@@ -265,6 +251,12 @@ static struct exynos_drm_overlay_ops drm_hdmi_overlay_ops = { | |||
265 | .disable = drm_mixer_disable, | 251 | .disable = drm_mixer_disable, |
266 | }; | 252 | }; |
267 | 253 | ||
254 | static struct exynos_drm_manager hdmi_manager = { | ||
255 | .pipe = -1, | ||
256 | .ops = &drm_hdmi_manager_ops, | ||
257 | .overlay_ops = &drm_hdmi_overlay_ops, | ||
258 | .display_ops = &drm_hdmi_display_ops, | ||
259 | }; | ||
268 | 260 | ||
269 | static int hdmi_subdrv_probe(struct drm_device *drm_dev, | 261 | static int hdmi_subdrv_probe(struct drm_device *drm_dev, |
270 | struct device *dev) | 262 | struct device *dev) |
@@ -332,12 +324,9 @@ static int __devinit exynos_drm_hdmi_probe(struct platform_device *pdev) | |||
332 | 324 | ||
333 | subdrv = &ctx->subdrv; | 325 | subdrv = &ctx->subdrv; |
334 | 326 | ||
327 | subdrv->dev = dev; | ||
328 | subdrv->manager = &hdmi_manager; | ||
335 | subdrv->probe = hdmi_subdrv_probe; | 329 | subdrv->probe = hdmi_subdrv_probe; |
336 | subdrv->manager.pipe = -1; | ||
337 | subdrv->manager.ops = &drm_hdmi_manager_ops; | ||
338 | subdrv->manager.overlay_ops = &drm_hdmi_overlay_ops; | ||
339 | subdrv->manager.display_ops = &drm_hdmi_display_ops; | ||
340 | subdrv->manager.dev = dev; | ||
341 | 330 | ||
342 | platform_set_drvdata(pdev, subdrv); | 331 | platform_set_drvdata(pdev, subdrv); |
343 | 332 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h index 44497cfb6c74..f3ae192c8dcf 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h +++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h | |||
@@ -38,15 +38,15 @@ struct exynos_drm_hdmi_context { | |||
38 | void *ctx; | 38 | void *ctx; |
39 | }; | 39 | }; |
40 | 40 | ||
41 | struct exynos_hdmi_display_ops { | 41 | struct exynos_hdmi_ops { |
42 | /* display */ | ||
42 | bool (*is_connected)(void *ctx); | 43 | bool (*is_connected)(void *ctx); |
43 | int (*get_edid)(void *ctx, struct drm_connector *connector, | 44 | int (*get_edid)(void *ctx, struct drm_connector *connector, |
44 | u8 *edid, int len); | 45 | u8 *edid, int len); |
45 | int (*check_timing)(void *ctx, void *timing); | 46 | int (*check_timing)(void *ctx, void *timing); |
46 | int (*power_on)(void *ctx, int mode); | 47 | int (*power_on)(void *ctx, int mode); |
47 | }; | ||
48 | 48 | ||
49 | struct exynos_hdmi_manager_ops { | 49 | /* manager */ |
50 | void (*mode_fixup)(void *ctx, struct drm_connector *connector, | 50 | void (*mode_fixup)(void *ctx, struct drm_connector *connector, |
51 | struct drm_display_mode *mode, | 51 | struct drm_display_mode *mode, |
52 | struct drm_display_mode *adjusted_mode); | 52 | struct drm_display_mode *adjusted_mode); |
@@ -57,22 +57,17 @@ struct exynos_hdmi_manager_ops { | |||
57 | void (*disable)(void *ctx); | 57 | void (*disable)(void *ctx); |
58 | }; | 58 | }; |
59 | 59 | ||
60 | struct exynos_hdmi_overlay_ops { | 60 | struct exynos_mixer_ops { |
61 | /* manager */ | ||
61 | int (*enable_vblank)(void *ctx, int pipe); | 62 | int (*enable_vblank)(void *ctx, int pipe); |
62 | void (*disable_vblank)(void *ctx); | 63 | void (*disable_vblank)(void *ctx); |
64 | |||
65 | /* overlay */ | ||
63 | void (*win_mode_set)(void *ctx, struct exynos_drm_overlay *overlay); | 66 | void (*win_mode_set)(void *ctx, struct exynos_drm_overlay *overlay); |
64 | void (*win_commit)(void *ctx, int zpos); | 67 | void (*win_commit)(void *ctx, int zpos); |
65 | void (*win_disable)(void *ctx, int zpos); | 68 | void (*win_disable)(void *ctx, int zpos); |
66 | }; | 69 | }; |
67 | 70 | ||
68 | extern struct platform_driver hdmi_driver; | 71 | void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops); |
69 | extern struct platform_driver mixer_driver; | 72 | void exynos_mixer_ops_register(struct exynos_mixer_ops *ops); |
70 | |||
71 | void exynos_drm_display_ops_register(struct exynos_hdmi_display_ops | ||
72 | *display_ops); | ||
73 | void exynos_drm_manager_ops_register(struct exynos_hdmi_manager_ops | ||
74 | *manager_ops); | ||
75 | void exynos_drm_overlay_ops_register(struct exynos_hdmi_overlay_ops | ||
76 | *overlay_ops); | ||
77 | |||
78 | #endif | 73 | #endif |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index c277a3a445f5..f92fe4c6174a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c | |||
@@ -24,6 +24,10 @@ struct exynos_plane { | |||
24 | 24 | ||
25 | static const uint32_t formats[] = { | 25 | static const uint32_t formats[] = { |
26 | DRM_FORMAT_XRGB8888, | 26 | DRM_FORMAT_XRGB8888, |
27 | DRM_FORMAT_ARGB8888, | ||
28 | DRM_FORMAT_NV12, | ||
29 | DRM_FORMAT_NV12M, | ||
30 | DRM_FORMAT_NV12MT, | ||
27 | }; | 31 | }; |
28 | 32 | ||
29 | static int | 33 | static int |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index 8e1339f9fe1f..7b9c153dceb6 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c | |||
@@ -199,7 +199,7 @@ static void vidi_dpms(struct device *subdrv_dev, int mode) | |||
199 | static void vidi_apply(struct device *subdrv_dev) | 199 | static void vidi_apply(struct device *subdrv_dev) |
200 | { | 200 | { |
201 | struct vidi_context *ctx = get_vidi_context(subdrv_dev); | 201 | struct vidi_context *ctx = get_vidi_context(subdrv_dev); |
202 | struct exynos_drm_manager *mgr = &ctx->subdrv.manager; | 202 | struct exynos_drm_manager *mgr = ctx->subdrv.manager; |
203 | struct exynos_drm_manager_ops *mgr_ops = mgr->ops; | 203 | struct exynos_drm_manager_ops *mgr_ops = mgr->ops; |
204 | struct exynos_drm_overlay_ops *ovl_ops = mgr->overlay_ops; | 204 | struct exynos_drm_overlay_ops *ovl_ops = mgr->overlay_ops; |
205 | struct vidi_win_data *win_data; | 205 | struct vidi_win_data *win_data; |
@@ -374,6 +374,13 @@ static struct exynos_drm_overlay_ops vidi_overlay_ops = { | |||
374 | .disable = vidi_win_disable, | 374 | .disable = vidi_win_disable, |
375 | }; | 375 | }; |
376 | 376 | ||
377 | static struct exynos_drm_manager vidi_manager = { | ||
378 | .pipe = -1, | ||
379 | .ops = &vidi_manager_ops, | ||
380 | .overlay_ops = &vidi_overlay_ops, | ||
381 | .display_ops = &vidi_display_ops, | ||
382 | }; | ||
383 | |||
377 | static void vidi_finish_pageflip(struct drm_device *drm_dev, int crtc) | 384 | static void vidi_finish_pageflip(struct drm_device *drm_dev, int crtc) |
378 | { | 385 | { |
379 | struct exynos_drm_private *dev_priv = drm_dev->dev_private; | 386 | struct exynos_drm_private *dev_priv = drm_dev->dev_private; |
@@ -425,7 +432,7 @@ static void vidi_fake_vblank_handler(struct work_struct *work) | |||
425 | struct vidi_context *ctx = container_of(work, struct vidi_context, | 432 | struct vidi_context *ctx = container_of(work, struct vidi_context, |
426 | work); | 433 | work); |
427 | struct exynos_drm_subdrv *subdrv = &ctx->subdrv; | 434 | struct exynos_drm_subdrv *subdrv = &ctx->subdrv; |
428 | struct exynos_drm_manager *manager = &subdrv->manager; | 435 | struct exynos_drm_manager *manager = subdrv->manager; |
429 | 436 | ||
430 | if (manager->pipe < 0) | 437 | if (manager->pipe < 0) |
431 | return; | 438 | return; |
@@ -471,7 +478,7 @@ static void vidi_subdrv_remove(struct drm_device *drm_dev) | |||
471 | static int vidi_power_on(struct vidi_context *ctx, bool enable) | 478 | static int vidi_power_on(struct vidi_context *ctx, bool enable) |
472 | { | 479 | { |
473 | struct exynos_drm_subdrv *subdrv = &ctx->subdrv; | 480 | struct exynos_drm_subdrv *subdrv = &ctx->subdrv; |
474 | struct device *dev = subdrv->manager.dev; | 481 | struct device *dev = subdrv->dev; |
475 | 482 | ||
476 | DRM_DEBUG_KMS("%s\n", __FILE__); | 483 | DRM_DEBUG_KMS("%s\n", __FILE__); |
477 | 484 | ||
@@ -611,13 +618,10 @@ static int __devinit vidi_probe(struct platform_device *pdev) | |||
611 | ctx->raw_edid = (struct edid *)fake_edid_info; | 618 | ctx->raw_edid = (struct edid *)fake_edid_info; |
612 | 619 | ||
613 | subdrv = &ctx->subdrv; | 620 | subdrv = &ctx->subdrv; |
621 | subdrv->dev = dev; | ||
622 | subdrv->manager = &vidi_manager; | ||
614 | subdrv->probe = vidi_subdrv_probe; | 623 | subdrv->probe = vidi_subdrv_probe; |
615 | subdrv->remove = vidi_subdrv_remove; | 624 | subdrv->remove = vidi_subdrv_remove; |
616 | subdrv->manager.pipe = -1; | ||
617 | subdrv->manager.ops = &vidi_manager_ops; | ||
618 | subdrv->manager.overlay_ops = &vidi_overlay_ops; | ||
619 | subdrv->manager.display_ops = &vidi_display_ops; | ||
620 | subdrv->manager.dev = dev; | ||
621 | 625 | ||
622 | mutex_init(&ctx->lock); | 626 | mutex_init(&ctx->lock); |
623 | 627 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 575a8cbd3533..b00353876458 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c | |||
@@ -40,7 +40,6 @@ | |||
40 | 40 | ||
41 | #include "exynos_hdmi.h" | 41 | #include "exynos_hdmi.h" |
42 | 42 | ||
43 | #define HDMI_OVERLAY_NUMBER 3 | ||
44 | #define MAX_WIDTH 1920 | 43 | #define MAX_WIDTH 1920 |
45 | #define MAX_HEIGHT 1080 | 44 | #define MAX_HEIGHT 1080 |
46 | #define get_hdmi_context(dev) platform_get_drvdata(to_platform_device(dev)) | 45 | #define get_hdmi_context(dev) platform_get_drvdata(to_platform_device(dev)) |
@@ -1194,7 +1193,7 @@ static int hdmi_conf_index(struct hdmi_context *hdata, | |||
1194 | 1193 | ||
1195 | static bool hdmi_is_connected(void *ctx) | 1194 | static bool hdmi_is_connected(void *ctx) |
1196 | { | 1195 | { |
1197 | struct hdmi_context *hdata = (struct hdmi_context *)ctx; | 1196 | struct hdmi_context *hdata = ctx; |
1198 | u32 val = hdmi_reg_read(hdata, HDMI_HPD_STATUS); | 1197 | u32 val = hdmi_reg_read(hdata, HDMI_HPD_STATUS); |
1199 | 1198 | ||
1200 | if (val) | 1199 | if (val) |
@@ -1207,7 +1206,7 @@ static int hdmi_get_edid(void *ctx, struct drm_connector *connector, | |||
1207 | u8 *edid, int len) | 1206 | u8 *edid, int len) |
1208 | { | 1207 | { |
1209 | struct edid *raw_edid; | 1208 | struct edid *raw_edid; |
1210 | struct hdmi_context *hdata = (struct hdmi_context *)ctx; | 1209 | struct hdmi_context *hdata = ctx; |
1211 | 1210 | ||
1212 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); | 1211 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); |
1213 | 1212 | ||
@@ -1275,7 +1274,7 @@ static int hdmi_v14_check_timing(struct fb_videomode *check_timing) | |||
1275 | 1274 | ||
1276 | static int hdmi_check_timing(void *ctx, void *timing) | 1275 | static int hdmi_check_timing(void *ctx, void *timing) |
1277 | { | 1276 | { |
1278 | struct hdmi_context *hdata = (struct hdmi_context *)ctx; | 1277 | struct hdmi_context *hdata = ctx; |
1279 | struct fb_videomode *check_timing = timing; | 1278 | struct fb_videomode *check_timing = timing; |
1280 | 1279 | ||
1281 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); | 1280 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); |
@@ -1312,13 +1311,6 @@ static int hdmi_display_power_on(void *ctx, int mode) | |||
1312 | return 0; | 1311 | return 0; |
1313 | } | 1312 | } |
1314 | 1313 | ||
1315 | static struct exynos_hdmi_display_ops display_ops = { | ||
1316 | .is_connected = hdmi_is_connected, | ||
1317 | .get_edid = hdmi_get_edid, | ||
1318 | .check_timing = hdmi_check_timing, | ||
1319 | .power_on = hdmi_display_power_on, | ||
1320 | }; | ||
1321 | |||
1322 | static void hdmi_set_acr(u32 freq, u8 *acr) | 1314 | static void hdmi_set_acr(u32 freq, u8 *acr) |
1323 | { | 1315 | { |
1324 | u32 n, cts; | 1316 | u32 n, cts; |
@@ -1914,7 +1906,7 @@ static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector, | |||
1914 | struct drm_display_mode *adjusted_mode) | 1906 | struct drm_display_mode *adjusted_mode) |
1915 | { | 1907 | { |
1916 | struct drm_display_mode *m; | 1908 | struct drm_display_mode *m; |
1917 | struct hdmi_context *hdata = (struct hdmi_context *)ctx; | 1909 | struct hdmi_context *hdata = ctx; |
1918 | int index; | 1910 | int index; |
1919 | 1911 | ||
1920 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); | 1912 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); |
@@ -1951,7 +1943,7 @@ static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector, | |||
1951 | 1943 | ||
1952 | static void hdmi_mode_set(void *ctx, void *mode) | 1944 | static void hdmi_mode_set(void *ctx, void *mode) |
1953 | { | 1945 | { |
1954 | struct hdmi_context *hdata = (struct hdmi_context *)ctx; | 1946 | struct hdmi_context *hdata = ctx; |
1955 | int conf_idx; | 1947 | int conf_idx; |
1956 | 1948 | ||
1957 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); | 1949 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); |
@@ -1974,7 +1966,7 @@ static void hdmi_get_max_resol(void *ctx, unsigned int *width, | |||
1974 | 1966 | ||
1975 | static void hdmi_commit(void *ctx) | 1967 | static void hdmi_commit(void *ctx) |
1976 | { | 1968 | { |
1977 | struct hdmi_context *hdata = (struct hdmi_context *)ctx; | 1969 | struct hdmi_context *hdata = ctx; |
1978 | 1970 | ||
1979 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); | 1971 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); |
1980 | 1972 | ||
@@ -1985,7 +1977,7 @@ static void hdmi_commit(void *ctx) | |||
1985 | 1977 | ||
1986 | static void hdmi_disable(void *ctx) | 1978 | static void hdmi_disable(void *ctx) |
1987 | { | 1979 | { |
1988 | struct hdmi_context *hdata = (struct hdmi_context *)ctx; | 1980 | struct hdmi_context *hdata = ctx; |
1989 | 1981 | ||
1990 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); | 1982 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); |
1991 | 1983 | ||
@@ -1996,7 +1988,14 @@ static void hdmi_disable(void *ctx) | |||
1996 | } | 1988 | } |
1997 | } | 1989 | } |
1998 | 1990 | ||
1999 | static struct exynos_hdmi_manager_ops manager_ops = { | 1991 | static struct exynos_hdmi_ops hdmi_ops = { |
1992 | /* display */ | ||
1993 | .is_connected = hdmi_is_connected, | ||
1994 | .get_edid = hdmi_get_edid, | ||
1995 | .check_timing = hdmi_check_timing, | ||
1996 | .power_on = hdmi_display_power_on, | ||
1997 | |||
1998 | /* manager */ | ||
2000 | .mode_fixup = hdmi_mode_fixup, | 1999 | .mode_fixup = hdmi_mode_fixup, |
2001 | .mode_set = hdmi_mode_set, | 2000 | .mode_set = hdmi_mode_set, |
2002 | .get_max_resol = hdmi_get_max_resol, | 2001 | .get_max_resol = hdmi_get_max_resol, |
@@ -2020,7 +2019,7 @@ static void hdmi_hotplug_func(struct work_struct *work) | |||
2020 | static irqreturn_t hdmi_irq_handler(int irq, void *arg) | 2019 | static irqreturn_t hdmi_irq_handler(int irq, void *arg) |
2021 | { | 2020 | { |
2022 | struct exynos_drm_hdmi_context *ctx = arg; | 2021 | struct exynos_drm_hdmi_context *ctx = arg; |
2023 | struct hdmi_context *hdata = (struct hdmi_context *)ctx->ctx; | 2022 | struct hdmi_context *hdata = ctx->ctx; |
2024 | u32 intc_flag; | 2023 | u32 intc_flag; |
2025 | 2024 | ||
2026 | intc_flag = hdmi_reg_read(hdata, HDMI_INTC_FLAG); | 2025 | intc_flag = hdmi_reg_read(hdata, HDMI_INTC_FLAG); |
@@ -2173,7 +2172,7 @@ static int hdmi_runtime_suspend(struct device *dev) | |||
2173 | 2172 | ||
2174 | DRM_DEBUG_KMS("%s\n", __func__); | 2173 | DRM_DEBUG_KMS("%s\n", __func__); |
2175 | 2174 | ||
2176 | hdmi_resource_poweroff((struct hdmi_context *)ctx->ctx); | 2175 | hdmi_resource_poweroff(ctx->ctx); |
2177 | 2176 | ||
2178 | return 0; | 2177 | return 0; |
2179 | } | 2178 | } |
@@ -2184,7 +2183,7 @@ static int hdmi_runtime_resume(struct device *dev) | |||
2184 | 2183 | ||
2185 | DRM_DEBUG_KMS("%s\n", __func__); | 2184 | DRM_DEBUG_KMS("%s\n", __func__); |
2186 | 2185 | ||
2187 | hdmi_resource_poweron((struct hdmi_context *)ctx->ctx); | 2186 | hdmi_resource_poweron(ctx->ctx); |
2188 | 2187 | ||
2189 | return 0; | 2188 | return 0; |
2190 | } | 2189 | } |
@@ -2322,8 +2321,7 @@ static int __devinit hdmi_probe(struct platform_device *pdev) | |||
2322 | hdata->irq = res->start; | 2321 | hdata->irq = res->start; |
2323 | 2322 | ||
2324 | /* register specific callbacks to common hdmi. */ | 2323 | /* register specific callbacks to common hdmi. */ |
2325 | exynos_drm_display_ops_register(&display_ops); | 2324 | exynos_hdmi_ops_register(&hdmi_ops); |
2326 | exynos_drm_manager_ops_register(&manager_ops); | ||
2327 | 2325 | ||
2328 | hdmi_resource_poweron(hdata); | 2326 | hdmi_resource_poweron(hdata); |
2329 | 2327 | ||
@@ -2351,7 +2349,7 @@ err_data: | |||
2351 | static int __devexit hdmi_remove(struct platform_device *pdev) | 2349 | static int __devexit hdmi_remove(struct platform_device *pdev) |
2352 | { | 2350 | { |
2353 | struct exynos_drm_hdmi_context *ctx = platform_get_drvdata(pdev); | 2351 | struct exynos_drm_hdmi_context *ctx = platform_get_drvdata(pdev); |
2354 | struct hdmi_context *hdata = (struct hdmi_context *)ctx->ctx; | 2352 | struct hdmi_context *hdata = ctx->ctx; |
2355 | 2353 | ||
2356 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); | 2354 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); |
2357 | 2355 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index 4d5f41e19527..e15438c01129 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c | |||
@@ -37,7 +37,8 @@ | |||
37 | #include "exynos_drm_drv.h" | 37 | #include "exynos_drm_drv.h" |
38 | #include "exynos_drm_hdmi.h" | 38 | #include "exynos_drm_hdmi.h" |
39 | 39 | ||
40 | #define HDMI_OVERLAY_NUMBER 3 | 40 | #define MIXER_WIN_NR 3 |
41 | #define MIXER_DEFAULT_WIN 0 | ||
41 | 42 | ||
42 | #define get_mixer_context(dev) platform_get_drvdata(to_platform_device(dev)) | 43 | #define get_mixer_context(dev) platform_get_drvdata(to_platform_device(dev)) |
43 | 44 | ||
@@ -75,16 +76,12 @@ struct mixer_resources { | |||
75 | }; | 76 | }; |
76 | 77 | ||
77 | struct mixer_context { | 78 | struct mixer_context { |
78 | struct fb_videomode *default_timing; | ||
79 | unsigned int default_win; | ||
80 | unsigned int default_bpp; | ||
81 | unsigned int irq; | 79 | unsigned int irq; |
82 | int pipe; | 80 | int pipe; |
83 | bool interlace; | 81 | bool interlace; |
84 | bool vp_enabled; | ||
85 | 82 | ||
86 | struct mixer_resources mixer_res; | 83 | struct mixer_resources mixer_res; |
87 | struct hdmi_win_data win_data[HDMI_OVERLAY_NUMBER]; | 84 | struct hdmi_win_data win_data[MIXER_WIN_NR]; |
88 | }; | 85 | }; |
89 | 86 | ||
90 | static const u8 filter_y_horiz_tap8[] = { | 87 | static const u8 filter_y_horiz_tap8[] = { |
@@ -643,9 +640,9 @@ static void mixer_win_mode_set(void *ctx, | |||
643 | 640 | ||
644 | win = overlay->zpos; | 641 | win = overlay->zpos; |
645 | if (win == DEFAULT_ZPOS) | 642 | if (win == DEFAULT_ZPOS) |
646 | win = mixer_ctx->default_win; | 643 | win = MIXER_DEFAULT_WIN; |
647 | 644 | ||
648 | if (win < 0 || win > HDMI_OVERLAY_NUMBER) { | 645 | if (win < 0 || win > MIXER_WIN_NR) { |
649 | DRM_ERROR("overlay plane[%d] is wrong\n", win); | 646 | DRM_ERROR("overlay plane[%d] is wrong\n", win); |
650 | return; | 647 | return; |
651 | } | 648 | } |
@@ -683,9 +680,9 @@ static void mixer_win_commit(void *ctx, int zpos) | |||
683 | DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win); | 680 | DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win); |
684 | 681 | ||
685 | if (win == DEFAULT_ZPOS) | 682 | if (win == DEFAULT_ZPOS) |
686 | win = mixer_ctx->default_win; | 683 | win = MIXER_DEFAULT_WIN; |
687 | 684 | ||
688 | if (win < 0 || win > HDMI_OVERLAY_NUMBER) { | 685 | if (win < 0 || win > MIXER_WIN_NR) { |
689 | DRM_ERROR("overlay plane[%d] is wrong\n", win); | 686 | DRM_ERROR("overlay plane[%d] is wrong\n", win); |
690 | return; | 687 | return; |
691 | } | 688 | } |
@@ -706,9 +703,9 @@ static void mixer_win_disable(void *ctx, int zpos) | |||
706 | DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win); | 703 | DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win); |
707 | 704 | ||
708 | if (win == DEFAULT_ZPOS) | 705 | if (win == DEFAULT_ZPOS) |
709 | win = mixer_ctx->default_win; | 706 | win = MIXER_DEFAULT_WIN; |
710 | 707 | ||
711 | if (win < 0 || win > HDMI_OVERLAY_NUMBER) { | 708 | if (win < 0 || win > MIXER_WIN_NR) { |
712 | DRM_ERROR("overlay plane[%d] is wrong\n", win); | 709 | DRM_ERROR("overlay plane[%d] is wrong\n", win); |
713 | return; | 710 | return; |
714 | } | 711 | } |
@@ -722,9 +719,12 @@ static void mixer_win_disable(void *ctx, int zpos) | |||
722 | spin_unlock_irqrestore(&res->reg_slock, flags); | 719 | spin_unlock_irqrestore(&res->reg_slock, flags); |
723 | } | 720 | } |
724 | 721 | ||
725 | static struct exynos_hdmi_overlay_ops overlay_ops = { | 722 | static struct exynos_mixer_ops mixer_ops = { |
723 | /* manager */ | ||
726 | .enable_vblank = mixer_enable_vblank, | 724 | .enable_vblank = mixer_enable_vblank, |
727 | .disable_vblank = mixer_disable_vblank, | 725 | .disable_vblank = mixer_disable_vblank, |
726 | |||
727 | /* overlay */ | ||
728 | .win_mode_set = mixer_win_mode_set, | 728 | .win_mode_set = mixer_win_mode_set, |
729 | .win_commit = mixer_win_commit, | 729 | .win_commit = mixer_win_commit, |
730 | .win_disable = mixer_win_disable, | 730 | .win_disable = mixer_win_disable, |
@@ -771,8 +771,7 @@ static void mixer_finish_pageflip(struct drm_device *drm_dev, int crtc) | |||
771 | static irqreturn_t mixer_irq_handler(int irq, void *arg) | 771 | static irqreturn_t mixer_irq_handler(int irq, void *arg) |
772 | { | 772 | { |
773 | struct exynos_drm_hdmi_context *drm_hdmi_ctx = arg; | 773 | struct exynos_drm_hdmi_context *drm_hdmi_ctx = arg; |
774 | struct mixer_context *ctx = | 774 | struct mixer_context *ctx = drm_hdmi_ctx->ctx; |
775 | (struct mixer_context *)drm_hdmi_ctx->ctx; | ||
776 | struct mixer_resources *res = &ctx->mixer_res; | 775 | struct mixer_resources *res = &ctx->mixer_res; |
777 | u32 val, val_base; | 776 | u32 val, val_base; |
778 | 777 | ||
@@ -902,7 +901,7 @@ static int mixer_runtime_resume(struct device *dev) | |||
902 | 901 | ||
903 | DRM_DEBUG_KMS("resume - start\n"); | 902 | DRM_DEBUG_KMS("resume - start\n"); |
904 | 903 | ||
905 | mixer_resource_poweron((struct mixer_context *)ctx->ctx); | 904 | mixer_resource_poweron(ctx->ctx); |
906 | 905 | ||
907 | return 0; | 906 | return 0; |
908 | } | 907 | } |
@@ -913,7 +912,7 @@ static int mixer_runtime_suspend(struct device *dev) | |||
913 | 912 | ||
914 | DRM_DEBUG_KMS("suspend - start\n"); | 913 | DRM_DEBUG_KMS("suspend - start\n"); |
915 | 914 | ||
916 | mixer_resource_poweroff((struct mixer_context *)ctx->ctx); | 915 | mixer_resource_poweroff(ctx->ctx); |
917 | 916 | ||
918 | return 0; | 917 | return 0; |
919 | } | 918 | } |
@@ -926,8 +925,7 @@ static const struct dev_pm_ops mixer_pm_ops = { | |||
926 | static int __devinit mixer_resources_init(struct exynos_drm_hdmi_context *ctx, | 925 | static int __devinit mixer_resources_init(struct exynos_drm_hdmi_context *ctx, |
927 | struct platform_device *pdev) | 926 | struct platform_device *pdev) |
928 | { | 927 | { |
929 | struct mixer_context *mixer_ctx = | 928 | struct mixer_context *mixer_ctx = ctx->ctx; |
930 | (struct mixer_context *)ctx->ctx; | ||
931 | struct device *dev = &pdev->dev; | 929 | struct device *dev = &pdev->dev; |
932 | struct mixer_resources *mixer_res = &mixer_ctx->mixer_res; | 930 | struct mixer_resources *mixer_res = &mixer_ctx->mixer_res; |
933 | struct resource *res; | 931 | struct resource *res; |
@@ -1076,7 +1074,7 @@ static int __devinit mixer_probe(struct platform_device *pdev) | |||
1076 | goto fail; | 1074 | goto fail; |
1077 | 1075 | ||
1078 | /* register specific callback point to common hdmi. */ | 1076 | /* register specific callback point to common hdmi. */ |
1079 | exynos_drm_overlay_ops_register(&overlay_ops); | 1077 | exynos_mixer_ops_register(&mixer_ops); |
1080 | 1078 | ||
1081 | mixer_resource_poweron(ctx); | 1079 | mixer_resource_poweron(ctx); |
1082 | 1080 | ||
@@ -1093,7 +1091,7 @@ static int mixer_remove(struct platform_device *pdev) | |||
1093 | struct device *dev = &pdev->dev; | 1091 | struct device *dev = &pdev->dev; |
1094 | struct exynos_drm_hdmi_context *drm_hdmi_ctx = | 1092 | struct exynos_drm_hdmi_context *drm_hdmi_ctx = |
1095 | platform_get_drvdata(pdev); | 1093 | platform_get_drvdata(pdev); |
1096 | struct mixer_context *ctx = (struct mixer_context *)drm_hdmi_ctx->ctx; | 1094 | struct mixer_context *ctx = drm_hdmi_ctx->ctx; |
1097 | 1095 | ||
1098 | dev_info(dev, "remove successful\n"); | 1096 | dev_info(dev, "remove successful\n"); |
1099 | 1097 | ||
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index ce7fc77678b4..b65c06f1a021 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile | |||
@@ -12,6 +12,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o \ | |||
12 | i915_gem_execbuffer.o \ | 12 | i915_gem_execbuffer.o \ |
13 | i915_gem_gtt.o \ | 13 | i915_gem_gtt.o \ |
14 | i915_gem_tiling.o \ | 14 | i915_gem_tiling.o \ |
15 | i915_sysfs.o \ | ||
15 | i915_trace_points.o \ | 16 | i915_trace_points.o \ |
16 | intel_display.o \ | 17 | intel_display.o \ |
17 | intel_crt.o \ | 18 | intel_crt.o \ |
@@ -22,6 +23,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o \ | |||
22 | intel_sdvo.o \ | 23 | intel_sdvo.o \ |
23 | intel_modes.o \ | 24 | intel_modes.o \ |
24 | intel_panel.o \ | 25 | intel_panel.o \ |
26 | intel_pm.o \ | ||
25 | intel_i2c.o \ | 27 | intel_i2c.o \ |
26 | intel_fb.o \ | 28 | intel_fb.o \ |
27 | intel_tv.o \ | 29 | intel_tv.o \ |
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 967fb928c577..35462df7cefd 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -1171,6 +1171,17 @@ static int gen6_drpc_info(struct seq_file *m) | |||
1171 | 1171 | ||
1172 | seq_printf(m, "Core Power Down: %s\n", | 1172 | seq_printf(m, "Core Power Down: %s\n", |
1173 | yesno(gt_core_status & GEN6_CORE_CPD_STATE_MASK)); | 1173 | yesno(gt_core_status & GEN6_CORE_CPD_STATE_MASK)); |
1174 | |||
1175 | /* Not exactly sure what this is */ | ||
1176 | seq_printf(m, "RC6 \"Locked to RPn\" residency since boot: %u\n", | ||
1177 | I915_READ(GEN6_GT_GFX_RC6_LOCKED)); | ||
1178 | seq_printf(m, "RC6 residency since boot: %u\n", | ||
1179 | I915_READ(GEN6_GT_GFX_RC6)); | ||
1180 | seq_printf(m, "RC6+ residency since boot: %u\n", | ||
1181 | I915_READ(GEN6_GT_GFX_RC6p)); | ||
1182 | seq_printf(m, "RC6++ residency since boot: %u\n", | ||
1183 | I915_READ(GEN6_GT_GFX_RC6pp)); | ||
1184 | |||
1174 | return 0; | 1185 | return 0; |
1175 | } | 1186 | } |
1176 | 1187 | ||
@@ -1821,7 +1832,7 @@ static int i915_forcewake_open(struct inode *inode, struct file *file) | |||
1821 | return 0; | 1832 | return 0; |
1822 | } | 1833 | } |
1823 | 1834 | ||
1824 | int i915_forcewake_release(struct inode *inode, struct file *file) | 1835 | static int i915_forcewake_release(struct inode *inode, struct file *file) |
1825 | { | 1836 | { |
1826 | struct drm_device *dev = inode->i_private; | 1837 | struct drm_device *dev = inode->i_private; |
1827 | struct drm_i915_private *dev_priv = dev->dev_private; | 1838 | struct drm_i915_private *dev_priv = dev->dev_private; |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 652f43f00ef2..a813f652fa1f 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -2115,7 +2115,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2115 | spin_lock_init(&dev_priv->error_lock); | 2115 | spin_lock_init(&dev_priv->error_lock); |
2116 | spin_lock_init(&dev_priv->rps_lock); | 2116 | spin_lock_init(&dev_priv->rps_lock); |
2117 | 2117 | ||
2118 | if (IS_IVYBRIDGE(dev)) | 2118 | if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) |
2119 | dev_priv->num_pipe = 3; | 2119 | dev_priv->num_pipe = 3; |
2120 | else if (IS_MOBILE(dev) || !IS_GEN2(dev)) | 2120 | else if (IS_MOBILE(dev) || !IS_GEN2(dev)) |
2121 | dev_priv->num_pipe = 2; | 2121 | dev_priv->num_pipe = 2; |
@@ -2139,6 +2139,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2139 | } | 2139 | } |
2140 | } | 2140 | } |
2141 | 2141 | ||
2142 | i915_setup_sysfs(dev); | ||
2143 | |||
2142 | /* Must be done after probing outputs */ | 2144 | /* Must be done after probing outputs */ |
2143 | intel_opregion_init(dev); | 2145 | intel_opregion_init(dev); |
2144 | acpi_video_register(); | 2146 | acpi_video_register(); |
@@ -2190,6 +2192,8 @@ int i915_driver_unload(struct drm_device *dev) | |||
2190 | i915_mch_dev = NULL; | 2192 | i915_mch_dev = NULL; |
2191 | spin_unlock(&mchdev_lock); | 2193 | spin_unlock(&mchdev_lock); |
2192 | 2194 | ||
2195 | i915_teardown_sysfs(dev); | ||
2196 | |||
2193 | if (dev_priv->mm.inactive_shrinker.shrink) | 2197 | if (dev_priv->mm.inactive_shrinker.shrink) |
2194 | unregister_shrinker(&dev_priv->mm.inactive_shrinker); | 2198 | unregister_shrinker(&dev_priv->mm.inactive_shrinker); |
2195 | 2199 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index c33b0a41a73d..3effcf71e1b1 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -64,7 +64,7 @@ MODULE_PARM_DESC(semaphores, | |||
64 | "Use semaphores for inter-ring sync (default: -1 (use per-chip defaults))"); | 64 | "Use semaphores for inter-ring sync (default: -1 (use per-chip defaults))"); |
65 | 65 | ||
66 | int i915_enable_rc6 __read_mostly = -1; | 66 | int i915_enable_rc6 __read_mostly = -1; |
67 | module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600); | 67 | module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0400); |
68 | MODULE_PARM_DESC(i915_enable_rc6, | 68 | MODULE_PARM_DESC(i915_enable_rc6, |
69 | "Enable power-saving render C-state 6. " | 69 | "Enable power-saving render C-state 6. " |
70 | "Different stages can be selected via bitmask values " | 70 | "Different stages can be selected via bitmask values " |
@@ -394,6 +394,21 @@ void intel_detect_pch(struct drm_device *dev) | |||
394 | } | 394 | } |
395 | } | 395 | } |
396 | 396 | ||
397 | bool i915_semaphore_is_enabled(struct drm_device *dev) | ||
398 | { | ||
399 | if (INTEL_INFO(dev)->gen < 6) | ||
400 | return 0; | ||
401 | |||
402 | if (i915_semaphores >= 0) | ||
403 | return i915_semaphores; | ||
404 | |||
405 | /* Enable semaphores on SNB when IO remapping is off */ | ||
406 | if (INTEL_INFO(dev)->gen == 6) | ||
407 | return !intel_iommu_enabled; | ||
408 | |||
409 | return 1; | ||
410 | } | ||
411 | |||
397 | void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) | 412 | void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) |
398 | { | 413 | { |
399 | int count; | 414 | int count; |
@@ -836,9 +851,14 @@ int i915_reset(struct drm_device *dev, u8 flags) | |||
836 | i915_gem_init_ppgtt(dev); | 851 | i915_gem_init_ppgtt(dev); |
837 | 852 | ||
838 | mutex_unlock(&dev->struct_mutex); | 853 | mutex_unlock(&dev->struct_mutex); |
854 | |||
855 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | ||
856 | intel_modeset_init_hw(dev); | ||
857 | |||
839 | drm_irq_uninstall(dev); | 858 | drm_irq_uninstall(dev); |
840 | drm_mode_config_reset(dev); | 859 | drm_mode_config_reset(dev); |
841 | drm_irq_install(dev); | 860 | drm_irq_install(dev); |
861 | |||
842 | mutex_lock(&dev->struct_mutex); | 862 | mutex_lock(&dev->struct_mutex); |
843 | } | 863 | } |
844 | 864 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 92e496afc6f4..69e153956182 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/i2c-algo-bit.h> | 38 | #include <linux/i2c-algo-bit.h> |
39 | #include <drm/intel-gtt.h> | 39 | #include <drm/intel-gtt.h> |
40 | #include <linux/backlight.h> | 40 | #include <linux/backlight.h> |
41 | #include <linux/intel-iommu.h> | ||
41 | 42 | ||
42 | /* General customization: | 43 | /* General customization: |
43 | */ | 44 | */ |
@@ -145,7 +146,6 @@ struct drm_i915_master_private { | |||
145 | struct drm_i915_fence_reg { | 146 | struct drm_i915_fence_reg { |
146 | struct list_head lru_list; | 147 | struct list_head lru_list; |
147 | struct drm_i915_gem_object *obj; | 148 | struct drm_i915_gem_object *obj; |
148 | uint32_t setup_seqno; | ||
149 | int pin_count; | 149 | int pin_count; |
150 | }; | 150 | }; |
151 | 151 | ||
@@ -930,13 +930,12 @@ struct drm_i915_gem_object { | |||
930 | */ | 930 | */ |
931 | uint32_t gtt_offset; | 931 | uint32_t gtt_offset; |
932 | 932 | ||
933 | /** Breadcrumb of last rendering to the buffer. */ | ||
934 | uint32_t last_rendering_seqno; | ||
935 | struct intel_ring_buffer *ring; | 933 | struct intel_ring_buffer *ring; |
936 | 934 | ||
935 | /** Breadcrumb of last rendering to the buffer. */ | ||
936 | uint32_t last_rendering_seqno; | ||
937 | /** Breadcrumb of last fenced GPU access to the buffer. */ | 937 | /** Breadcrumb of last fenced GPU access to the buffer. */ |
938 | uint32_t last_fenced_seqno; | 938 | uint32_t last_fenced_seqno; |
939 | struct intel_ring_buffer *last_fenced_ring; | ||
940 | 939 | ||
941 | /** Current tiling stride for the object, if it's tiled. */ | 940 | /** Current tiling stride for the object, if it's tiled. */ |
942 | uint32_t stride; | 941 | uint32_t stride; |
@@ -1127,8 +1126,10 @@ extern void i915_driver_preclose(struct drm_device *dev, | |||
1127 | extern void i915_driver_postclose(struct drm_device *dev, | 1126 | extern void i915_driver_postclose(struct drm_device *dev, |
1128 | struct drm_file *file_priv); | 1127 | struct drm_file *file_priv); |
1129 | extern int i915_driver_device_is_agp(struct drm_device * dev); | 1128 | extern int i915_driver_device_is_agp(struct drm_device * dev); |
1129 | #ifdef CONFIG_COMPAT | ||
1130 | extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, | 1130 | extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, |
1131 | unsigned long arg); | 1131 | unsigned long arg); |
1132 | #endif | ||
1132 | extern int i915_emit_box(struct drm_device *dev, | 1133 | extern int i915_emit_box(struct drm_device *dev, |
1133 | struct drm_clip_rect *box, | 1134 | struct drm_clip_rect *box, |
1134 | int DR1, int DR4); | 1135 | int DR1, int DR4); |
@@ -1230,6 +1231,8 @@ void i915_gem_lastclose(struct drm_device *dev); | |||
1230 | 1231 | ||
1231 | int __must_check i915_mutex_lock_interruptible(struct drm_device *dev); | 1232 | int __must_check i915_mutex_lock_interruptible(struct drm_device *dev); |
1232 | int __must_check i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj); | 1233 | int __must_check i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj); |
1234 | int i915_gem_object_sync(struct drm_i915_gem_object *obj, | ||
1235 | struct intel_ring_buffer *to); | ||
1233 | void i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, | 1236 | void i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, |
1234 | struct intel_ring_buffer *ring, | 1237 | struct intel_ring_buffer *ring, |
1235 | u32 seqno); | 1238 | u32 seqno); |
@@ -1252,17 +1255,18 @@ i915_seqno_passed(uint32_t seq1, uint32_t seq2) | |||
1252 | 1255 | ||
1253 | u32 i915_gem_next_request_seqno(struct intel_ring_buffer *ring); | 1256 | u32 i915_gem_next_request_seqno(struct intel_ring_buffer *ring); |
1254 | 1257 | ||
1255 | int __must_check i915_gem_object_get_fence(struct drm_i915_gem_object *obj, | 1258 | int __must_check i915_gem_object_get_fence(struct drm_i915_gem_object *obj); |
1256 | struct intel_ring_buffer *pipelined); | ||
1257 | int __must_check i915_gem_object_put_fence(struct drm_i915_gem_object *obj); | 1259 | int __must_check i915_gem_object_put_fence(struct drm_i915_gem_object *obj); |
1258 | 1260 | ||
1259 | static inline void | 1261 | static inline bool |
1260 | i915_gem_object_pin_fence(struct drm_i915_gem_object *obj) | 1262 | i915_gem_object_pin_fence(struct drm_i915_gem_object *obj) |
1261 | { | 1263 | { |
1262 | if (obj->fence_reg != I915_FENCE_REG_NONE) { | 1264 | if (obj->fence_reg != I915_FENCE_REG_NONE) { |
1263 | struct drm_i915_private *dev_priv = obj->base.dev->dev_private; | 1265 | struct drm_i915_private *dev_priv = obj->base.dev->dev_private; |
1264 | dev_priv->fence_regs[obj->fence_reg].pin_count++; | 1266 | dev_priv->fence_regs[obj->fence_reg].pin_count++; |
1265 | } | 1267 | return true; |
1268 | } else | ||
1269 | return false; | ||
1266 | } | 1270 | } |
1267 | 1271 | ||
1268 | static inline void | 1272 | static inline void |
@@ -1380,6 +1384,10 @@ extern int i915_restore_state(struct drm_device *dev); | |||
1380 | extern int i915_save_state(struct drm_device *dev); | 1384 | extern int i915_save_state(struct drm_device *dev); |
1381 | extern int i915_restore_state(struct drm_device *dev); | 1385 | extern int i915_restore_state(struct drm_device *dev); |
1382 | 1386 | ||
1387 | /* i915_sysfs.c */ | ||
1388 | void i915_setup_sysfs(struct drm_device *dev_priv); | ||
1389 | void i915_teardown_sysfs(struct drm_device *dev_priv); | ||
1390 | |||
1383 | /* intel_i2c.c */ | 1391 | /* intel_i2c.c */ |
1384 | extern int intel_setup_gmbus(struct drm_device *dev); | 1392 | extern int intel_setup_gmbus(struct drm_device *dev); |
1385 | extern void intel_teardown_gmbus(struct drm_device *dev); | 1393 | extern void intel_teardown_gmbus(struct drm_device *dev); |
@@ -1424,6 +1432,7 @@ static inline void intel_unregister_dsm_handler(void) { return; } | |||
1424 | #endif /* CONFIG_ACPI */ | 1432 | #endif /* CONFIG_ACPI */ |
1425 | 1433 | ||
1426 | /* modesetting */ | 1434 | /* modesetting */ |
1435 | extern void intel_modeset_init_hw(struct drm_device *dev); | ||
1427 | extern void intel_modeset_init(struct drm_device *dev); | 1436 | extern void intel_modeset_init(struct drm_device *dev); |
1428 | extern void intel_modeset_gem_init(struct drm_device *dev); | 1437 | extern void intel_modeset_gem_init(struct drm_device *dev); |
1429 | extern void intel_modeset_cleanup(struct drm_device *dev); | 1438 | extern void intel_modeset_cleanup(struct drm_device *dev); |
@@ -1436,7 +1445,9 @@ extern void ironlake_enable_rc6(struct drm_device *dev); | |||
1436 | extern void gen6_set_rps(struct drm_device *dev, u8 val); | 1445 | extern void gen6_set_rps(struct drm_device *dev, u8 val); |
1437 | extern void intel_detect_pch(struct drm_device *dev); | 1446 | extern void intel_detect_pch(struct drm_device *dev); |
1438 | extern int intel_trans_dp_port_sel(struct drm_crtc *crtc); | 1447 | extern int intel_trans_dp_port_sel(struct drm_crtc *crtc); |
1448 | extern int intel_enable_rc6(const struct drm_device *dev); | ||
1439 | 1449 | ||
1450 | extern bool i915_semaphore_is_enabled(struct drm_device *dev); | ||
1440 | extern void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv); | 1451 | extern void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv); |
1441 | extern void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv); | 1452 | extern void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv); |
1442 | extern void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv); | 1453 | extern void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv); |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index b851bd34ca18..7bc4a40132ad 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -42,18 +42,34 @@ static void i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *o | |||
42 | static __must_check int i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, | 42 | static __must_check int i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, |
43 | unsigned alignment, | 43 | unsigned alignment, |
44 | bool map_and_fenceable); | 44 | bool map_and_fenceable); |
45 | static void i915_gem_clear_fence_reg(struct drm_device *dev, | ||
46 | struct drm_i915_fence_reg *reg); | ||
47 | static int i915_gem_phys_pwrite(struct drm_device *dev, | 45 | static int i915_gem_phys_pwrite(struct drm_device *dev, |
48 | struct drm_i915_gem_object *obj, | 46 | struct drm_i915_gem_object *obj, |
49 | struct drm_i915_gem_pwrite *args, | 47 | struct drm_i915_gem_pwrite *args, |
50 | struct drm_file *file); | 48 | struct drm_file *file); |
51 | static void i915_gem_free_object_tail(struct drm_i915_gem_object *obj); | 49 | static void i915_gem_free_object_tail(struct drm_i915_gem_object *obj); |
52 | 50 | ||
51 | static void i915_gem_write_fence(struct drm_device *dev, int reg, | ||
52 | struct drm_i915_gem_object *obj); | ||
53 | static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj, | ||
54 | struct drm_i915_fence_reg *fence, | ||
55 | bool enable); | ||
56 | |||
53 | static int i915_gem_inactive_shrink(struct shrinker *shrinker, | 57 | static int i915_gem_inactive_shrink(struct shrinker *shrinker, |
54 | struct shrink_control *sc); | 58 | struct shrink_control *sc); |
55 | static void i915_gem_object_truncate(struct drm_i915_gem_object *obj); | 59 | static void i915_gem_object_truncate(struct drm_i915_gem_object *obj); |
56 | 60 | ||
61 | static inline void i915_gem_object_fence_lost(struct drm_i915_gem_object *obj) | ||
62 | { | ||
63 | if (obj->tiling_mode) | ||
64 | i915_gem_release_mmap(obj); | ||
65 | |||
66 | /* As we do not have an associated fence register, we will force | ||
67 | * a tiling change if we ever need to acquire one. | ||
68 | */ | ||
69 | obj->tiling_changed = false; | ||
70 | obj->fence_reg = I915_FENCE_REG_NONE; | ||
71 | } | ||
72 | |||
57 | /* some bookkeeping */ | 73 | /* some bookkeeping */ |
58 | static void i915_gem_info_add_obj(struct drm_i915_private *dev_priv, | 74 | static void i915_gem_info_add_obj(struct drm_i915_private *dev_priv, |
59 | size_t size) | 75 | size_t size) |
@@ -876,6 +892,7 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, | |||
876 | 892 | ||
877 | if (obj->gtt_space && | 893 | if (obj->gtt_space && |
878 | obj->cache_level == I915_CACHE_NONE && | 894 | obj->cache_level == I915_CACHE_NONE && |
895 | obj->tiling_mode == I915_TILING_NONE && | ||
879 | obj->map_and_fenceable && | 896 | obj->map_and_fenceable && |
880 | obj->base.write_domain != I915_GEM_DOMAIN_CPU) { | 897 | obj->base.write_domain != I915_GEM_DOMAIN_CPU) { |
881 | ret = i915_gem_gtt_pwrite_fast(dev, obj, args, file); | 898 | ret = i915_gem_gtt_pwrite_fast(dev, obj, args, file); |
@@ -1078,10 +1095,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
1078 | if (!obj->has_global_gtt_mapping) | 1095 | if (!obj->has_global_gtt_mapping) |
1079 | i915_gem_gtt_bind_object(obj, obj->cache_level); | 1096 | i915_gem_gtt_bind_object(obj, obj->cache_level); |
1080 | 1097 | ||
1081 | if (obj->tiling_mode == I915_TILING_NONE) | 1098 | ret = i915_gem_object_get_fence(obj); |
1082 | ret = i915_gem_object_put_fence(obj); | ||
1083 | else | ||
1084 | ret = i915_gem_object_get_fence(obj, NULL); | ||
1085 | if (ret) | 1099 | if (ret) |
1086 | goto unlock; | 1100 | goto unlock; |
1087 | 1101 | ||
@@ -1400,7 +1414,6 @@ i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, | |||
1400 | 1414 | ||
1401 | if (obj->fenced_gpu_access) { | 1415 | if (obj->fenced_gpu_access) { |
1402 | obj->last_fenced_seqno = seqno; | 1416 | obj->last_fenced_seqno = seqno; |
1403 | obj->last_fenced_ring = ring; | ||
1404 | 1417 | ||
1405 | /* Bump MRU to take account of the delayed flush */ | 1418 | /* Bump MRU to take account of the delayed flush */ |
1406 | if (obj->fence_reg != I915_FENCE_REG_NONE) { | 1419 | if (obj->fence_reg != I915_FENCE_REG_NONE) { |
@@ -1418,6 +1431,7 @@ i915_gem_object_move_off_active(struct drm_i915_gem_object *obj) | |||
1418 | { | 1431 | { |
1419 | list_del_init(&obj->ring_list); | 1432 | list_del_init(&obj->ring_list); |
1420 | obj->last_rendering_seqno = 0; | 1433 | obj->last_rendering_seqno = 0; |
1434 | obj->last_fenced_seqno = 0; | ||
1421 | } | 1435 | } |
1422 | 1436 | ||
1423 | static void | 1437 | static void |
@@ -1639,20 +1653,18 @@ static void i915_gem_reset_fences(struct drm_device *dev) | |||
1639 | 1653 | ||
1640 | for (i = 0; i < dev_priv->num_fence_regs; i++) { | 1654 | for (i = 0; i < dev_priv->num_fence_regs; i++) { |
1641 | struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i]; | 1655 | struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i]; |
1642 | struct drm_i915_gem_object *obj = reg->obj; | ||
1643 | 1656 | ||
1644 | if (!obj) | 1657 | i915_gem_write_fence(dev, i, NULL); |
1645 | continue; | ||
1646 | 1658 | ||
1647 | if (obj->tiling_mode) | 1659 | if (reg->obj) |
1648 | i915_gem_release_mmap(obj); | 1660 | i915_gem_object_fence_lost(reg->obj); |
1649 | 1661 | ||
1650 | reg->obj->fence_reg = I915_FENCE_REG_NONE; | 1662 | reg->pin_count = 0; |
1651 | reg->obj->fenced_gpu_access = false; | 1663 | reg->obj = NULL; |
1652 | reg->obj->last_fenced_seqno = 0; | 1664 | INIT_LIST_HEAD(®->lru_list); |
1653 | reg->obj->last_fenced_ring = NULL; | ||
1654 | i915_gem_clear_fence_reg(dev, reg); | ||
1655 | } | 1665 | } |
1666 | |||
1667 | INIT_LIST_HEAD(&dev_priv->mm.fence_list); | ||
1656 | } | 1668 | } |
1657 | 1669 | ||
1658 | void i915_gem_reset(struct drm_device *dev) | 1670 | void i915_gem_reset(struct drm_device *dev) |
@@ -1956,6 +1968,62 @@ i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj) | |||
1956 | return 0; | 1968 | return 0; |
1957 | } | 1969 | } |
1958 | 1970 | ||
1971 | /** | ||
1972 | * i915_gem_object_sync - sync an object to a ring. | ||
1973 | * | ||
1974 | * @obj: object which may be in use on another ring. | ||
1975 | * @to: ring we wish to use the object on. May be NULL. | ||
1976 | * | ||
1977 | * This code is meant to abstract object synchronization with the GPU. | ||
1978 | * Calling with NULL implies synchronizing the object with the CPU | ||
1979 | * rather than a particular GPU ring. | ||
1980 | * | ||
1981 | * Returns 0 if successful, else propagates up the lower layer error. | ||
1982 | */ | ||
1983 | int | ||
1984 | i915_gem_object_sync(struct drm_i915_gem_object *obj, | ||
1985 | struct intel_ring_buffer *to) | ||
1986 | { | ||
1987 | struct intel_ring_buffer *from = obj->ring; | ||
1988 | u32 seqno; | ||
1989 | int ret, idx; | ||
1990 | |||
1991 | if (from == NULL || to == from) | ||
1992 | return 0; | ||
1993 | |||
1994 | if (to == NULL || !i915_semaphore_is_enabled(obj->base.dev)) | ||
1995 | return i915_gem_object_wait_rendering(obj); | ||
1996 | |||
1997 | idx = intel_ring_sync_index(from, to); | ||
1998 | |||
1999 | seqno = obj->last_rendering_seqno; | ||
2000 | if (seqno <= from->sync_seqno[idx]) | ||
2001 | return 0; | ||
2002 | |||
2003 | if (seqno == from->outstanding_lazy_request) { | ||
2004 | struct drm_i915_gem_request *request; | ||
2005 | |||
2006 | request = kzalloc(sizeof(*request), GFP_KERNEL); | ||
2007 | if (request == NULL) | ||
2008 | return -ENOMEM; | ||
2009 | |||
2010 | ret = i915_add_request(from, NULL, request); | ||
2011 | if (ret) { | ||
2012 | kfree(request); | ||
2013 | return ret; | ||
2014 | } | ||
2015 | |||
2016 | seqno = request->seqno; | ||
2017 | } | ||
2018 | |||
2019 | |||
2020 | ret = to->sync_to(to, from, seqno); | ||
2021 | if (!ret) | ||
2022 | from->sync_seqno[idx] = seqno; | ||
2023 | |||
2024 | return ret; | ||
2025 | } | ||
2026 | |||
1959 | static void i915_gem_object_finish_gtt(struct drm_i915_gem_object *obj) | 2027 | static void i915_gem_object_finish_gtt(struct drm_i915_gem_object *obj) |
1960 | { | 2028 | { |
1961 | u32 old_write_domain, old_read_domains; | 2029 | u32 old_write_domain, old_read_domains; |
@@ -2110,189 +2178,178 @@ int i915_gpu_idle(struct drm_device *dev, bool do_retire) | |||
2110 | return 0; | 2178 | return 0; |
2111 | } | 2179 | } |
2112 | 2180 | ||
2113 | static int sandybridge_write_fence_reg(struct drm_i915_gem_object *obj, | 2181 | static void sandybridge_write_fence_reg(struct drm_device *dev, int reg, |
2114 | struct intel_ring_buffer *pipelined) | 2182 | struct drm_i915_gem_object *obj) |
2115 | { | 2183 | { |
2116 | struct drm_device *dev = obj->base.dev; | ||
2117 | drm_i915_private_t *dev_priv = dev->dev_private; | 2184 | drm_i915_private_t *dev_priv = dev->dev_private; |
2118 | u32 size = obj->gtt_space->size; | ||
2119 | int regnum = obj->fence_reg; | ||
2120 | uint64_t val; | 2185 | uint64_t val; |
2121 | 2186 | ||
2122 | val = (uint64_t)((obj->gtt_offset + size - 4096) & | 2187 | if (obj) { |
2123 | 0xfffff000) << 32; | 2188 | u32 size = obj->gtt_space->size; |
2124 | val |= obj->gtt_offset & 0xfffff000; | ||
2125 | val |= (uint64_t)((obj->stride / 128) - 1) << | ||
2126 | SANDYBRIDGE_FENCE_PITCH_SHIFT; | ||
2127 | |||
2128 | if (obj->tiling_mode == I915_TILING_Y) | ||
2129 | val |= 1 << I965_FENCE_TILING_Y_SHIFT; | ||
2130 | val |= I965_FENCE_REG_VALID; | ||
2131 | 2189 | ||
2132 | if (pipelined) { | 2190 | val = (uint64_t)((obj->gtt_offset + size - 4096) & |
2133 | int ret = intel_ring_begin(pipelined, 6); | 2191 | 0xfffff000) << 32; |
2134 | if (ret) | 2192 | val |= obj->gtt_offset & 0xfffff000; |
2135 | return ret; | 2193 | val |= (uint64_t)((obj->stride / 128) - 1) << |
2194 | SANDYBRIDGE_FENCE_PITCH_SHIFT; | ||
2136 | 2195 | ||
2137 | intel_ring_emit(pipelined, MI_NOOP); | 2196 | if (obj->tiling_mode == I915_TILING_Y) |
2138 | intel_ring_emit(pipelined, MI_LOAD_REGISTER_IMM(2)); | 2197 | val |= 1 << I965_FENCE_TILING_Y_SHIFT; |
2139 | intel_ring_emit(pipelined, FENCE_REG_SANDYBRIDGE_0 + regnum*8); | 2198 | val |= I965_FENCE_REG_VALID; |
2140 | intel_ring_emit(pipelined, (u32)val); | ||
2141 | intel_ring_emit(pipelined, FENCE_REG_SANDYBRIDGE_0 + regnum*8 + 4); | ||
2142 | intel_ring_emit(pipelined, (u32)(val >> 32)); | ||
2143 | intel_ring_advance(pipelined); | ||
2144 | } else | 2199 | } else |
2145 | I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + regnum * 8, val); | 2200 | val = 0; |
2146 | 2201 | ||
2147 | return 0; | 2202 | I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + reg * 8, val); |
2203 | POSTING_READ(FENCE_REG_SANDYBRIDGE_0 + reg * 8); | ||
2148 | } | 2204 | } |
2149 | 2205 | ||
2150 | static int i965_write_fence_reg(struct drm_i915_gem_object *obj, | 2206 | static void i965_write_fence_reg(struct drm_device *dev, int reg, |
2151 | struct intel_ring_buffer *pipelined) | 2207 | struct drm_i915_gem_object *obj) |
2152 | { | 2208 | { |
2153 | struct drm_device *dev = obj->base.dev; | ||
2154 | drm_i915_private_t *dev_priv = dev->dev_private; | 2209 | drm_i915_private_t *dev_priv = dev->dev_private; |
2155 | u32 size = obj->gtt_space->size; | ||
2156 | int regnum = obj->fence_reg; | ||
2157 | uint64_t val; | 2210 | uint64_t val; |
2158 | 2211 | ||
2159 | val = (uint64_t)((obj->gtt_offset + size - 4096) & | 2212 | if (obj) { |
2160 | 0xfffff000) << 32; | 2213 | u32 size = obj->gtt_space->size; |
2161 | val |= obj->gtt_offset & 0xfffff000; | ||
2162 | val |= ((obj->stride / 128) - 1) << I965_FENCE_PITCH_SHIFT; | ||
2163 | if (obj->tiling_mode == I915_TILING_Y) | ||
2164 | val |= 1 << I965_FENCE_TILING_Y_SHIFT; | ||
2165 | val |= I965_FENCE_REG_VALID; | ||
2166 | |||
2167 | if (pipelined) { | ||
2168 | int ret = intel_ring_begin(pipelined, 6); | ||
2169 | if (ret) | ||
2170 | return ret; | ||
2171 | 2214 | ||
2172 | intel_ring_emit(pipelined, MI_NOOP); | 2215 | val = (uint64_t)((obj->gtt_offset + size - 4096) & |
2173 | intel_ring_emit(pipelined, MI_LOAD_REGISTER_IMM(2)); | 2216 | 0xfffff000) << 32; |
2174 | intel_ring_emit(pipelined, FENCE_REG_965_0 + regnum*8); | 2217 | val |= obj->gtt_offset & 0xfffff000; |
2175 | intel_ring_emit(pipelined, (u32)val); | 2218 | val |= ((obj->stride / 128) - 1) << I965_FENCE_PITCH_SHIFT; |
2176 | intel_ring_emit(pipelined, FENCE_REG_965_0 + regnum*8 + 4); | 2219 | if (obj->tiling_mode == I915_TILING_Y) |
2177 | intel_ring_emit(pipelined, (u32)(val >> 32)); | 2220 | val |= 1 << I965_FENCE_TILING_Y_SHIFT; |
2178 | intel_ring_advance(pipelined); | 2221 | val |= I965_FENCE_REG_VALID; |
2179 | } else | 2222 | } else |
2180 | I915_WRITE64(FENCE_REG_965_0 + regnum * 8, val); | 2223 | val = 0; |
2181 | 2224 | ||
2182 | return 0; | 2225 | I915_WRITE64(FENCE_REG_965_0 + reg * 8, val); |
2226 | POSTING_READ(FENCE_REG_965_0 + reg * 8); | ||
2183 | } | 2227 | } |
2184 | 2228 | ||
2185 | static int i915_write_fence_reg(struct drm_i915_gem_object *obj, | 2229 | static void i915_write_fence_reg(struct drm_device *dev, int reg, |
2186 | struct intel_ring_buffer *pipelined) | 2230 | struct drm_i915_gem_object *obj) |
2187 | { | 2231 | { |
2188 | struct drm_device *dev = obj->base.dev; | ||
2189 | drm_i915_private_t *dev_priv = dev->dev_private; | 2232 | drm_i915_private_t *dev_priv = dev->dev_private; |
2190 | u32 size = obj->gtt_space->size; | 2233 | u32 val; |
2191 | u32 fence_reg, val, pitch_val; | ||
2192 | int tile_width; | ||
2193 | |||
2194 | if (WARN((obj->gtt_offset & ~I915_FENCE_START_MASK) || | ||
2195 | (size & -size) != size || | ||
2196 | (obj->gtt_offset & (size - 1)), | ||
2197 | "object 0x%08x [fenceable? %d] not 1M or pot-size (0x%08x) aligned\n", | ||
2198 | obj->gtt_offset, obj->map_and_fenceable, size)) | ||
2199 | return -EINVAL; | ||
2200 | 2234 | ||
2201 | if (obj->tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev)) | 2235 | if (obj) { |
2202 | tile_width = 128; | 2236 | u32 size = obj->gtt_space->size; |
2203 | else | 2237 | int pitch_val; |
2204 | tile_width = 512; | 2238 | int tile_width; |
2205 | |||
2206 | /* Note: pitch better be a power of two tile widths */ | ||
2207 | pitch_val = obj->stride / tile_width; | ||
2208 | pitch_val = ffs(pitch_val) - 1; | ||
2209 | |||
2210 | val = obj->gtt_offset; | ||
2211 | if (obj->tiling_mode == I915_TILING_Y) | ||
2212 | val |= 1 << I830_FENCE_TILING_Y_SHIFT; | ||
2213 | val |= I915_FENCE_SIZE_BITS(size); | ||
2214 | val |= pitch_val << I830_FENCE_PITCH_SHIFT; | ||
2215 | val |= I830_FENCE_REG_VALID; | ||
2216 | |||
2217 | fence_reg = obj->fence_reg; | ||
2218 | if (fence_reg < 8) | ||
2219 | fence_reg = FENCE_REG_830_0 + fence_reg * 4; | ||
2220 | else | ||
2221 | fence_reg = FENCE_REG_945_8 + (fence_reg - 8) * 4; | ||
2222 | 2239 | ||
2223 | if (pipelined) { | 2240 | WARN((obj->gtt_offset & ~I915_FENCE_START_MASK) || |
2224 | int ret = intel_ring_begin(pipelined, 4); | 2241 | (size & -size) != size || |
2225 | if (ret) | 2242 | (obj->gtt_offset & (size - 1)), |
2226 | return ret; | 2243 | "object 0x%08x [fenceable? %d] not 1M or pot-size (0x%08x) aligned\n", |
2244 | obj->gtt_offset, obj->map_and_fenceable, size); | ||
2227 | 2245 | ||
2228 | intel_ring_emit(pipelined, MI_NOOP); | 2246 | if (obj->tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev)) |
2229 | intel_ring_emit(pipelined, MI_LOAD_REGISTER_IMM(1)); | 2247 | tile_width = 128; |
2230 | intel_ring_emit(pipelined, fence_reg); | 2248 | else |
2231 | intel_ring_emit(pipelined, val); | 2249 | tile_width = 512; |
2232 | intel_ring_advance(pipelined); | 2250 | |
2251 | /* Note: pitch better be a power of two tile widths */ | ||
2252 | pitch_val = obj->stride / tile_width; | ||
2253 | pitch_val = ffs(pitch_val) - 1; | ||
2254 | |||
2255 | val = obj->gtt_offset; | ||
2256 | if (obj->tiling_mode == I915_TILING_Y) | ||
2257 | val |= 1 << I830_FENCE_TILING_Y_SHIFT; | ||
2258 | val |= I915_FENCE_SIZE_BITS(size); | ||
2259 | val |= pitch_val << I830_FENCE_PITCH_SHIFT; | ||
2260 | val |= I830_FENCE_REG_VALID; | ||
2233 | } else | 2261 | } else |
2234 | I915_WRITE(fence_reg, val); | 2262 | val = 0; |
2235 | 2263 | ||
2236 | return 0; | 2264 | if (reg < 8) |
2265 | reg = FENCE_REG_830_0 + reg * 4; | ||
2266 | else | ||
2267 | reg = FENCE_REG_945_8 + (reg - 8) * 4; | ||
2268 | |||
2269 | I915_WRITE(reg, val); | ||
2270 | POSTING_READ(reg); | ||
2237 | } | 2271 | } |
2238 | 2272 | ||
2239 | static int i830_write_fence_reg(struct drm_i915_gem_object *obj, | 2273 | static void i830_write_fence_reg(struct drm_device *dev, int reg, |
2240 | struct intel_ring_buffer *pipelined) | 2274 | struct drm_i915_gem_object *obj) |
2241 | { | 2275 | { |
2242 | struct drm_device *dev = obj->base.dev; | ||
2243 | drm_i915_private_t *dev_priv = dev->dev_private; | 2276 | drm_i915_private_t *dev_priv = dev->dev_private; |
2244 | u32 size = obj->gtt_space->size; | ||
2245 | int regnum = obj->fence_reg; | ||
2246 | uint32_t val; | 2277 | uint32_t val; |
2247 | uint32_t pitch_val; | ||
2248 | 2278 | ||
2249 | if (WARN((obj->gtt_offset & ~I830_FENCE_START_MASK) || | 2279 | if (obj) { |
2250 | (size & -size) != size || | 2280 | u32 size = obj->gtt_space->size; |
2251 | (obj->gtt_offset & (size - 1)), | 2281 | uint32_t pitch_val; |
2252 | "object 0x%08x not 512K or pot-size 0x%08x aligned\n", | 2282 | |
2253 | obj->gtt_offset, size)) | 2283 | WARN((obj->gtt_offset & ~I830_FENCE_START_MASK) || |
2254 | return -EINVAL; | 2284 | (size & -size) != size || |
2255 | 2285 | (obj->gtt_offset & (size - 1)), | |
2256 | pitch_val = obj->stride / 128; | 2286 | "object 0x%08x not 512K or pot-size 0x%08x aligned\n", |
2257 | pitch_val = ffs(pitch_val) - 1; | 2287 | obj->gtt_offset, size); |
2258 | 2288 | ||
2259 | val = obj->gtt_offset; | 2289 | pitch_val = obj->stride / 128; |
2260 | if (obj->tiling_mode == I915_TILING_Y) | 2290 | pitch_val = ffs(pitch_val) - 1; |
2261 | val |= 1 << I830_FENCE_TILING_Y_SHIFT; | 2291 | |
2262 | val |= I830_FENCE_SIZE_BITS(size); | 2292 | val = obj->gtt_offset; |
2263 | val |= pitch_val << I830_FENCE_PITCH_SHIFT; | 2293 | if (obj->tiling_mode == I915_TILING_Y) |
2264 | val |= I830_FENCE_REG_VALID; | 2294 | val |= 1 << I830_FENCE_TILING_Y_SHIFT; |
2295 | val |= I830_FENCE_SIZE_BITS(size); | ||
2296 | val |= pitch_val << I830_FENCE_PITCH_SHIFT; | ||
2297 | val |= I830_FENCE_REG_VALID; | ||
2298 | } else | ||
2299 | val = 0; | ||
2265 | 2300 | ||
2266 | if (pipelined) { | 2301 | I915_WRITE(FENCE_REG_830_0 + reg * 4, val); |
2267 | int ret = intel_ring_begin(pipelined, 4); | 2302 | POSTING_READ(FENCE_REG_830_0 + reg * 4); |
2268 | if (ret) | 2303 | } |
2269 | return ret; | ||
2270 | 2304 | ||
2271 | intel_ring_emit(pipelined, MI_NOOP); | 2305 | static void i915_gem_write_fence(struct drm_device *dev, int reg, |
2272 | intel_ring_emit(pipelined, MI_LOAD_REGISTER_IMM(1)); | 2306 | struct drm_i915_gem_object *obj) |
2273 | intel_ring_emit(pipelined, FENCE_REG_830_0 + regnum*4); | 2307 | { |
2274 | intel_ring_emit(pipelined, val); | 2308 | switch (INTEL_INFO(dev)->gen) { |
2275 | intel_ring_advance(pipelined); | 2309 | case 7: |
2276 | } else | 2310 | case 6: sandybridge_write_fence_reg(dev, reg, obj); break; |
2277 | I915_WRITE(FENCE_REG_830_0 + regnum * 4, val); | 2311 | case 5: |
2312 | case 4: i965_write_fence_reg(dev, reg, obj); break; | ||
2313 | case 3: i915_write_fence_reg(dev, reg, obj); break; | ||
2314 | case 2: i830_write_fence_reg(dev, reg, obj); break; | ||
2315 | default: break; | ||
2316 | } | ||
2317 | } | ||
2278 | 2318 | ||
2279 | return 0; | 2319 | static inline int fence_number(struct drm_i915_private *dev_priv, |
2320 | struct drm_i915_fence_reg *fence) | ||
2321 | { | ||
2322 | return fence - dev_priv->fence_regs; | ||
2280 | } | 2323 | } |
2281 | 2324 | ||
2282 | static bool ring_passed_seqno(struct intel_ring_buffer *ring, u32 seqno) | 2325 | static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj, |
2326 | struct drm_i915_fence_reg *fence, | ||
2327 | bool enable) | ||
2283 | { | 2328 | { |
2284 | return i915_seqno_passed(ring->get_seqno(ring), seqno); | 2329 | struct drm_i915_private *dev_priv = obj->base.dev->dev_private; |
2330 | int reg = fence_number(dev_priv, fence); | ||
2331 | |||
2332 | i915_gem_write_fence(obj->base.dev, reg, enable ? obj : NULL); | ||
2333 | |||
2334 | if (enable) { | ||
2335 | obj->fence_reg = reg; | ||
2336 | fence->obj = obj; | ||
2337 | list_move_tail(&fence->lru_list, &dev_priv->mm.fence_list); | ||
2338 | } else { | ||
2339 | obj->fence_reg = I915_FENCE_REG_NONE; | ||
2340 | fence->obj = NULL; | ||
2341 | list_del_init(&fence->lru_list); | ||
2342 | } | ||
2285 | } | 2343 | } |
2286 | 2344 | ||
2287 | static int | 2345 | static int |
2288 | i915_gem_object_flush_fence(struct drm_i915_gem_object *obj, | 2346 | i915_gem_object_flush_fence(struct drm_i915_gem_object *obj) |
2289 | struct intel_ring_buffer *pipelined) | ||
2290 | { | 2347 | { |
2291 | int ret; | 2348 | int ret; |
2292 | 2349 | ||
2293 | if (obj->fenced_gpu_access) { | 2350 | if (obj->fenced_gpu_access) { |
2294 | if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) { | 2351 | if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) { |
2295 | ret = i915_gem_flush_ring(obj->last_fenced_ring, | 2352 | ret = i915_gem_flush_ring(obj->ring, |
2296 | 0, obj->base.write_domain); | 2353 | 0, obj->base.write_domain); |
2297 | if (ret) | 2354 | if (ret) |
2298 | return ret; | 2355 | return ret; |
@@ -2301,18 +2358,14 @@ i915_gem_object_flush_fence(struct drm_i915_gem_object *obj, | |||
2301 | obj->fenced_gpu_access = false; | 2358 | obj->fenced_gpu_access = false; |
2302 | } | 2359 | } |
2303 | 2360 | ||
2304 | if (obj->last_fenced_seqno && pipelined != obj->last_fenced_ring) { | 2361 | if (obj->last_fenced_seqno) { |
2305 | if (!ring_passed_seqno(obj->last_fenced_ring, | 2362 | ret = i915_wait_request(obj->ring, |
2306 | obj->last_fenced_seqno)) { | 2363 | obj->last_fenced_seqno, |
2307 | ret = i915_wait_request(obj->last_fenced_ring, | 2364 | false); |
2308 | obj->last_fenced_seqno, | 2365 | if (ret) |
2309 | true); | 2366 | return ret; |
2310 | if (ret) | ||
2311 | return ret; | ||
2312 | } | ||
2313 | 2367 | ||
2314 | obj->last_fenced_seqno = 0; | 2368 | obj->last_fenced_seqno = 0; |
2315 | obj->last_fenced_ring = NULL; | ||
2316 | } | 2369 | } |
2317 | 2370 | ||
2318 | /* Ensure that all CPU reads are completed before installing a fence | 2371 | /* Ensure that all CPU reads are completed before installing a fence |
@@ -2327,34 +2380,29 @@ i915_gem_object_flush_fence(struct drm_i915_gem_object *obj, | |||
2327 | int | 2380 | int |
2328 | i915_gem_object_put_fence(struct drm_i915_gem_object *obj) | 2381 | i915_gem_object_put_fence(struct drm_i915_gem_object *obj) |
2329 | { | 2382 | { |
2383 | struct drm_i915_private *dev_priv = obj->base.dev->dev_private; | ||
2330 | int ret; | 2384 | int ret; |
2331 | 2385 | ||
2332 | if (obj->tiling_mode) | 2386 | ret = i915_gem_object_flush_fence(obj); |
2333 | i915_gem_release_mmap(obj); | ||
2334 | |||
2335 | ret = i915_gem_object_flush_fence(obj, NULL); | ||
2336 | if (ret) | 2387 | if (ret) |
2337 | return ret; | 2388 | return ret; |
2338 | 2389 | ||
2339 | if (obj->fence_reg != I915_FENCE_REG_NONE) { | 2390 | if (obj->fence_reg == I915_FENCE_REG_NONE) |
2340 | struct drm_i915_private *dev_priv = obj->base.dev->dev_private; | 2391 | return 0; |
2341 | |||
2342 | WARN_ON(dev_priv->fence_regs[obj->fence_reg].pin_count); | ||
2343 | i915_gem_clear_fence_reg(obj->base.dev, | ||
2344 | &dev_priv->fence_regs[obj->fence_reg]); | ||
2345 | 2392 | ||
2346 | obj->fence_reg = I915_FENCE_REG_NONE; | 2393 | i915_gem_object_update_fence(obj, |
2347 | } | 2394 | &dev_priv->fence_regs[obj->fence_reg], |
2395 | false); | ||
2396 | i915_gem_object_fence_lost(obj); | ||
2348 | 2397 | ||
2349 | return 0; | 2398 | return 0; |
2350 | } | 2399 | } |
2351 | 2400 | ||
2352 | static struct drm_i915_fence_reg * | 2401 | static struct drm_i915_fence_reg * |
2353 | i915_find_fence_reg(struct drm_device *dev, | 2402 | i915_find_fence_reg(struct drm_device *dev) |
2354 | struct intel_ring_buffer *pipelined) | ||
2355 | { | 2403 | { |
2356 | struct drm_i915_private *dev_priv = dev->dev_private; | 2404 | struct drm_i915_private *dev_priv = dev->dev_private; |
2357 | struct drm_i915_fence_reg *reg, *first, *avail; | 2405 | struct drm_i915_fence_reg *reg, *avail; |
2358 | int i; | 2406 | int i; |
2359 | 2407 | ||
2360 | /* First try to find a free reg */ | 2408 | /* First try to find a free reg */ |
@@ -2372,204 +2420,77 @@ i915_find_fence_reg(struct drm_device *dev, | |||
2372 | return NULL; | 2420 | return NULL; |
2373 | 2421 | ||
2374 | /* None available, try to steal one or wait for a user to finish */ | 2422 | /* None available, try to steal one or wait for a user to finish */ |
2375 | avail = first = NULL; | ||
2376 | list_for_each_entry(reg, &dev_priv->mm.fence_list, lru_list) { | 2423 | list_for_each_entry(reg, &dev_priv->mm.fence_list, lru_list) { |
2377 | if (reg->pin_count) | 2424 | if (reg->pin_count) |
2378 | continue; | 2425 | continue; |
2379 | 2426 | ||
2380 | if (first == NULL) | 2427 | return reg; |
2381 | first = reg; | ||
2382 | |||
2383 | if (!pipelined || | ||
2384 | !reg->obj->last_fenced_ring || | ||
2385 | reg->obj->last_fenced_ring == pipelined) { | ||
2386 | avail = reg; | ||
2387 | break; | ||
2388 | } | ||
2389 | } | 2428 | } |
2390 | 2429 | ||
2391 | if (avail == NULL) | 2430 | return NULL; |
2392 | avail = first; | ||
2393 | |||
2394 | return avail; | ||
2395 | } | 2431 | } |
2396 | 2432 | ||
2397 | /** | 2433 | /** |
2398 | * i915_gem_object_get_fence - set up a fence reg for an object | 2434 | * i915_gem_object_get_fence - set up fencing for an object |
2399 | * @obj: object to map through a fence reg | 2435 | * @obj: object to map through a fence reg |
2400 | * @pipelined: ring on which to queue the change, or NULL for CPU access | ||
2401 | * @interruptible: must we wait uninterruptibly for the register to retire? | ||
2402 | * | 2436 | * |
2403 | * When mapping objects through the GTT, userspace wants to be able to write | 2437 | * When mapping objects through the GTT, userspace wants to be able to write |
2404 | * to them without having to worry about swizzling if the object is tiled. | 2438 | * to them without having to worry about swizzling if the object is tiled. |
2405 | * | ||
2406 | * This function walks the fence regs looking for a free one for @obj, | 2439 | * This function walks the fence regs looking for a free one for @obj, |
2407 | * stealing one if it can't find any. | 2440 | * stealing one if it can't find any. |
2408 | * | 2441 | * |
2409 | * It then sets up the reg based on the object's properties: address, pitch | 2442 | * It then sets up the reg based on the object's properties: address, pitch |
2410 | * and tiling format. | 2443 | * and tiling format. |
2444 | * | ||
2445 | * For an untiled surface, this removes any existing fence. | ||
2411 | */ | 2446 | */ |
2412 | int | 2447 | int |
2413 | i915_gem_object_get_fence(struct drm_i915_gem_object *obj, | 2448 | i915_gem_object_get_fence(struct drm_i915_gem_object *obj) |
2414 | struct intel_ring_buffer *pipelined) | ||
2415 | { | 2449 | { |
2416 | struct drm_device *dev = obj->base.dev; | 2450 | struct drm_device *dev = obj->base.dev; |
2417 | struct drm_i915_private *dev_priv = dev->dev_private; | 2451 | struct drm_i915_private *dev_priv = dev->dev_private; |
2452 | bool enable = obj->tiling_mode != I915_TILING_NONE; | ||
2418 | struct drm_i915_fence_reg *reg; | 2453 | struct drm_i915_fence_reg *reg; |
2419 | int ret; | 2454 | int ret; |
2420 | 2455 | ||
2421 | /* XXX disable pipelining. There are bugs. Shocking. */ | 2456 | /* Have we updated the tiling parameters upon the object and so |
2422 | pipelined = NULL; | 2457 | * will need to serialise the write to the associated fence register? |
2458 | */ | ||
2459 | if (obj->tiling_changed) { | ||
2460 | ret = i915_gem_object_flush_fence(obj); | ||
2461 | if (ret) | ||
2462 | return ret; | ||
2463 | } | ||
2423 | 2464 | ||
2424 | /* Just update our place in the LRU if our fence is getting reused. */ | 2465 | /* Just update our place in the LRU if our fence is getting reused. */ |
2425 | if (obj->fence_reg != I915_FENCE_REG_NONE) { | 2466 | if (obj->fence_reg != I915_FENCE_REG_NONE) { |
2426 | reg = &dev_priv->fence_regs[obj->fence_reg]; | 2467 | reg = &dev_priv->fence_regs[obj->fence_reg]; |
2427 | list_move_tail(®->lru_list, &dev_priv->mm.fence_list); | 2468 | if (!obj->tiling_changed) { |
2428 | 2469 | list_move_tail(®->lru_list, | |
2429 | if (obj->tiling_changed) { | 2470 | &dev_priv->mm.fence_list); |
2430 | ret = i915_gem_object_flush_fence(obj, pipelined); | 2471 | return 0; |
2431 | if (ret) | ||
2432 | return ret; | ||
2433 | |||
2434 | if (!obj->fenced_gpu_access && !obj->last_fenced_seqno) | ||
2435 | pipelined = NULL; | ||
2436 | |||
2437 | if (pipelined) { | ||
2438 | reg->setup_seqno = | ||
2439 | i915_gem_next_request_seqno(pipelined); | ||
2440 | obj->last_fenced_seqno = reg->setup_seqno; | ||
2441 | obj->last_fenced_ring = pipelined; | ||
2442 | } | ||
2443 | |||
2444 | goto update; | ||
2445 | } | 2472 | } |
2473 | } else if (enable) { | ||
2474 | reg = i915_find_fence_reg(dev); | ||
2475 | if (reg == NULL) | ||
2476 | return -EDEADLK; | ||
2446 | 2477 | ||
2447 | if (!pipelined) { | 2478 | if (reg->obj) { |
2448 | if (reg->setup_seqno) { | 2479 | struct drm_i915_gem_object *old = reg->obj; |
2449 | if (!ring_passed_seqno(obj->last_fenced_ring, | ||
2450 | reg->setup_seqno)) { | ||
2451 | ret = i915_wait_request(obj->last_fenced_ring, | ||
2452 | reg->setup_seqno, | ||
2453 | true); | ||
2454 | if (ret) | ||
2455 | return ret; | ||
2456 | } | ||
2457 | 2480 | ||
2458 | reg->setup_seqno = 0; | 2481 | ret = i915_gem_object_flush_fence(old); |
2459 | } | ||
2460 | } else if (obj->last_fenced_ring && | ||
2461 | obj->last_fenced_ring != pipelined) { | ||
2462 | ret = i915_gem_object_flush_fence(obj, pipelined); | ||
2463 | if (ret) | 2482 | if (ret) |
2464 | return ret; | 2483 | return ret; |
2465 | } | ||
2466 | |||
2467 | return 0; | ||
2468 | } | ||
2469 | |||
2470 | reg = i915_find_fence_reg(dev, pipelined); | ||
2471 | if (reg == NULL) | ||
2472 | return -EDEADLK; | ||
2473 | |||
2474 | ret = i915_gem_object_flush_fence(obj, pipelined); | ||
2475 | if (ret) | ||
2476 | return ret; | ||
2477 | |||
2478 | if (reg->obj) { | ||
2479 | struct drm_i915_gem_object *old = reg->obj; | ||
2480 | |||
2481 | drm_gem_object_reference(&old->base); | ||
2482 | |||
2483 | if (old->tiling_mode) | ||
2484 | i915_gem_release_mmap(old); | ||
2485 | 2484 | ||
2486 | ret = i915_gem_object_flush_fence(old, pipelined); | 2485 | i915_gem_object_fence_lost(old); |
2487 | if (ret) { | ||
2488 | drm_gem_object_unreference(&old->base); | ||
2489 | return ret; | ||
2490 | } | 2486 | } |
2487 | } else | ||
2488 | return 0; | ||
2491 | 2489 | ||
2492 | if (old->last_fenced_seqno == 0 && obj->last_fenced_seqno == 0) | 2490 | i915_gem_object_update_fence(obj, reg, enable); |
2493 | pipelined = NULL; | ||
2494 | |||
2495 | old->fence_reg = I915_FENCE_REG_NONE; | ||
2496 | old->last_fenced_ring = pipelined; | ||
2497 | old->last_fenced_seqno = | ||
2498 | pipelined ? i915_gem_next_request_seqno(pipelined) : 0; | ||
2499 | |||
2500 | drm_gem_object_unreference(&old->base); | ||
2501 | } else if (obj->last_fenced_seqno == 0) | ||
2502 | pipelined = NULL; | ||
2503 | |||
2504 | reg->obj = obj; | ||
2505 | list_move_tail(®->lru_list, &dev_priv->mm.fence_list); | ||
2506 | obj->fence_reg = reg - dev_priv->fence_regs; | ||
2507 | obj->last_fenced_ring = pipelined; | ||
2508 | |||
2509 | reg->setup_seqno = | ||
2510 | pipelined ? i915_gem_next_request_seqno(pipelined) : 0; | ||
2511 | obj->last_fenced_seqno = reg->setup_seqno; | ||
2512 | |||
2513 | update: | ||
2514 | obj->tiling_changed = false; | 2491 | obj->tiling_changed = false; |
2515 | switch (INTEL_INFO(dev)->gen) { | ||
2516 | case 7: | ||
2517 | case 6: | ||
2518 | ret = sandybridge_write_fence_reg(obj, pipelined); | ||
2519 | break; | ||
2520 | case 5: | ||
2521 | case 4: | ||
2522 | ret = i965_write_fence_reg(obj, pipelined); | ||
2523 | break; | ||
2524 | case 3: | ||
2525 | ret = i915_write_fence_reg(obj, pipelined); | ||
2526 | break; | ||
2527 | case 2: | ||
2528 | ret = i830_write_fence_reg(obj, pipelined); | ||
2529 | break; | ||
2530 | } | ||
2531 | |||
2532 | return ret; | ||
2533 | } | ||
2534 | |||
2535 | /** | ||
2536 | * i915_gem_clear_fence_reg - clear out fence register info | ||
2537 | * @obj: object to clear | ||
2538 | * | ||
2539 | * Zeroes out the fence register itself and clears out the associated | ||
2540 | * data structures in dev_priv and obj. | ||
2541 | */ | ||
2542 | static void | ||
2543 | i915_gem_clear_fence_reg(struct drm_device *dev, | ||
2544 | struct drm_i915_fence_reg *reg) | ||
2545 | { | ||
2546 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
2547 | uint32_t fence_reg = reg - dev_priv->fence_regs; | ||
2548 | 2492 | ||
2549 | switch (INTEL_INFO(dev)->gen) { | 2493 | return 0; |
2550 | case 7: | ||
2551 | case 6: | ||
2552 | I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + fence_reg*8, 0); | ||
2553 | break; | ||
2554 | case 5: | ||
2555 | case 4: | ||
2556 | I915_WRITE64(FENCE_REG_965_0 + fence_reg*8, 0); | ||
2557 | break; | ||
2558 | case 3: | ||
2559 | if (fence_reg >= 8) | ||
2560 | fence_reg = FENCE_REG_945_8 + (fence_reg - 8) * 4; | ||
2561 | else | ||
2562 | case 2: | ||
2563 | fence_reg = FENCE_REG_830_0 + fence_reg * 4; | ||
2564 | |||
2565 | I915_WRITE(fence_reg, 0); | ||
2566 | break; | ||
2567 | } | ||
2568 | |||
2569 | list_del_init(®->lru_list); | ||
2570 | reg->obj = NULL; | ||
2571 | reg->setup_seqno = 0; | ||
2572 | reg->pin_count = 0; | ||
2573 | } | 2494 | } |
2574 | 2495 | ||
2575 | /** | 2496 | /** |
@@ -2926,11 +2847,6 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, | |||
2926 | * Prepare buffer for display plane (scanout, cursors, etc). | 2847 | * Prepare buffer for display plane (scanout, cursors, etc). |
2927 | * Can be called from an uninterruptible phase (modesetting) and allows | 2848 | * Can be called from an uninterruptible phase (modesetting) and allows |
2928 | * any flushes to be pipelined (for pageflips). | 2849 | * any flushes to be pipelined (for pageflips). |
2929 | * | ||
2930 | * For the display plane, we want to be in the GTT but out of any write | ||
2931 | * domains. So in many ways this looks like set_to_gtt_domain() apart from the | ||
2932 | * ability to pipeline the waits, pinning and any additional subtleties | ||
2933 | * that may differentiate the display plane from ordinary buffers. | ||
2934 | */ | 2850 | */ |
2935 | int | 2851 | int |
2936 | i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, | 2852 | i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, |
@@ -2945,8 +2861,8 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, | |||
2945 | return ret; | 2861 | return ret; |
2946 | 2862 | ||
2947 | if (pipelined != obj->ring) { | 2863 | if (pipelined != obj->ring) { |
2948 | ret = i915_gem_object_wait_rendering(obj); | 2864 | ret = i915_gem_object_sync(obj, pipelined); |
2949 | if (ret == -ERESTARTSYS) | 2865 | if (ret) |
2950 | return ret; | 2866 | return ret; |
2951 | } | 2867 | } |
2952 | 2868 | ||
@@ -3031,9 +2947,11 @@ i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write) | |||
3031 | if (ret) | 2947 | if (ret) |
3032 | return ret; | 2948 | return ret; |
3033 | 2949 | ||
3034 | ret = i915_gem_object_wait_rendering(obj); | 2950 | if (write || obj->pending_gpu_write) { |
3035 | if (ret) | 2951 | ret = i915_gem_object_wait_rendering(obj); |
3036 | return ret; | 2952 | if (ret) |
2953 | return ret; | ||
2954 | } | ||
3037 | 2955 | ||
3038 | i915_gem_object_flush_gtt_write_domain(obj); | 2956 | i915_gem_object_flush_gtt_write_domain(obj); |
3039 | 2957 | ||
@@ -3613,7 +3531,15 @@ void i915_gem_init_ppgtt(struct drm_device *dev) | |||
3613 | pd_offset <<= 16; | 3531 | pd_offset <<= 16; |
3614 | 3532 | ||
3615 | if (INTEL_INFO(dev)->gen == 6) { | 3533 | if (INTEL_INFO(dev)->gen == 6) { |
3616 | uint32_t ecochk = I915_READ(GAM_ECOCHK); | 3534 | uint32_t ecochk, gab_ctl, ecobits; |
3535 | |||
3536 | ecobits = I915_READ(GAC_ECO_BITS); | ||
3537 | I915_WRITE(GAC_ECO_BITS, ecobits | ECOBITS_PPGTT_CACHE64B); | ||
3538 | |||
3539 | gab_ctl = I915_READ(GAB_CTL); | ||
3540 | I915_WRITE(GAB_CTL, gab_ctl | GAB_CTL_CONT_AFTER_PAGEFAULT); | ||
3541 | |||
3542 | ecochk = I915_READ(GAM_ECOCHK); | ||
3617 | I915_WRITE(GAM_ECOCHK, ecochk | ECOCHK_SNB_BIT | | 3543 | I915_WRITE(GAM_ECOCHK, ecochk | ECOCHK_SNB_BIT | |
3618 | ECOCHK_PPGTT_CACHE64B); | 3544 | ECOCHK_PPGTT_CACHE64B); |
3619 | I915_WRITE(GFX_MODE, GFX_MODE_ENABLE(GFX_PPGTT_ENABLE)); | 3545 | I915_WRITE(GFX_MODE, GFX_MODE_ENABLE(GFX_PPGTT_ENABLE)); |
@@ -3804,9 +3730,7 @@ i915_gem_load(struct drm_device *dev) | |||
3804 | dev_priv->num_fence_regs = 8; | 3730 | dev_priv->num_fence_regs = 8; |
3805 | 3731 | ||
3806 | /* Initialize fence registers to zero */ | 3732 | /* Initialize fence registers to zero */ |
3807 | for (i = 0; i < dev_priv->num_fence_regs; i++) { | 3733 | i915_gem_reset_fences(dev); |
3808 | i915_gem_clear_fence_reg(dev, &dev_priv->fence_regs[i]); | ||
3809 | } | ||
3810 | 3734 | ||
3811 | i915_gem_detect_bit_6_swizzle(dev); | 3735 | i915_gem_detect_bit_6_swizzle(dev); |
3812 | init_waitqueue_head(&dev_priv->pending_flip_queue); | 3736 | init_waitqueue_head(&dev_priv->pending_flip_queue); |
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 254e2f6ac4f0..68ec0130a626 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
@@ -381,7 +381,11 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, | |||
381 | uint32_t __iomem *reloc_entry; | 381 | uint32_t __iomem *reloc_entry; |
382 | void __iomem *reloc_page; | 382 | void __iomem *reloc_page; |
383 | 383 | ||
384 | ret = i915_gem_object_set_to_gtt_domain(obj, 1); | 384 | ret = i915_gem_object_set_to_gtt_domain(obj, true); |
385 | if (ret) | ||
386 | return ret; | ||
387 | |||
388 | ret = i915_gem_object_put_fence(obj); | ||
385 | if (ret) | 389 | if (ret) |
386 | return ret; | 390 | return ret; |
387 | 391 | ||
@@ -530,18 +534,13 @@ pin_and_fence_object(struct drm_i915_gem_object *obj, | |||
530 | 534 | ||
531 | if (has_fenced_gpu_access) { | 535 | if (has_fenced_gpu_access) { |
532 | if (entry->flags & EXEC_OBJECT_NEEDS_FENCE) { | 536 | if (entry->flags & EXEC_OBJECT_NEEDS_FENCE) { |
533 | if (obj->tiling_mode) { | 537 | ret = i915_gem_object_get_fence(obj); |
534 | ret = i915_gem_object_get_fence(obj, ring); | 538 | if (ret) |
535 | if (ret) | 539 | goto err_unpin; |
536 | goto err_unpin; | ||
537 | 540 | ||
541 | if (i915_gem_object_pin_fence(obj)) | ||
538 | entry->flags |= __EXEC_OBJECT_HAS_FENCE; | 542 | entry->flags |= __EXEC_OBJECT_HAS_FENCE; |
539 | i915_gem_object_pin_fence(obj); | 543 | |
540 | } else { | ||
541 | ret = i915_gem_object_put_fence(obj); | ||
542 | if (ret) | ||
543 | goto err_unpin; | ||
544 | } | ||
545 | obj->pending_fenced_gpu_access = true; | 544 | obj->pending_fenced_gpu_access = true; |
546 | } | 545 | } |
547 | } | 546 | } |
@@ -840,64 +839,6 @@ i915_gem_execbuffer_flush(struct drm_device *dev, | |||
840 | return 0; | 839 | return 0; |
841 | } | 840 | } |
842 | 841 | ||
843 | static bool | ||
844 | intel_enable_semaphores(struct drm_device *dev) | ||
845 | { | ||
846 | if (INTEL_INFO(dev)->gen < 6) | ||
847 | return 0; | ||
848 | |||
849 | if (i915_semaphores >= 0) | ||
850 | return i915_semaphores; | ||
851 | |||
852 | /* Disable semaphores on SNB */ | ||
853 | if (INTEL_INFO(dev)->gen == 6) | ||
854 | return 0; | ||
855 | |||
856 | return 1; | ||
857 | } | ||
858 | |||
859 | static int | ||
860 | i915_gem_execbuffer_sync_rings(struct drm_i915_gem_object *obj, | ||
861 | struct intel_ring_buffer *to) | ||
862 | { | ||
863 | struct intel_ring_buffer *from = obj->ring; | ||
864 | u32 seqno; | ||
865 | int ret, idx; | ||
866 | |||
867 | if (from == NULL || to == from) | ||
868 | return 0; | ||
869 | |||
870 | /* XXX gpu semaphores are implicated in various hard hangs on SNB */ | ||
871 | if (!intel_enable_semaphores(obj->base.dev)) | ||
872 | return i915_gem_object_wait_rendering(obj); | ||
873 | |||
874 | idx = intel_ring_sync_index(from, to); | ||
875 | |||
876 | seqno = obj->last_rendering_seqno; | ||
877 | if (seqno <= from->sync_seqno[idx]) | ||
878 | return 0; | ||
879 | |||
880 | if (seqno == from->outstanding_lazy_request) { | ||
881 | struct drm_i915_gem_request *request; | ||
882 | |||
883 | request = kzalloc(sizeof(*request), GFP_KERNEL); | ||
884 | if (request == NULL) | ||
885 | return -ENOMEM; | ||
886 | |||
887 | ret = i915_add_request(from, NULL, request); | ||
888 | if (ret) { | ||
889 | kfree(request); | ||
890 | return ret; | ||
891 | } | ||
892 | |||
893 | seqno = request->seqno; | ||
894 | } | ||
895 | |||
896 | from->sync_seqno[idx] = seqno; | ||
897 | |||
898 | return to->sync_to(to, from, seqno - 1); | ||
899 | } | ||
900 | |||
901 | static int | 842 | static int |
902 | i915_gem_execbuffer_wait_for_flips(struct intel_ring_buffer *ring, u32 flips) | 843 | i915_gem_execbuffer_wait_for_flips(struct intel_ring_buffer *ring, u32 flips) |
903 | { | 844 | { |
@@ -959,7 +900,7 @@ i915_gem_execbuffer_move_to_gpu(struct intel_ring_buffer *ring, | |||
959 | } | 900 | } |
960 | 901 | ||
961 | list_for_each_entry(obj, objects, exec_list) { | 902 | list_for_each_entry(obj, objects, exec_list) { |
962 | ret = i915_gem_execbuffer_sync_rings(obj, ring); | 903 | ret = i915_gem_object_sync(obj, ring); |
963 | if (ret) | 904 | if (ret) |
964 | return ret; | 905 | return ret; |
965 | } | 906 | } |
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 4fb875de32e6..25c8bf9d1d4e 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c | |||
@@ -96,11 +96,10 @@ int i915_gem_init_aliasing_ppgtt(struct drm_device *dev) | |||
96 | GFP_KERNEL); | 96 | GFP_KERNEL); |
97 | if (!ppgtt->pt_dma_addr) | 97 | if (!ppgtt->pt_dma_addr) |
98 | goto err_pt_alloc; | 98 | goto err_pt_alloc; |
99 | } | ||
100 | 99 | ||
101 | for (i = 0; i < ppgtt->num_pd_entries; i++) { | 100 | for (i = 0; i < ppgtt->num_pd_entries; i++) { |
102 | dma_addr_t pt_addr; | 101 | dma_addr_t pt_addr; |
103 | if (dev_priv->mm.gtt->needs_dmar) { | 102 | |
104 | pt_addr = pci_map_page(dev->pdev, ppgtt->pt_pages[i], | 103 | pt_addr = pci_map_page(dev->pdev, ppgtt->pt_pages[i], |
105 | 0, 4096, | 104 | 0, 4096, |
106 | PCI_DMA_BIDIRECTIONAL); | 105 | PCI_DMA_BIDIRECTIONAL); |
@@ -112,8 +111,7 @@ int i915_gem_init_aliasing_ppgtt(struct drm_device *dev) | |||
112 | 111 | ||
113 | } | 112 | } |
114 | ppgtt->pt_dma_addr[i] = pt_addr; | 113 | ppgtt->pt_dma_addr[i] = pt_addr; |
115 | } else | 114 | } |
116 | pt_addr = page_to_phys(ppgtt->pt_pages[i]); | ||
117 | } | 115 | } |
118 | 116 | ||
119 | ppgtt->scratch_page_dma_addr = dev_priv->mm.gtt->scratch_page_dma; | 117 | ppgtt->scratch_page_dma_addr = dev_priv->mm.gtt->scratch_page_dma; |
diff --git a/drivers/gpu/drm/i915/i915_ioc32.c b/drivers/gpu/drm/i915/i915_ioc32.c index 13b028994b2b..0e72abb9f701 100644 --- a/drivers/gpu/drm/i915/i915_ioc32.c +++ b/drivers/gpu/drm/i915/i915_ioc32.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include "drmP.h" | 34 | #include "drmP.h" |
35 | #include "drm.h" | 35 | #include "drm.h" |
36 | #include "i915_drm.h" | 36 | #include "i915_drm.h" |
37 | #include "i915_drv.h" | ||
37 | 38 | ||
38 | typedef struct _drm_i915_batchbuffer32 { | 39 | typedef struct _drm_i915_batchbuffer32 { |
39 | int start; /* agp offset */ | 40 | int start; /* agp offset */ |
@@ -181,7 +182,7 @@ static int compat_i915_alloc(struct file *file, unsigned int cmd, | |||
181 | (unsigned long)request); | 182 | (unsigned long)request); |
182 | } | 183 | } |
183 | 184 | ||
184 | drm_ioctl_compat_t *i915_compat_ioctls[] = { | 185 | static drm_ioctl_compat_t *i915_compat_ioctls[] = { |
185 | [DRM_I915_BATCHBUFFER] = compat_i915_batchbuffer, | 186 | [DRM_I915_BATCHBUFFER] = compat_i915_batchbuffer, |
186 | [DRM_I915_CMDBUFFER] = compat_i915_cmdbuffer, | 187 | [DRM_I915_CMDBUFFER] = compat_i915_cmdbuffer, |
187 | [DRM_I915_GETPARAM] = compat_i915_getparam, | 188 | [DRM_I915_GETPARAM] = compat_i915_getparam, |
@@ -189,6 +190,7 @@ drm_ioctl_compat_t *i915_compat_ioctls[] = { | |||
189 | [DRM_I915_ALLOC] = compat_i915_alloc | 190 | [DRM_I915_ALLOC] = compat_i915_alloc |
190 | }; | 191 | }; |
191 | 192 | ||
193 | #ifdef CONFIG_COMPAT | ||
192 | /** | 194 | /** |
193 | * Called whenever a 32-bit process running under a 64-bit kernel | 195 | * Called whenever a 32-bit process running under a 64-bit kernel |
194 | * performs an ioctl on /dev/dri/card<n>. | 196 | * performs an ioctl on /dev/dri/card<n>. |
@@ -217,3 +219,4 @@ long i915_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
217 | 219 | ||
218 | return ret; | 220 | return ret; |
219 | } | 221 | } |
222 | #endif | ||
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index febddc2952fb..ab023ca73b45 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -451,6 +451,31 @@ static void snb_gt_irq_handler(struct drm_device *dev, | |||
451 | } | 451 | } |
452 | } | 452 | } |
453 | 453 | ||
454 | static void gen6_queue_rps_work(struct drm_i915_private *dev_priv, | ||
455 | u32 pm_iir) | ||
456 | { | ||
457 | unsigned long flags; | ||
458 | |||
459 | /* | ||
460 | * IIR bits should never already be set because IMR should | ||
461 | * prevent an interrupt from being shown in IIR. The warning | ||
462 | * displays a case where we've unsafely cleared | ||
463 | * dev_priv->pm_iir. Although missing an interrupt of the same | ||
464 | * type is not a problem, it displays a problem in the logic. | ||
465 | * | ||
466 | * The mask bit in IMR is cleared by rps_work. | ||
467 | */ | ||
468 | |||
469 | spin_lock_irqsave(&dev_priv->rps_lock, flags); | ||
470 | WARN(dev_priv->pm_iir & pm_iir, "Missed a PM interrupt\n"); | ||
471 | dev_priv->pm_iir |= pm_iir; | ||
472 | I915_WRITE(GEN6_PMIMR, dev_priv->pm_iir); | ||
473 | POSTING_READ(GEN6_PMIMR); | ||
474 | spin_unlock_irqrestore(&dev_priv->rps_lock, flags); | ||
475 | |||
476 | queue_work(dev_priv->wq, &dev_priv->rps_work); | ||
477 | } | ||
478 | |||
454 | static irqreturn_t valleyview_irq_handler(DRM_IRQ_ARGS) | 479 | static irqreturn_t valleyview_irq_handler(DRM_IRQ_ARGS) |
455 | { | 480 | { |
456 | struct drm_device *dev = (struct drm_device *) arg; | 481 | struct drm_device *dev = (struct drm_device *) arg; |
@@ -532,16 +557,8 @@ static irqreturn_t valleyview_irq_handler(DRM_IRQ_ARGS) | |||
532 | if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS) | 557 | if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS) |
533 | blc_event = true; | 558 | blc_event = true; |
534 | 559 | ||
535 | if (pm_iir & GEN6_PM_DEFERRED_EVENTS) { | 560 | if (pm_iir & GEN6_PM_DEFERRED_EVENTS) |
536 | unsigned long flags; | 561 | gen6_queue_rps_work(dev_priv, pm_iir); |
537 | spin_lock_irqsave(&dev_priv->rps_lock, flags); | ||
538 | WARN(dev_priv->pm_iir & pm_iir, "Missed a PM interrupt\n"); | ||
539 | dev_priv->pm_iir |= pm_iir; | ||
540 | I915_WRITE(GEN6_PMIMR, dev_priv->pm_iir); | ||
541 | POSTING_READ(GEN6_PMIMR); | ||
542 | spin_unlock_irqrestore(&dev_priv->rps_lock, flags); | ||
543 | queue_work(dev_priv->wq, &dev_priv->rps_work); | ||
544 | } | ||
545 | 562 | ||
546 | I915_WRITE(GTIIR, gt_iir); | 563 | I915_WRITE(GTIIR, gt_iir); |
547 | I915_WRITE(GEN6_PMIIR, pm_iir); | 564 | I915_WRITE(GEN6_PMIIR, pm_iir); |
@@ -655,16 +672,8 @@ static irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS) | |||
655 | pch_irq_handler(dev); | 672 | pch_irq_handler(dev); |
656 | } | 673 | } |
657 | 674 | ||
658 | if (pm_iir & GEN6_PM_DEFERRED_EVENTS) { | 675 | if (pm_iir & GEN6_PM_DEFERRED_EVENTS) |
659 | unsigned long flags; | 676 | gen6_queue_rps_work(dev_priv, pm_iir); |
660 | spin_lock_irqsave(&dev_priv->rps_lock, flags); | ||
661 | WARN(dev_priv->pm_iir & pm_iir, "Missed a PM interrupt\n"); | ||
662 | dev_priv->pm_iir |= pm_iir; | ||
663 | I915_WRITE(GEN6_PMIMR, dev_priv->pm_iir); | ||
664 | POSTING_READ(GEN6_PMIMR); | ||
665 | spin_unlock_irqrestore(&dev_priv->rps_lock, flags); | ||
666 | queue_work(dev_priv->wq, &dev_priv->rps_work); | ||
667 | } | ||
668 | 677 | ||
669 | /* should clear PCH hotplug event before clear CPU irq */ | 678 | /* should clear PCH hotplug event before clear CPU irq */ |
670 | I915_WRITE(SDEIIR, pch_iir); | 679 | I915_WRITE(SDEIIR, pch_iir); |
@@ -764,25 +773,8 @@ static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS) | |||
764 | i915_handle_rps_change(dev); | 773 | i915_handle_rps_change(dev); |
765 | } | 774 | } |
766 | 775 | ||
767 | if (IS_GEN6(dev) && pm_iir & GEN6_PM_DEFERRED_EVENTS) { | 776 | if (IS_GEN6(dev) && pm_iir & GEN6_PM_DEFERRED_EVENTS) |
768 | /* | 777 | gen6_queue_rps_work(dev_priv, pm_iir); |
769 | * IIR bits should never already be set because IMR should | ||
770 | * prevent an interrupt from being shown in IIR. The warning | ||
771 | * displays a case where we've unsafely cleared | ||
772 | * dev_priv->pm_iir. Although missing an interrupt of the same | ||
773 | * type is not a problem, it displays a problem in the logic. | ||
774 | * | ||
775 | * The mask bit in IMR is cleared by rps_work. | ||
776 | */ | ||
777 | unsigned long flags; | ||
778 | spin_lock_irqsave(&dev_priv->rps_lock, flags); | ||
779 | WARN(dev_priv->pm_iir & pm_iir, "Missed a PM interrupt\n"); | ||
780 | dev_priv->pm_iir |= pm_iir; | ||
781 | I915_WRITE(GEN6_PMIMR, dev_priv->pm_iir); | ||
782 | POSTING_READ(GEN6_PMIMR); | ||
783 | spin_unlock_irqrestore(&dev_priv->rps_lock, flags); | ||
784 | queue_work(dev_priv->wq, &dev_priv->rps_work); | ||
785 | } | ||
786 | 778 | ||
787 | /* should clear PCH hotplug event before clear CPU irq */ | 779 | /* should clear PCH hotplug event before clear CPU irq */ |
788 | I915_WRITE(SDEIIR, pch_iir); | 780 | I915_WRITE(SDEIIR, pch_iir); |
@@ -1376,7 +1368,8 @@ static void i915_pageflip_stall_check(struct drm_device *dev, int pipe) | |||
1376 | obj = work->pending_flip_obj; | 1368 | obj = work->pending_flip_obj; |
1377 | if (INTEL_INFO(dev)->gen >= 4) { | 1369 | if (INTEL_INFO(dev)->gen >= 4) { |
1378 | int dspsurf = DSPSURF(intel_crtc->plane); | 1370 | int dspsurf = DSPSURF(intel_crtc->plane); |
1379 | stall_detected = I915_READ(dspsurf) == obj->gtt_offset; | 1371 | stall_detected = I915_HI_DISPBASE(I915_READ(dspsurf)) == |
1372 | obj->gtt_offset; | ||
1380 | } else { | 1373 | } else { |
1381 | int dspaddr = DSPADDR(intel_crtc->plane); | 1374 | int dspaddr = DSPADDR(intel_crtc->plane); |
1382 | stall_detected = I915_READ(dspaddr) == (obj->gtt_offset + | 1375 | stall_detected = I915_READ(dspaddr) == (obj->gtt_offset + |
@@ -1875,6 +1868,36 @@ static bool kick_ring(struct intel_ring_buffer *ring) | |||
1875 | return false; | 1868 | return false; |
1876 | } | 1869 | } |
1877 | 1870 | ||
1871 | static bool i915_hangcheck_hung(struct drm_device *dev) | ||
1872 | { | ||
1873 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
1874 | |||
1875 | if (dev_priv->hangcheck_count++ > 1) { | ||
1876 | DRM_ERROR("Hangcheck timer elapsed... GPU hung\n"); | ||
1877 | i915_handle_error(dev, true); | ||
1878 | |||
1879 | if (!IS_GEN2(dev)) { | ||
1880 | /* Is the chip hanging on a WAIT_FOR_EVENT? | ||
1881 | * If so we can simply poke the RB_WAIT bit | ||
1882 | * and break the hang. This should work on | ||
1883 | * all but the second generation chipsets. | ||
1884 | */ | ||
1885 | if (kick_ring(&dev_priv->ring[RCS])) | ||
1886 | return false; | ||
1887 | |||
1888 | if (HAS_BSD(dev) && kick_ring(&dev_priv->ring[VCS])) | ||
1889 | return false; | ||
1890 | |||
1891 | if (HAS_BLT(dev) && kick_ring(&dev_priv->ring[BCS])) | ||
1892 | return false; | ||
1893 | } | ||
1894 | |||
1895 | return true; | ||
1896 | } | ||
1897 | |||
1898 | return false; | ||
1899 | } | ||
1900 | |||
1878 | /** | 1901 | /** |
1879 | * This is called when the chip hasn't reported back with completed | 1902 | * This is called when the chip hasn't reported back with completed |
1880 | * batchbuffers in a long time. The first time this is called we simply record | 1903 | * batchbuffers in a long time. The first time this is called we simply record |
@@ -1895,9 +1918,14 @@ void i915_hangcheck_elapsed(unsigned long data) | |||
1895 | if (i915_hangcheck_ring_idle(&dev_priv->ring[RCS], &err) && | 1918 | if (i915_hangcheck_ring_idle(&dev_priv->ring[RCS], &err) && |
1896 | i915_hangcheck_ring_idle(&dev_priv->ring[VCS], &err) && | 1919 | i915_hangcheck_ring_idle(&dev_priv->ring[VCS], &err) && |
1897 | i915_hangcheck_ring_idle(&dev_priv->ring[BCS], &err)) { | 1920 | i915_hangcheck_ring_idle(&dev_priv->ring[BCS], &err)) { |
1898 | dev_priv->hangcheck_count = 0; | 1921 | if (err) { |
1899 | if (err) | 1922 | if (i915_hangcheck_hung(dev)) |
1923 | return; | ||
1924 | |||
1900 | goto repeat; | 1925 | goto repeat; |
1926 | } | ||
1927 | |||
1928 | dev_priv->hangcheck_count = 0; | ||
1901 | return; | 1929 | return; |
1902 | } | 1930 | } |
1903 | 1931 | ||
@@ -1919,30 +1947,8 @@ void i915_hangcheck_elapsed(unsigned long data) | |||
1919 | dev_priv->last_acthd_blt == acthd_blt && | 1947 | dev_priv->last_acthd_blt == acthd_blt && |
1920 | dev_priv->last_instdone == instdone && | 1948 | dev_priv->last_instdone == instdone && |
1921 | dev_priv->last_instdone1 == instdone1) { | 1949 | dev_priv->last_instdone1 == instdone1) { |
1922 | if (dev_priv->hangcheck_count++ > 1) { | 1950 | if (i915_hangcheck_hung(dev)) |
1923 | DRM_ERROR("Hangcheck timer elapsed... GPU hung\n"); | ||
1924 | i915_handle_error(dev, true); | ||
1925 | |||
1926 | if (!IS_GEN2(dev)) { | ||
1927 | /* Is the chip hanging on a WAIT_FOR_EVENT? | ||
1928 | * If so we can simply poke the RB_WAIT bit | ||
1929 | * and break the hang. This should work on | ||
1930 | * all but the second generation chipsets. | ||
1931 | */ | ||
1932 | if (kick_ring(&dev_priv->ring[RCS])) | ||
1933 | goto repeat; | ||
1934 | |||
1935 | if (HAS_BSD(dev) && | ||
1936 | kick_ring(&dev_priv->ring[VCS])) | ||
1937 | goto repeat; | ||
1938 | |||
1939 | if (HAS_BLT(dev) && | ||
1940 | kick_ring(&dev_priv->ring[BCS])) | ||
1941 | goto repeat; | ||
1942 | } | ||
1943 | |||
1944 | return; | 1951 | return; |
1945 | } | ||
1946 | } else { | 1952 | } else { |
1947 | dev_priv->hangcheck_count = 0; | 1953 | dev_priv->hangcheck_count = 0; |
1948 | 1954 | ||
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 6924f44a88df..5ac9837e49a5 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -127,6 +127,13 @@ | |||
127 | #define ECOCHK_PPGTT_CACHE64B (0x3<<3) | 127 | #define ECOCHK_PPGTT_CACHE64B (0x3<<3) |
128 | #define ECOCHK_PPGTT_CACHE4B (0x0<<3) | 128 | #define ECOCHK_PPGTT_CACHE4B (0x0<<3) |
129 | 129 | ||
130 | #define GAC_ECO_BITS 0x14090 | ||
131 | #define ECOBITS_PPGTT_CACHE64B (3<<8) | ||
132 | #define ECOBITS_PPGTT_CACHE4B (0<<8) | ||
133 | |||
134 | #define GAB_CTL 0x24000 | ||
135 | #define GAB_CTL_CONT_AFTER_PAGEFAULT (1<<8) | ||
136 | |||
130 | /* VGA stuff */ | 137 | /* VGA stuff */ |
131 | 138 | ||
132 | #define VGA_ST01_MDA 0x3ba | 139 | #define VGA_ST01_MDA 0x3ba |
@@ -224,6 +231,7 @@ | |||
224 | #define MI_BATCH_NON_SECURE (1) | 231 | #define MI_BATCH_NON_SECURE (1) |
225 | #define MI_BATCH_NON_SECURE_I965 (1<<8) | 232 | #define MI_BATCH_NON_SECURE_I965 (1<<8) |
226 | #define MI_BATCH_BUFFER_START MI_INSTR(0x31, 0) | 233 | #define MI_BATCH_BUFFER_START MI_INSTR(0x31, 0) |
234 | #define MI_BATCH_GTT (2<<6) /* aliased with (1<<7) on gen4 */ | ||
227 | #define MI_SEMAPHORE_MBOX MI_INSTR(0x16, 1) /* gen6+ */ | 235 | #define MI_SEMAPHORE_MBOX MI_INSTR(0x16, 1) /* gen6+ */ |
228 | #define MI_SEMAPHORE_GLOBAL_GTT (1<<22) | 236 | #define MI_SEMAPHORE_GLOBAL_GTT (1<<22) |
229 | #define MI_SEMAPHORE_UPDATE (1<<21) | 237 | #define MI_SEMAPHORE_UPDATE (1<<21) |
@@ -490,6 +498,7 @@ | |||
490 | */ | 498 | */ |
491 | # define _3D_CHICKEN2_WM_READ_PIPELINED (1 << 14) | 499 | # define _3D_CHICKEN2_WM_READ_PIPELINED (1 << 14) |
492 | #define _3D_CHICKEN3 0x02090 | 500 | #define _3D_CHICKEN3 0x02090 |
501 | #define _3D_CHICKEN_SF_DISABLE_FASTCLIP_CULL (1 << 5) | ||
493 | 502 | ||
494 | #define MI_MODE 0x0209c | 503 | #define MI_MODE 0x0209c |
495 | # define VS_TIMER_DISPATCH (1 << 6) | 504 | # define VS_TIMER_DISPATCH (1 << 6) |
@@ -631,6 +640,7 @@ | |||
631 | #define CM0_MASK_SHIFT 16 | 640 | #define CM0_MASK_SHIFT 16 |
632 | #define CM0_IZ_OPT_DISABLE (1<<6) | 641 | #define CM0_IZ_OPT_DISABLE (1<<6) |
633 | #define CM0_ZR_OPT_DISABLE (1<<5) | 642 | #define CM0_ZR_OPT_DISABLE (1<<5) |
643 | #define CM0_STC_EVICT_DISABLE_LRA_SNB (1<<5) | ||
634 | #define CM0_DEPTH_EVICT_DISABLE (1<<4) | 644 | #define CM0_DEPTH_EVICT_DISABLE (1<<4) |
635 | #define CM0_COLOR_EVICT_DISABLE (1<<3) | 645 | #define CM0_COLOR_EVICT_DISABLE (1<<3) |
636 | #define CM0_DEPTH_WRITE_DISABLE (1<<1) | 646 | #define CM0_DEPTH_WRITE_DISABLE (1<<1) |
@@ -682,6 +692,21 @@ | |||
682 | 692 | ||
683 | #define GEN6_BSD_RNCID 0x12198 | 693 | #define GEN6_BSD_RNCID 0x12198 |
684 | 694 | ||
695 | #define GEN7_FF_THREAD_MODE 0x20a0 | ||
696 | #define GEN7_FF_SCHED_MASK 0x0077070 | ||
697 | #define GEN7_FF_TS_SCHED_HS1 (0x5<<16) | ||
698 | #define GEN7_FF_TS_SCHED_HS0 (0x3<<16) | ||
699 | #define GEN7_FF_TS_SCHED_LOAD_BALANCE (0x1<<16) | ||
700 | #define GEN7_FF_TS_SCHED_HW (0x0<<16) /* Default */ | ||
701 | #define GEN7_FF_VS_SCHED_HS1 (0x5<<12) | ||
702 | #define GEN7_FF_VS_SCHED_HS0 (0x3<<12) | ||
703 | #define GEN7_FF_VS_SCHED_LOAD_BALANCE (0x1<<12) /* Default */ | ||
704 | #define GEN7_FF_VS_SCHED_HW (0x0<<12) | ||
705 | #define GEN7_FF_DS_SCHED_HS1 (0x5<<4) | ||
706 | #define GEN7_FF_DS_SCHED_HS0 (0x3<<4) | ||
707 | #define GEN7_FF_DS_SCHED_LOAD_BALANCE (0x1<<4) /* Default */ | ||
708 | #define GEN7_FF_DS_SCHED_HW (0x0<<4) | ||
709 | |||
685 | /* | 710 | /* |
686 | * Framebuffer compression (915+ only) | 711 | * Framebuffer compression (915+ only) |
687 | */ | 712 | */ |
@@ -2860,6 +2885,13 @@ | |||
2860 | #define DSPSURF(plane) _PIPE(plane, _DSPASURF, _DSPBSURF) | 2885 | #define DSPSURF(plane) _PIPE(plane, _DSPASURF, _DSPBSURF) |
2861 | #define DSPTILEOFF(plane) _PIPE(plane, _DSPATILEOFF, _DSPBTILEOFF) | 2886 | #define DSPTILEOFF(plane) _PIPE(plane, _DSPATILEOFF, _DSPBTILEOFF) |
2862 | 2887 | ||
2888 | /* Display/Sprite base address macros */ | ||
2889 | #define DISP_BASEADDR_MASK (0xfffff000) | ||
2890 | #define I915_LO_DISPBASE(val) (val & ~DISP_BASEADDR_MASK) | ||
2891 | #define I915_HI_DISPBASE(val) (val & DISP_BASEADDR_MASK) | ||
2892 | #define I915_MODIFY_DISPBASE(reg, gfx_addr) \ | ||
2893 | (I915_WRITE(reg, gfx_addr | I915_LO_DISPBASE(I915_READ(reg)))) | ||
2894 | |||
2863 | /* VBIOS flags */ | 2895 | /* VBIOS flags */ |
2864 | #define SWF00 0x71410 | 2896 | #define SWF00 0x71410 |
2865 | #define SWF01 0x71414 | 2897 | #define SWF01 0x71414 |
@@ -3648,6 +3680,9 @@ | |||
3648 | #define FDI_LINK_TRAIN_PATTERN_IDLE_CPT (2<<8) | 3680 | #define FDI_LINK_TRAIN_PATTERN_IDLE_CPT (2<<8) |
3649 | #define FDI_LINK_TRAIN_NORMAL_CPT (3<<8) | 3681 | #define FDI_LINK_TRAIN_NORMAL_CPT (3<<8) |
3650 | #define FDI_LINK_TRAIN_PATTERN_MASK_CPT (3<<8) | 3682 | #define FDI_LINK_TRAIN_PATTERN_MASK_CPT (3<<8) |
3683 | /* LPT */ | ||
3684 | #define FDI_PORT_WIDTH_2X_LPT (1<<19) | ||
3685 | #define FDI_PORT_WIDTH_1X_LPT (0<<19) | ||
3651 | 3686 | ||
3652 | #define _FDI_RXA_MISC 0xf0010 | 3687 | #define _FDI_RXA_MISC 0xf0010 |
3653 | #define _FDI_RXB_MISC 0xf1010 | 3688 | #define _FDI_RXB_MISC 0xf1010 |
@@ -3891,6 +3926,10 @@ | |||
3891 | #define GT_FIFO_FREE_ENTRIES 0x120008 | 3926 | #define GT_FIFO_FREE_ENTRIES 0x120008 |
3892 | #define GT_FIFO_NUM_RESERVED_ENTRIES 20 | 3927 | #define GT_FIFO_NUM_RESERVED_ENTRIES 20 |
3893 | 3928 | ||
3929 | #define GEN6_UCGCTL1 0x9400 | ||
3930 | # define GEN6_BLBUNIT_CLOCK_GATE_DISABLE (1 << 5) | ||
3931 | # define GEN6_CSUNIT_CLOCK_GATE_DISABLE (1 << 7) | ||
3932 | |||
3894 | #define GEN6_UCGCTL2 0x9404 | 3933 | #define GEN6_UCGCTL2 0x9404 |
3895 | # define GEN6_RCZUNIT_CLOCK_GATE_DISABLE (1 << 13) | 3934 | # define GEN6_RCZUNIT_CLOCK_GATE_DISABLE (1 << 13) |
3896 | # define GEN6_RCPBUNIT_CLOCK_GATE_DISABLE (1 << 12) | 3935 | # define GEN6_RCPBUNIT_CLOCK_GATE_DISABLE (1 << 12) |
@@ -3970,6 +4009,11 @@ | |||
3970 | GEN6_PM_RP_DOWN_THRESHOLD | \ | 4009 | GEN6_PM_RP_DOWN_THRESHOLD | \ |
3971 | GEN6_PM_RP_DOWN_TIMEOUT) | 4010 | GEN6_PM_RP_DOWN_TIMEOUT) |
3972 | 4011 | ||
4012 | #define GEN6_GT_GFX_RC6_LOCKED 0x138104 | ||
4013 | #define GEN6_GT_GFX_RC6 0x138108 | ||
4014 | #define GEN6_GT_GFX_RC6p 0x13810C | ||
4015 | #define GEN6_GT_GFX_RC6pp 0x138110 | ||
4016 | |||
3973 | #define GEN6_PCODE_MAILBOX 0x138124 | 4017 | #define GEN6_PCODE_MAILBOX 0x138124 |
3974 | #define GEN6_PCODE_READY (1<<31) | 4018 | #define GEN6_PCODE_READY (1<<31) |
3975 | #define GEN6_READ_OC_PARAMS 0xc | 4019 | #define GEN6_READ_OC_PARAMS 0xc |
@@ -4170,6 +4214,10 @@ | |||
4170 | #define WRPLL_PLL_SELECT_SSC (0x01<<28) | 4214 | #define WRPLL_PLL_SELECT_SSC (0x01<<28) |
4171 | #define WRPLL_PLL_SELECT_NON_SCC (0x02<<28) | 4215 | #define WRPLL_PLL_SELECT_NON_SCC (0x02<<28) |
4172 | #define WRPLL_PLL_SELECT_LCPLL_2700 (0x03<<28) | 4216 | #define WRPLL_PLL_SELECT_LCPLL_2700 (0x03<<28) |
4217 | /* WRPLL divider programming */ | ||
4218 | #define WRPLL_DIVIDER_REFERENCE(x) ((x)<<0) | ||
4219 | #define WRPLL_DIVIDER_POST(x) ((x)<<8) | ||
4220 | #define WRPLL_DIVIDER_FEEDBACK(x) ((x)<<16) | ||
4173 | 4221 | ||
4174 | /* Port clock selection */ | 4222 | /* Port clock selection */ |
4175 | #define PORT_CLK_SEL_A 0x46100 | 4223 | #define PORT_CLK_SEL_A 0x46100 |
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 2b5eb229ff2c..0c3e3bf67c28 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
@@ -879,17 +879,7 @@ int i915_restore_state(struct drm_device *dev) | |||
879 | mutex_unlock(&dev->struct_mutex); | 879 | mutex_unlock(&dev->struct_mutex); |
880 | 880 | ||
881 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | 881 | if (drm_core_check_feature(dev, DRIVER_MODESET)) |
882 | intel_init_clock_gating(dev); | 882 | intel_modeset_init_hw(dev); |
883 | |||
884 | if (IS_IRONLAKE_M(dev)) { | ||
885 | ironlake_enable_drps(dev); | ||
886 | intel_init_emon(dev); | ||
887 | } | ||
888 | |||
889 | if (INTEL_INFO(dev)->gen >= 6) { | ||
890 | gen6_enable_rps(dev_priv); | ||
891 | gen6_update_ring_freq(dev_priv); | ||
892 | } | ||
893 | 883 | ||
894 | mutex_lock(&dev->struct_mutex); | 884 | mutex_lock(&dev->struct_mutex); |
895 | 885 | ||
diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c new file mode 100644 index 000000000000..79f83445afa0 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_sysfs.c | |||
@@ -0,0 +1,111 @@ | |||
1 | /* | ||
2 | * Copyright © 2012 Intel Corporation | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice (including the next | ||
12 | * paragraph) shall be included in all copies or substantial portions of the | ||
13 | * Software. | ||
14 | * | ||
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
21 | * IN THE SOFTWARE. | ||
22 | * | ||
23 | * Authors: | ||
24 | * Ben Widawsky <ben@bwidawsk.net> | ||
25 | * | ||
26 | */ | ||
27 | |||
28 | #include <linux/device.h> | ||
29 | #include <linux/module.h> | ||
30 | #include <linux/stat.h> | ||
31 | #include <linux/sysfs.h> | ||
32 | #include "i915_drv.h" | ||
33 | |||
34 | static u32 calc_residency(struct drm_device *dev, const u32 reg) | ||
35 | { | ||
36 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
37 | u64 raw_time; /* 32b value may overflow during fixed point math */ | ||
38 | |||
39 | if (!intel_enable_rc6(dev)) | ||
40 | return 0; | ||
41 | |||
42 | raw_time = I915_READ(reg) * 128ULL; | ||
43 | return DIV_ROUND_UP_ULL(raw_time, 100000); | ||
44 | } | ||
45 | |||
46 | static ssize_t | ||
47 | show_rc6_mask(struct device *dev, struct device_attribute *attr, char *buf) | ||
48 | { | ||
49 | struct drm_minor *dminor = container_of(dev, struct drm_minor, kdev); | ||
50 | return snprintf(buf, PAGE_SIZE, "%x", intel_enable_rc6(dminor->dev)); | ||
51 | } | ||
52 | |||
53 | static ssize_t | ||
54 | show_rc6_ms(struct device *dev, struct device_attribute *attr, char *buf) | ||
55 | { | ||
56 | struct drm_minor *dminor = container_of(dev, struct drm_minor, kdev); | ||
57 | u32 rc6_residency = calc_residency(dminor->dev, GEN6_GT_GFX_RC6); | ||
58 | return snprintf(buf, PAGE_SIZE, "%u", rc6_residency); | ||
59 | } | ||
60 | |||
61 | static ssize_t | ||
62 | show_rc6p_ms(struct device *dev, struct device_attribute *attr, char *buf) | ||
63 | { | ||
64 | struct drm_minor *dminor = container_of(dev, struct drm_minor, kdev); | ||
65 | u32 rc6p_residency = calc_residency(dminor->dev, GEN6_GT_GFX_RC6p); | ||
66 | return snprintf(buf, PAGE_SIZE, "%u", rc6p_residency); | ||
67 | } | ||
68 | |||
69 | static ssize_t | ||
70 | show_rc6pp_ms(struct device *dev, struct device_attribute *attr, char *buf) | ||
71 | { | ||
72 | struct drm_minor *dminor = container_of(dev, struct drm_minor, kdev); | ||
73 | u32 rc6pp_residency = calc_residency(dminor->dev, GEN6_GT_GFX_RC6pp); | ||
74 | return snprintf(buf, PAGE_SIZE, "%u", rc6pp_residency); | ||
75 | } | ||
76 | |||
77 | static DEVICE_ATTR(rc6_enable, S_IRUGO, show_rc6_mask, NULL); | ||
78 | static DEVICE_ATTR(rc6_residency_ms, S_IRUGO, show_rc6_ms, NULL); | ||
79 | static DEVICE_ATTR(rc6p_residency_ms, S_IRUGO, show_rc6p_ms, NULL); | ||
80 | static DEVICE_ATTR(rc6pp_residency_ms, S_IRUGO, show_rc6pp_ms, NULL); | ||
81 | |||
82 | static struct attribute *rc6_attrs[] = { | ||
83 | &dev_attr_rc6_enable.attr, | ||
84 | &dev_attr_rc6_residency_ms.attr, | ||
85 | &dev_attr_rc6p_residency_ms.attr, | ||
86 | &dev_attr_rc6pp_residency_ms.attr, | ||
87 | NULL | ||
88 | }; | ||
89 | |||
90 | static struct attribute_group rc6_attr_group = { | ||
91 | .name = power_group_name, | ||
92 | .attrs = rc6_attrs | ||
93 | }; | ||
94 | |||
95 | void i915_setup_sysfs(struct drm_device *dev) | ||
96 | { | ||
97 | int ret; | ||
98 | |||
99 | /* ILK doesn't have any residency information */ | ||
100 | if (INTEL_INFO(dev)->gen < 6) | ||
101 | return; | ||
102 | |||
103 | ret = sysfs_merge_group(&dev->primary->kdev.kobj, &rc6_attr_group); | ||
104 | if (ret) | ||
105 | DRM_ERROR("sysfs setup failed\n"); | ||
106 | } | ||
107 | |||
108 | void i915_teardown_sysfs(struct drm_device *dev) | ||
109 | { | ||
110 | sysfs_unmerge_group(&dev->primary->kdev.kobj, &rc6_attr_group); | ||
111 | } | ||
diff --git a/drivers/gpu/drm/i915/i915_trace_points.c b/drivers/gpu/drm/i915/i915_trace_points.c index ead876eb6ea0..f1df2bd4ecf4 100644 --- a/drivers/gpu/drm/i915/i915_trace_points.c +++ b/drivers/gpu/drm/i915/i915_trace_points.c | |||
@@ -7,5 +7,7 @@ | |||
7 | 7 | ||
8 | #include "i915_drv.h" | 8 | #include "i915_drv.h" |
9 | 9 | ||
10 | #ifndef __CHECKER__ | ||
10 | #define CREATE_TRACE_POINTS | 11 | #define CREATE_TRACE_POINTS |
11 | #include "i915_trace.h" | 12 | #include "i915_trace.h" |
13 | #endif | ||
diff --git a/drivers/gpu/drm/i915/intel_acpi.c b/drivers/gpu/drm/i915/intel_acpi.c index f152b2a7fc54..f413899475e9 100644 --- a/drivers/gpu/drm/i915/intel_acpi.c +++ b/drivers/gpu/drm/i915/intel_acpi.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <acpi/acpi_drivers.h> | 9 | #include <acpi/acpi_drivers.h> |
10 | 10 | ||
11 | #include "drmP.h" | 11 | #include "drmP.h" |
12 | #include "i915_drv.h" | ||
12 | 13 | ||
13 | #define INTEL_DSM_REVISION_ID 1 /* For Calpella anyway... */ | 14 | #define INTEL_DSM_REVISION_ID 1 /* For Calpella anyway... */ |
14 | 15 | ||
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 70b0f1abf149..0976137ab79a 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -55,18 +55,36 @@ static struct intel_crt *intel_attached_crt(struct drm_connector *connector) | |||
55 | struct intel_crt, base); | 55 | struct intel_crt, base); |
56 | } | 56 | } |
57 | 57 | ||
58 | static void intel_crt_dpms(struct drm_encoder *encoder, int mode) | 58 | static void pch_crt_dpms(struct drm_encoder *encoder, int mode) |
59 | { | 59 | { |
60 | struct drm_device *dev = encoder->dev; | 60 | struct drm_device *dev = encoder->dev; |
61 | struct drm_i915_private *dev_priv = dev->dev_private; | 61 | struct drm_i915_private *dev_priv = dev->dev_private; |
62 | u32 temp, reg; | 62 | u32 temp; |
63 | 63 | ||
64 | if (HAS_PCH_SPLIT(dev)) | 64 | temp = I915_READ(PCH_ADPA); |
65 | reg = PCH_ADPA; | 65 | temp &= ~ADPA_DAC_ENABLE; |
66 | else | 66 | |
67 | reg = ADPA; | 67 | switch (mode) { |
68 | case DRM_MODE_DPMS_ON: | ||
69 | temp |= ADPA_DAC_ENABLE; | ||
70 | break; | ||
71 | case DRM_MODE_DPMS_STANDBY: | ||
72 | case DRM_MODE_DPMS_SUSPEND: | ||
73 | case DRM_MODE_DPMS_OFF: | ||
74 | /* Just leave port enable cleared */ | ||
75 | break; | ||
76 | } | ||
77 | |||
78 | I915_WRITE(PCH_ADPA, temp); | ||
79 | } | ||
68 | 80 | ||
69 | temp = I915_READ(reg); | 81 | static void gmch_crt_dpms(struct drm_encoder *encoder, int mode) |
82 | { | ||
83 | struct drm_device *dev = encoder->dev; | ||
84 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
85 | u32 temp; | ||
86 | |||
87 | temp = I915_READ(ADPA); | ||
70 | temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE); | 88 | temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE); |
71 | temp &= ~ADPA_DAC_ENABLE; | 89 | temp &= ~ADPA_DAC_ENABLE; |
72 | 90 | ||
@@ -85,7 +103,7 @@ static void intel_crt_dpms(struct drm_encoder *encoder, int mode) | |||
85 | break; | 103 | break; |
86 | } | 104 | } |
87 | 105 | ||
88 | I915_WRITE(reg, temp); | 106 | I915_WRITE(ADPA, temp); |
89 | } | 107 | } |
90 | 108 | ||
91 | static int intel_crt_mode_valid(struct drm_connector *connector, | 109 | static int intel_crt_mode_valid(struct drm_connector *connector, |
@@ -516,12 +534,20 @@ static void intel_crt_reset(struct drm_connector *connector) | |||
516 | * Routines for controlling stuff on the analog port | 534 | * Routines for controlling stuff on the analog port |
517 | */ | 535 | */ |
518 | 536 | ||
519 | static const struct drm_encoder_helper_funcs intel_crt_helper_funcs = { | 537 | static const struct drm_encoder_helper_funcs pch_encoder_funcs = { |
520 | .dpms = intel_crt_dpms, | 538 | .mode_fixup = intel_crt_mode_fixup, |
539 | .prepare = intel_encoder_prepare, | ||
540 | .commit = intel_encoder_commit, | ||
541 | .mode_set = intel_crt_mode_set, | ||
542 | .dpms = pch_crt_dpms, | ||
543 | }; | ||
544 | |||
545 | static const struct drm_encoder_helper_funcs gmch_encoder_funcs = { | ||
521 | .mode_fixup = intel_crt_mode_fixup, | 546 | .mode_fixup = intel_crt_mode_fixup, |
522 | .prepare = intel_encoder_prepare, | 547 | .prepare = intel_encoder_prepare, |
523 | .commit = intel_encoder_commit, | 548 | .commit = intel_encoder_commit, |
524 | .mode_set = intel_crt_mode_set, | 549 | .mode_set = intel_crt_mode_set, |
550 | .dpms = gmch_crt_dpms, | ||
525 | }; | 551 | }; |
526 | 552 | ||
527 | static const struct drm_connector_funcs intel_crt_connector_funcs = { | 553 | static const struct drm_connector_funcs intel_crt_connector_funcs = { |
@@ -567,6 +593,7 @@ void intel_crt_init(struct drm_device *dev) | |||
567 | struct intel_crt *crt; | 593 | struct intel_crt *crt; |
568 | struct intel_connector *intel_connector; | 594 | struct intel_connector *intel_connector; |
569 | struct drm_i915_private *dev_priv = dev->dev_private; | 595 | struct drm_i915_private *dev_priv = dev->dev_private; |
596 | const struct drm_encoder_helper_funcs *encoder_helper_funcs; | ||
570 | 597 | ||
571 | /* Skip machines without VGA that falsely report hotplug events */ | 598 | /* Skip machines without VGA that falsely report hotplug events */ |
572 | if (dmi_check_system(intel_no_crt)) | 599 | if (dmi_check_system(intel_no_crt)) |
@@ -602,7 +629,12 @@ void intel_crt_init(struct drm_device *dev) | |||
602 | connector->interlace_allowed = 1; | 629 | connector->interlace_allowed = 1; |
603 | connector->doublescan_allowed = 0; | 630 | connector->doublescan_allowed = 0; |
604 | 631 | ||
605 | drm_encoder_helper_add(&crt->base.base, &intel_crt_helper_funcs); | 632 | if (HAS_PCH_SPLIT(dev)) |
633 | encoder_helper_funcs = &pch_encoder_funcs; | ||
634 | else | ||
635 | encoder_helper_funcs = &gmch_encoder_funcs; | ||
636 | |||
637 | drm_encoder_helper_add(&crt->base.base, encoder_helper_funcs); | ||
606 | drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs); | 638 | drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs); |
607 | 639 | ||
608 | drm_sysfs_connector_add(connector); | 640 | drm_sysfs_connector_add(connector); |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 37514a52b05c..4c844c68ec80 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -25,7 +25,6 @@ | |||
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include <linux/dmi.h> | 27 | #include <linux/dmi.h> |
28 | #include <linux/cpufreq.h> | ||
29 | #include <linux/module.h> | 28 | #include <linux/module.h> |
30 | #include <linux/input.h> | 29 | #include <linux/input.h> |
31 | #include <linux/i2c.h> | 30 | #include <linux/i2c.h> |
@@ -45,7 +44,6 @@ | |||
45 | #define HAS_eDP (intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) | 44 | #define HAS_eDP (intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) |
46 | 45 | ||
47 | bool intel_pipe_has_type(struct drm_crtc *crtc, int type); | 46 | bool intel_pipe_has_type(struct drm_crtc *crtc, int type); |
48 | static void intel_update_watermarks(struct drm_device *dev); | ||
49 | static void intel_increase_pllclock(struct drm_crtc *crtc); | 47 | static void intel_increase_pllclock(struct drm_crtc *crtc); |
50 | static void intel_crtc_update_cursor(struct drm_crtc *crtc, bool on); | 48 | static void intel_crtc_update_cursor(struct drm_crtc *crtc, bool on); |
51 | 49 | ||
@@ -1517,7 +1515,7 @@ static void intel_disable_pipe(struct drm_i915_private *dev_priv, | |||
1517 | * Plane regs are double buffered, going from enabled->disabled needs a | 1515 | * Plane regs are double buffered, going from enabled->disabled needs a |
1518 | * trigger in order to latch. The display address reg provides this. | 1516 | * trigger in order to latch. The display address reg provides this. |
1519 | */ | 1517 | */ |
1520 | static void intel_flush_display_plane(struct drm_i915_private *dev_priv, | 1518 | void intel_flush_display_plane(struct drm_i915_private *dev_priv, |
1521 | enum plane plane) | 1519 | enum plane plane) |
1522 | { | 1520 | { |
1523 | I915_WRITE(DSPADDR(plane), I915_READ(DSPADDR(plane))); | 1521 | I915_WRITE(DSPADDR(plane), I915_READ(DSPADDR(plane))); |
@@ -1628,490 +1626,6 @@ static void intel_disable_pch_ports(struct drm_i915_private *dev_priv, | |||
1628 | disable_pch_hdmi(dev_priv, pipe, HDMID); | 1626 | disable_pch_hdmi(dev_priv, pipe, HDMID); |
1629 | } | 1627 | } |
1630 | 1628 | ||
1631 | static void i8xx_disable_fbc(struct drm_device *dev) | ||
1632 | { | ||
1633 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1634 | u32 fbc_ctl; | ||
1635 | |||
1636 | /* Disable compression */ | ||
1637 | fbc_ctl = I915_READ(FBC_CONTROL); | ||
1638 | if ((fbc_ctl & FBC_CTL_EN) == 0) | ||
1639 | return; | ||
1640 | |||
1641 | fbc_ctl &= ~FBC_CTL_EN; | ||
1642 | I915_WRITE(FBC_CONTROL, fbc_ctl); | ||
1643 | |||
1644 | /* Wait for compressing bit to clear */ | ||
1645 | if (wait_for((I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) == 0, 10)) { | ||
1646 | DRM_DEBUG_KMS("FBC idle timed out\n"); | ||
1647 | return; | ||
1648 | } | ||
1649 | |||
1650 | DRM_DEBUG_KMS("disabled FBC\n"); | ||
1651 | } | ||
1652 | |||
1653 | static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | ||
1654 | { | ||
1655 | struct drm_device *dev = crtc->dev; | ||
1656 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1657 | struct drm_framebuffer *fb = crtc->fb; | ||
1658 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); | ||
1659 | struct drm_i915_gem_object *obj = intel_fb->obj; | ||
1660 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
1661 | int cfb_pitch; | ||
1662 | int plane, i; | ||
1663 | u32 fbc_ctl, fbc_ctl2; | ||
1664 | |||
1665 | cfb_pitch = dev_priv->cfb_size / FBC_LL_SIZE; | ||
1666 | if (fb->pitches[0] < cfb_pitch) | ||
1667 | cfb_pitch = fb->pitches[0]; | ||
1668 | |||
1669 | /* FBC_CTL wants 64B units */ | ||
1670 | cfb_pitch = (cfb_pitch / 64) - 1; | ||
1671 | plane = intel_crtc->plane == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB; | ||
1672 | |||
1673 | /* Clear old tags */ | ||
1674 | for (i = 0; i < (FBC_LL_SIZE / 32) + 1; i++) | ||
1675 | I915_WRITE(FBC_TAG + (i * 4), 0); | ||
1676 | |||
1677 | /* Set it up... */ | ||
1678 | fbc_ctl2 = FBC_CTL_FENCE_DBL | FBC_CTL_IDLE_IMM | FBC_CTL_CPU_FENCE; | ||
1679 | fbc_ctl2 |= plane; | ||
1680 | I915_WRITE(FBC_CONTROL2, fbc_ctl2); | ||
1681 | I915_WRITE(FBC_FENCE_OFF, crtc->y); | ||
1682 | |||
1683 | /* enable it... */ | ||
1684 | fbc_ctl = FBC_CTL_EN | FBC_CTL_PERIODIC; | ||
1685 | if (IS_I945GM(dev)) | ||
1686 | fbc_ctl |= FBC_CTL_C3_IDLE; /* 945 needs special SR handling */ | ||
1687 | fbc_ctl |= (cfb_pitch & 0xff) << FBC_CTL_STRIDE_SHIFT; | ||
1688 | fbc_ctl |= (interval & 0x2fff) << FBC_CTL_INTERVAL_SHIFT; | ||
1689 | fbc_ctl |= obj->fence_reg; | ||
1690 | I915_WRITE(FBC_CONTROL, fbc_ctl); | ||
1691 | |||
1692 | DRM_DEBUG_KMS("enabled FBC, pitch %d, yoff %d, plane %d, ", | ||
1693 | cfb_pitch, crtc->y, intel_crtc->plane); | ||
1694 | } | ||
1695 | |||
1696 | static bool i8xx_fbc_enabled(struct drm_device *dev) | ||
1697 | { | ||
1698 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1699 | |||
1700 | return I915_READ(FBC_CONTROL) & FBC_CTL_EN; | ||
1701 | } | ||
1702 | |||
1703 | static void g4x_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | ||
1704 | { | ||
1705 | struct drm_device *dev = crtc->dev; | ||
1706 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1707 | struct drm_framebuffer *fb = crtc->fb; | ||
1708 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); | ||
1709 | struct drm_i915_gem_object *obj = intel_fb->obj; | ||
1710 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
1711 | int plane = intel_crtc->plane == 0 ? DPFC_CTL_PLANEA : DPFC_CTL_PLANEB; | ||
1712 | unsigned long stall_watermark = 200; | ||
1713 | u32 dpfc_ctl; | ||
1714 | |||
1715 | dpfc_ctl = plane | DPFC_SR_EN | DPFC_CTL_LIMIT_1X; | ||
1716 | dpfc_ctl |= DPFC_CTL_FENCE_EN | obj->fence_reg; | ||
1717 | I915_WRITE(DPFC_CHICKEN, DPFC_HT_MODIFY); | ||
1718 | |||
1719 | I915_WRITE(DPFC_RECOMP_CTL, DPFC_RECOMP_STALL_EN | | ||
1720 | (stall_watermark << DPFC_RECOMP_STALL_WM_SHIFT) | | ||
1721 | (interval << DPFC_RECOMP_TIMER_COUNT_SHIFT)); | ||
1722 | I915_WRITE(DPFC_FENCE_YOFF, crtc->y); | ||
1723 | |||
1724 | /* enable it... */ | ||
1725 | I915_WRITE(DPFC_CONTROL, I915_READ(DPFC_CONTROL) | DPFC_CTL_EN); | ||
1726 | |||
1727 | DRM_DEBUG_KMS("enabled fbc on plane %d\n", intel_crtc->plane); | ||
1728 | } | ||
1729 | |||
1730 | static void g4x_disable_fbc(struct drm_device *dev) | ||
1731 | { | ||
1732 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1733 | u32 dpfc_ctl; | ||
1734 | |||
1735 | /* Disable compression */ | ||
1736 | dpfc_ctl = I915_READ(DPFC_CONTROL); | ||
1737 | if (dpfc_ctl & DPFC_CTL_EN) { | ||
1738 | dpfc_ctl &= ~DPFC_CTL_EN; | ||
1739 | I915_WRITE(DPFC_CONTROL, dpfc_ctl); | ||
1740 | |||
1741 | DRM_DEBUG_KMS("disabled FBC\n"); | ||
1742 | } | ||
1743 | } | ||
1744 | |||
1745 | static bool g4x_fbc_enabled(struct drm_device *dev) | ||
1746 | { | ||
1747 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1748 | |||
1749 | return I915_READ(DPFC_CONTROL) & DPFC_CTL_EN; | ||
1750 | } | ||
1751 | |||
1752 | static void sandybridge_blit_fbc_update(struct drm_device *dev) | ||
1753 | { | ||
1754 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1755 | u32 blt_ecoskpd; | ||
1756 | |||
1757 | /* Make sure blitter notifies FBC of writes */ | ||
1758 | gen6_gt_force_wake_get(dev_priv); | ||
1759 | blt_ecoskpd = I915_READ(GEN6_BLITTER_ECOSKPD); | ||
1760 | blt_ecoskpd |= GEN6_BLITTER_FBC_NOTIFY << | ||
1761 | GEN6_BLITTER_LOCK_SHIFT; | ||
1762 | I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd); | ||
1763 | blt_ecoskpd |= GEN6_BLITTER_FBC_NOTIFY; | ||
1764 | I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd); | ||
1765 | blt_ecoskpd &= ~(GEN6_BLITTER_FBC_NOTIFY << | ||
1766 | GEN6_BLITTER_LOCK_SHIFT); | ||
1767 | I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd); | ||
1768 | POSTING_READ(GEN6_BLITTER_ECOSKPD); | ||
1769 | gen6_gt_force_wake_put(dev_priv); | ||
1770 | } | ||
1771 | |||
1772 | static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | ||
1773 | { | ||
1774 | struct drm_device *dev = crtc->dev; | ||
1775 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1776 | struct drm_framebuffer *fb = crtc->fb; | ||
1777 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); | ||
1778 | struct drm_i915_gem_object *obj = intel_fb->obj; | ||
1779 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
1780 | int plane = intel_crtc->plane == 0 ? DPFC_CTL_PLANEA : DPFC_CTL_PLANEB; | ||
1781 | unsigned long stall_watermark = 200; | ||
1782 | u32 dpfc_ctl; | ||
1783 | |||
1784 | dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); | ||
1785 | dpfc_ctl &= DPFC_RESERVED; | ||
1786 | dpfc_ctl |= (plane | DPFC_CTL_LIMIT_1X); | ||
1787 | /* Set persistent mode for front-buffer rendering, ala X. */ | ||
1788 | dpfc_ctl |= DPFC_CTL_PERSISTENT_MODE; | ||
1789 | dpfc_ctl |= (DPFC_CTL_FENCE_EN | obj->fence_reg); | ||
1790 | I915_WRITE(ILK_DPFC_CHICKEN, DPFC_HT_MODIFY); | ||
1791 | |||
1792 | I915_WRITE(ILK_DPFC_RECOMP_CTL, DPFC_RECOMP_STALL_EN | | ||
1793 | (stall_watermark << DPFC_RECOMP_STALL_WM_SHIFT) | | ||
1794 | (interval << DPFC_RECOMP_TIMER_COUNT_SHIFT)); | ||
1795 | I915_WRITE(ILK_DPFC_FENCE_YOFF, crtc->y); | ||
1796 | I915_WRITE(ILK_FBC_RT_BASE, obj->gtt_offset | ILK_FBC_RT_VALID); | ||
1797 | /* enable it... */ | ||
1798 | I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN); | ||
1799 | |||
1800 | if (IS_GEN6(dev)) { | ||
1801 | I915_WRITE(SNB_DPFC_CTL_SA, | ||
1802 | SNB_CPU_FENCE_ENABLE | obj->fence_reg); | ||
1803 | I915_WRITE(DPFC_CPU_FENCE_OFFSET, crtc->y); | ||
1804 | sandybridge_blit_fbc_update(dev); | ||
1805 | } | ||
1806 | |||
1807 | DRM_DEBUG_KMS("enabled fbc on plane %d\n", intel_crtc->plane); | ||
1808 | } | ||
1809 | |||
1810 | static void ironlake_disable_fbc(struct drm_device *dev) | ||
1811 | { | ||
1812 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1813 | u32 dpfc_ctl; | ||
1814 | |||
1815 | /* Disable compression */ | ||
1816 | dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); | ||
1817 | if (dpfc_ctl & DPFC_CTL_EN) { | ||
1818 | dpfc_ctl &= ~DPFC_CTL_EN; | ||
1819 | I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl); | ||
1820 | |||
1821 | DRM_DEBUG_KMS("disabled FBC\n"); | ||
1822 | } | ||
1823 | } | ||
1824 | |||
1825 | static bool ironlake_fbc_enabled(struct drm_device *dev) | ||
1826 | { | ||
1827 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1828 | |||
1829 | return I915_READ(ILK_DPFC_CONTROL) & DPFC_CTL_EN; | ||
1830 | } | ||
1831 | |||
1832 | bool intel_fbc_enabled(struct drm_device *dev) | ||
1833 | { | ||
1834 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1835 | |||
1836 | if (!dev_priv->display.fbc_enabled) | ||
1837 | return false; | ||
1838 | |||
1839 | return dev_priv->display.fbc_enabled(dev); | ||
1840 | } | ||
1841 | |||
1842 | static void intel_fbc_work_fn(struct work_struct *__work) | ||
1843 | { | ||
1844 | struct intel_fbc_work *work = | ||
1845 | container_of(to_delayed_work(__work), | ||
1846 | struct intel_fbc_work, work); | ||
1847 | struct drm_device *dev = work->crtc->dev; | ||
1848 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1849 | |||
1850 | mutex_lock(&dev->struct_mutex); | ||
1851 | if (work == dev_priv->fbc_work) { | ||
1852 | /* Double check that we haven't switched fb without cancelling | ||
1853 | * the prior work. | ||
1854 | */ | ||
1855 | if (work->crtc->fb == work->fb) { | ||
1856 | dev_priv->display.enable_fbc(work->crtc, | ||
1857 | work->interval); | ||
1858 | |||
1859 | dev_priv->cfb_plane = to_intel_crtc(work->crtc)->plane; | ||
1860 | dev_priv->cfb_fb = work->crtc->fb->base.id; | ||
1861 | dev_priv->cfb_y = work->crtc->y; | ||
1862 | } | ||
1863 | |||
1864 | dev_priv->fbc_work = NULL; | ||
1865 | } | ||
1866 | mutex_unlock(&dev->struct_mutex); | ||
1867 | |||
1868 | kfree(work); | ||
1869 | } | ||
1870 | |||
1871 | static void intel_cancel_fbc_work(struct drm_i915_private *dev_priv) | ||
1872 | { | ||
1873 | if (dev_priv->fbc_work == NULL) | ||
1874 | return; | ||
1875 | |||
1876 | DRM_DEBUG_KMS("cancelling pending FBC enable\n"); | ||
1877 | |||
1878 | /* Synchronisation is provided by struct_mutex and checking of | ||
1879 | * dev_priv->fbc_work, so we can perform the cancellation | ||
1880 | * entirely asynchronously. | ||
1881 | */ | ||
1882 | if (cancel_delayed_work(&dev_priv->fbc_work->work)) | ||
1883 | /* tasklet was killed before being run, clean up */ | ||
1884 | kfree(dev_priv->fbc_work); | ||
1885 | |||
1886 | /* Mark the work as no longer wanted so that if it does | ||
1887 | * wake-up (because the work was already running and waiting | ||
1888 | * for our mutex), it will discover that is no longer | ||
1889 | * necessary to run. | ||
1890 | */ | ||
1891 | dev_priv->fbc_work = NULL; | ||
1892 | } | ||
1893 | |||
1894 | static void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | ||
1895 | { | ||
1896 | struct intel_fbc_work *work; | ||
1897 | struct drm_device *dev = crtc->dev; | ||
1898 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1899 | |||
1900 | if (!dev_priv->display.enable_fbc) | ||
1901 | return; | ||
1902 | |||
1903 | intel_cancel_fbc_work(dev_priv); | ||
1904 | |||
1905 | work = kzalloc(sizeof *work, GFP_KERNEL); | ||
1906 | if (work == NULL) { | ||
1907 | dev_priv->display.enable_fbc(crtc, interval); | ||
1908 | return; | ||
1909 | } | ||
1910 | |||
1911 | work->crtc = crtc; | ||
1912 | work->fb = crtc->fb; | ||
1913 | work->interval = interval; | ||
1914 | INIT_DELAYED_WORK(&work->work, intel_fbc_work_fn); | ||
1915 | |||
1916 | dev_priv->fbc_work = work; | ||
1917 | |||
1918 | DRM_DEBUG_KMS("scheduling delayed FBC enable\n"); | ||
1919 | |||
1920 | /* Delay the actual enabling to let pageflipping cease and the | ||
1921 | * display to settle before starting the compression. Note that | ||
1922 | * this delay also serves a second purpose: it allows for a | ||
1923 | * vblank to pass after disabling the FBC before we attempt | ||
1924 | * to modify the control registers. | ||
1925 | * | ||
1926 | * A more complicated solution would involve tracking vblanks | ||
1927 | * following the termination of the page-flipping sequence | ||
1928 | * and indeed performing the enable as a co-routine and not | ||
1929 | * waiting synchronously upon the vblank. | ||
1930 | */ | ||
1931 | schedule_delayed_work(&work->work, msecs_to_jiffies(50)); | ||
1932 | } | ||
1933 | |||
1934 | void intel_disable_fbc(struct drm_device *dev) | ||
1935 | { | ||
1936 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1937 | |||
1938 | intel_cancel_fbc_work(dev_priv); | ||
1939 | |||
1940 | if (!dev_priv->display.disable_fbc) | ||
1941 | return; | ||
1942 | |||
1943 | dev_priv->display.disable_fbc(dev); | ||
1944 | dev_priv->cfb_plane = -1; | ||
1945 | } | ||
1946 | |||
1947 | /** | ||
1948 | * intel_update_fbc - enable/disable FBC as needed | ||
1949 | * @dev: the drm_device | ||
1950 | * | ||
1951 | * Set up the framebuffer compression hardware at mode set time. We | ||
1952 | * enable it if possible: | ||
1953 | * - plane A only (on pre-965) | ||
1954 | * - no pixel mulitply/line duplication | ||
1955 | * - no alpha buffer discard | ||
1956 | * - no dual wide | ||
1957 | * - framebuffer <= 2048 in width, 1536 in height | ||
1958 | * | ||
1959 | * We can't assume that any compression will take place (worst case), | ||
1960 | * so the compressed buffer has to be the same size as the uncompressed | ||
1961 | * one. It also must reside (along with the line length buffer) in | ||
1962 | * stolen memory. | ||
1963 | * | ||
1964 | * We need to enable/disable FBC on a global basis. | ||
1965 | */ | ||
1966 | static void intel_update_fbc(struct drm_device *dev) | ||
1967 | { | ||
1968 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1969 | struct drm_crtc *crtc = NULL, *tmp_crtc; | ||
1970 | struct intel_crtc *intel_crtc; | ||
1971 | struct drm_framebuffer *fb; | ||
1972 | struct intel_framebuffer *intel_fb; | ||
1973 | struct drm_i915_gem_object *obj; | ||
1974 | int enable_fbc; | ||
1975 | |||
1976 | DRM_DEBUG_KMS("\n"); | ||
1977 | |||
1978 | if (!i915_powersave) | ||
1979 | return; | ||
1980 | |||
1981 | if (!I915_HAS_FBC(dev)) | ||
1982 | return; | ||
1983 | |||
1984 | /* | ||
1985 | * If FBC is already on, we just have to verify that we can | ||
1986 | * keep it that way... | ||
1987 | * Need to disable if: | ||
1988 | * - more than one pipe is active | ||
1989 | * - changing FBC params (stride, fence, mode) | ||
1990 | * - new fb is too large to fit in compressed buffer | ||
1991 | * - going to an unsupported config (interlace, pixel multiply, etc.) | ||
1992 | */ | ||
1993 | list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head) { | ||
1994 | if (tmp_crtc->enabled && tmp_crtc->fb) { | ||
1995 | if (crtc) { | ||
1996 | DRM_DEBUG_KMS("more than one pipe active, disabling compression\n"); | ||
1997 | dev_priv->no_fbc_reason = FBC_MULTIPLE_PIPES; | ||
1998 | goto out_disable; | ||
1999 | } | ||
2000 | crtc = tmp_crtc; | ||
2001 | } | ||
2002 | } | ||
2003 | |||
2004 | if (!crtc || crtc->fb == NULL) { | ||
2005 | DRM_DEBUG_KMS("no output, disabling\n"); | ||
2006 | dev_priv->no_fbc_reason = FBC_NO_OUTPUT; | ||
2007 | goto out_disable; | ||
2008 | } | ||
2009 | |||
2010 | intel_crtc = to_intel_crtc(crtc); | ||
2011 | fb = crtc->fb; | ||
2012 | intel_fb = to_intel_framebuffer(fb); | ||
2013 | obj = intel_fb->obj; | ||
2014 | |||
2015 | enable_fbc = i915_enable_fbc; | ||
2016 | if (enable_fbc < 0) { | ||
2017 | DRM_DEBUG_KMS("fbc set to per-chip default\n"); | ||
2018 | enable_fbc = 1; | ||
2019 | if (INTEL_INFO(dev)->gen <= 6) | ||
2020 | enable_fbc = 0; | ||
2021 | } | ||
2022 | if (!enable_fbc) { | ||
2023 | DRM_DEBUG_KMS("fbc disabled per module param\n"); | ||
2024 | dev_priv->no_fbc_reason = FBC_MODULE_PARAM; | ||
2025 | goto out_disable; | ||
2026 | } | ||
2027 | if (intel_fb->obj->base.size > dev_priv->cfb_size) { | ||
2028 | DRM_DEBUG_KMS("framebuffer too large, disabling " | ||
2029 | "compression\n"); | ||
2030 | dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL; | ||
2031 | goto out_disable; | ||
2032 | } | ||
2033 | if ((crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) || | ||
2034 | (crtc->mode.flags & DRM_MODE_FLAG_DBLSCAN)) { | ||
2035 | DRM_DEBUG_KMS("mode incompatible with compression, " | ||
2036 | "disabling\n"); | ||
2037 | dev_priv->no_fbc_reason = FBC_UNSUPPORTED_MODE; | ||
2038 | goto out_disable; | ||
2039 | } | ||
2040 | if ((crtc->mode.hdisplay > 2048) || | ||
2041 | (crtc->mode.vdisplay > 1536)) { | ||
2042 | DRM_DEBUG_KMS("mode too large for compression, disabling\n"); | ||
2043 | dev_priv->no_fbc_reason = FBC_MODE_TOO_LARGE; | ||
2044 | goto out_disable; | ||
2045 | } | ||
2046 | if ((IS_I915GM(dev) || IS_I945GM(dev)) && intel_crtc->plane != 0) { | ||
2047 | DRM_DEBUG_KMS("plane not 0, disabling compression\n"); | ||
2048 | dev_priv->no_fbc_reason = FBC_BAD_PLANE; | ||
2049 | goto out_disable; | ||
2050 | } | ||
2051 | |||
2052 | /* The use of a CPU fence is mandatory in order to detect writes | ||
2053 | * by the CPU to the scanout and trigger updates to the FBC. | ||
2054 | */ | ||
2055 | if (obj->tiling_mode != I915_TILING_X || | ||
2056 | obj->fence_reg == I915_FENCE_REG_NONE) { | ||
2057 | DRM_DEBUG_KMS("framebuffer not tiled or fenced, disabling compression\n"); | ||
2058 | dev_priv->no_fbc_reason = FBC_NOT_TILED; | ||
2059 | goto out_disable; | ||
2060 | } | ||
2061 | |||
2062 | /* If the kernel debugger is active, always disable compression */ | ||
2063 | if (in_dbg_master()) | ||
2064 | goto out_disable; | ||
2065 | |||
2066 | /* If the scanout has not changed, don't modify the FBC settings. | ||
2067 | * Note that we make the fundamental assumption that the fb->obj | ||
2068 | * cannot be unpinned (and have its GTT offset and fence revoked) | ||
2069 | * without first being decoupled from the scanout and FBC disabled. | ||
2070 | */ | ||
2071 | if (dev_priv->cfb_plane == intel_crtc->plane && | ||
2072 | dev_priv->cfb_fb == fb->base.id && | ||
2073 | dev_priv->cfb_y == crtc->y) | ||
2074 | return; | ||
2075 | |||
2076 | if (intel_fbc_enabled(dev)) { | ||
2077 | /* We update FBC along two paths, after changing fb/crtc | ||
2078 | * configuration (modeswitching) and after page-flipping | ||
2079 | * finishes. For the latter, we know that not only did | ||
2080 | * we disable the FBC at the start of the page-flip | ||
2081 | * sequence, but also more than one vblank has passed. | ||
2082 | * | ||
2083 | * For the former case of modeswitching, it is possible | ||
2084 | * to switch between two FBC valid configurations | ||
2085 | * instantaneously so we do need to disable the FBC | ||
2086 | * before we can modify its control registers. We also | ||
2087 | * have to wait for the next vblank for that to take | ||
2088 | * effect. However, since we delay enabling FBC we can | ||
2089 | * assume that a vblank has passed since disabling and | ||
2090 | * that we can safely alter the registers in the deferred | ||
2091 | * callback. | ||
2092 | * | ||
2093 | * In the scenario that we go from a valid to invalid | ||
2094 | * and then back to valid FBC configuration we have | ||
2095 | * no strict enforcement that a vblank occurred since | ||
2096 | * disabling the FBC. However, along all current pipe | ||
2097 | * disabling paths we do need to wait for a vblank at | ||
2098 | * some point. And we wait before enabling FBC anyway. | ||
2099 | */ | ||
2100 | DRM_DEBUG_KMS("disabling active FBC for update\n"); | ||
2101 | intel_disable_fbc(dev); | ||
2102 | } | ||
2103 | |||
2104 | intel_enable_fbc(crtc, 500); | ||
2105 | return; | ||
2106 | |||
2107 | out_disable: | ||
2108 | /* Multiple disables should be harmless */ | ||
2109 | if (intel_fbc_enabled(dev)) { | ||
2110 | DRM_DEBUG_KMS("unsupported config, disabling FBC\n"); | ||
2111 | intel_disable_fbc(dev); | ||
2112 | } | ||
2113 | } | ||
2114 | |||
2115 | int | 1629 | int |
2116 | intel_pin_and_fence_fb_obj(struct drm_device *dev, | 1630 | intel_pin_and_fence_fb_obj(struct drm_device *dev, |
2117 | struct drm_i915_gem_object *obj, | 1631 | struct drm_i915_gem_object *obj, |
@@ -2152,13 +1666,11 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, | |||
2152 | * framebuffer compression. For simplicity, we always install | 1666 | * framebuffer compression. For simplicity, we always install |
2153 | * a fence as the cost is not that onerous. | 1667 | * a fence as the cost is not that onerous. |
2154 | */ | 1668 | */ |
2155 | if (obj->tiling_mode != I915_TILING_NONE) { | 1669 | ret = i915_gem_object_get_fence(obj); |
2156 | ret = i915_gem_object_get_fence(obj, pipelined); | 1670 | if (ret) |
2157 | if (ret) | 1671 | goto err_unpin; |
2158 | goto err_unpin; | ||
2159 | 1672 | ||
2160 | i915_gem_object_pin_fence(obj); | 1673 | i915_gem_object_pin_fence(obj); |
2161 | } | ||
2162 | 1674 | ||
2163 | dev_priv->mm.interruptible = true; | 1675 | dev_priv->mm.interruptible = true; |
2164 | return 0; | 1676 | return 0; |
@@ -2239,7 +1751,7 @@ static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb, | |||
2239 | Start, Offset, x, y, fb->pitches[0]); | 1751 | Start, Offset, x, y, fb->pitches[0]); |
2240 | I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]); | 1752 | I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]); |
2241 | if (INTEL_INFO(dev)->gen >= 4) { | 1753 | if (INTEL_INFO(dev)->gen >= 4) { |
2242 | I915_WRITE(DSPSURF(plane), Start); | 1754 | I915_MODIFY_DISPBASE(DSPSURF(plane), Start); |
2243 | I915_WRITE(DSPTILEOFF(plane), (y << 16) | x); | 1755 | I915_WRITE(DSPTILEOFF(plane), (y << 16) | x); |
2244 | I915_WRITE(DSPADDR(plane), Offset); | 1756 | I915_WRITE(DSPADDR(plane), Offset); |
2245 | } else | 1757 | } else |
@@ -2319,7 +1831,7 @@ static int ironlake_update_plane(struct drm_crtc *crtc, | |||
2319 | DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n", | 1831 | DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n", |
2320 | Start, Offset, x, y, fb->pitches[0]); | 1832 | Start, Offset, x, y, fb->pitches[0]); |
2321 | I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]); | 1833 | I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]); |
2322 | I915_WRITE(DSPSURF(plane), Start); | 1834 | I915_MODIFY_DISPBASE(DSPSURF(plane), Start); |
2323 | I915_WRITE(DSPTILEOFF(plane), (y << 16) | x); | 1835 | I915_WRITE(DSPTILEOFF(plane), (y << 16) | x); |
2324 | I915_WRITE(DSPADDR(plane), Offset); | 1836 | I915_WRITE(DSPADDR(plane), Offset); |
2325 | POSTING_READ(reg); | 1837 | POSTING_READ(reg); |
@@ -2334,16 +1846,39 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, | |||
2334 | { | 1846 | { |
2335 | struct drm_device *dev = crtc->dev; | 1847 | struct drm_device *dev = crtc->dev; |
2336 | struct drm_i915_private *dev_priv = dev->dev_private; | 1848 | struct drm_i915_private *dev_priv = dev->dev_private; |
1849 | |||
1850 | if (dev_priv->display.disable_fbc) | ||
1851 | dev_priv->display.disable_fbc(dev); | ||
1852 | intel_increase_pllclock(crtc); | ||
1853 | |||
1854 | return dev_priv->display.update_plane(crtc, fb, x, y); | ||
1855 | } | ||
1856 | |||
1857 | static int | ||
1858 | intel_finish_fb(struct drm_framebuffer *old_fb) | ||
1859 | { | ||
1860 | struct drm_i915_gem_object *obj = to_intel_framebuffer(old_fb)->obj; | ||
1861 | struct drm_i915_private *dev_priv = obj->base.dev->dev_private; | ||
1862 | bool was_interruptible = dev_priv->mm.interruptible; | ||
2337 | int ret; | 1863 | int ret; |
2338 | 1864 | ||
2339 | ret = dev_priv->display.update_plane(crtc, fb, x, y); | 1865 | wait_event(dev_priv->pending_flip_queue, |
2340 | if (ret) | 1866 | atomic_read(&dev_priv->mm.wedged) || |
2341 | return ret; | 1867 | atomic_read(&obj->pending_flip) == 0); |
2342 | 1868 | ||
2343 | intel_update_fbc(dev); | 1869 | /* Big Hammer, we also need to ensure that any pending |
2344 | intel_increase_pllclock(crtc); | 1870 | * MI_WAIT_FOR_EVENT inside a user batch buffer on the |
1871 | * current scanout is retired before unpinning the old | ||
1872 | * framebuffer. | ||
1873 | * | ||
1874 | * This should only fail upon a hung GPU, in which case we | ||
1875 | * can safely continue. | ||
1876 | */ | ||
1877 | dev_priv->mm.interruptible = false; | ||
1878 | ret = i915_gem_object_finish_gpu(obj); | ||
1879 | dev_priv->mm.interruptible = was_interruptible; | ||
2345 | 1880 | ||
2346 | return 0; | 1881 | return ret; |
2347 | } | 1882 | } |
2348 | 1883 | ||
2349 | static int | 1884 | static int |
@@ -2351,6 +1886,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
2351 | struct drm_framebuffer *old_fb) | 1886 | struct drm_framebuffer *old_fb) |
2352 | { | 1887 | { |
2353 | struct drm_device *dev = crtc->dev; | 1888 | struct drm_device *dev = crtc->dev; |
1889 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2354 | struct drm_i915_master_private *master_priv; | 1890 | struct drm_i915_master_private *master_priv; |
2355 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 1891 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
2356 | int ret; | 1892 | int ret; |
@@ -2384,28 +1920,10 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
2384 | return ret; | 1920 | return ret; |
2385 | } | 1921 | } |
2386 | 1922 | ||
2387 | if (old_fb) { | 1923 | if (old_fb) |
2388 | struct drm_i915_private *dev_priv = dev->dev_private; | 1924 | intel_finish_fb(old_fb); |
2389 | struct drm_i915_gem_object *obj = to_intel_framebuffer(old_fb)->obj; | ||
2390 | |||
2391 | wait_event(dev_priv->pending_flip_queue, | ||
2392 | atomic_read(&dev_priv->mm.wedged) || | ||
2393 | atomic_read(&obj->pending_flip) == 0); | ||
2394 | |||
2395 | /* Big Hammer, we also need to ensure that any pending | ||
2396 | * MI_WAIT_FOR_EVENT inside a user batch buffer on the | ||
2397 | * current scanout is retired before unpinning the old | ||
2398 | * framebuffer. | ||
2399 | * | ||
2400 | * This should only fail upon a hung GPU, in which case we | ||
2401 | * can safely continue. | ||
2402 | */ | ||
2403 | ret = i915_gem_object_finish_gpu(obj); | ||
2404 | (void) ret; | ||
2405 | } | ||
2406 | 1925 | ||
2407 | ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y, | 1926 | ret = dev_priv->display.update_plane(crtc, crtc->fb, x, y); |
2408 | LEAVE_ATOMIC_MODE_SET); | ||
2409 | if (ret) { | 1927 | if (ret) { |
2410 | intel_unpin_fb_obj(to_intel_framebuffer(crtc->fb)->obj); | 1928 | intel_unpin_fb_obj(to_intel_framebuffer(crtc->fb)->obj); |
2411 | mutex_unlock(&dev->struct_mutex); | 1929 | mutex_unlock(&dev->struct_mutex); |
@@ -2418,6 +1936,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
2418 | intel_unpin_fb_obj(to_intel_framebuffer(old_fb)->obj); | 1936 | intel_unpin_fb_obj(to_intel_framebuffer(old_fb)->obj); |
2419 | } | 1937 | } |
2420 | 1938 | ||
1939 | intel_update_fbc(dev); | ||
2421 | mutex_unlock(&dev->struct_mutex); | 1940 | mutex_unlock(&dev->struct_mutex); |
2422 | 1941 | ||
2423 | if (!dev->primary->master) | 1942 | if (!dev->primary->master) |
@@ -3010,16 +2529,14 @@ static void intel_clear_scanline_wait(struct drm_device *dev) | |||
3010 | 2529 | ||
3011 | static void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc) | 2530 | static void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc) |
3012 | { | 2531 | { |
3013 | struct drm_i915_gem_object *obj; | 2532 | struct drm_device *dev = crtc->dev; |
3014 | struct drm_i915_private *dev_priv; | ||
3015 | 2533 | ||
3016 | if (crtc->fb == NULL) | 2534 | if (crtc->fb == NULL) |
3017 | return; | 2535 | return; |
3018 | 2536 | ||
3019 | obj = to_intel_framebuffer(crtc->fb)->obj; | 2537 | mutex_lock(&dev->struct_mutex); |
3020 | dev_priv = crtc->dev->dev_private; | 2538 | intel_finish_fb(crtc->fb); |
3021 | wait_event(dev_priv->pending_flip_queue, | 2539 | mutex_unlock(&dev->struct_mutex); |
3022 | atomic_read(&obj->pending_flip) == 0); | ||
3023 | } | 2540 | } |
3024 | 2541 | ||
3025 | static bool intel_crtc_driving_pch(struct drm_crtc *crtc) | 2542 | static bool intel_crtc_driving_pch(struct drm_crtc *crtc) |
@@ -3669,1482 +3186,6 @@ ironlake_compute_m_n(int bits_per_pixel, int nlanes, int pixel_clock, | |||
3669 | fdi_reduce_ratio(&m_n->link_m, &m_n->link_n); | 3186 | fdi_reduce_ratio(&m_n->link_m, &m_n->link_n); |
3670 | } | 3187 | } |
3671 | 3188 | ||
3672 | |||
3673 | struct intel_watermark_params { | ||
3674 | unsigned long fifo_size; | ||
3675 | unsigned long max_wm; | ||
3676 | unsigned long default_wm; | ||
3677 | unsigned long guard_size; | ||
3678 | unsigned long cacheline_size; | ||
3679 | }; | ||
3680 | |||
3681 | /* Pineview has different values for various configs */ | ||
3682 | static const struct intel_watermark_params pineview_display_wm = { | ||
3683 | PINEVIEW_DISPLAY_FIFO, | ||
3684 | PINEVIEW_MAX_WM, | ||
3685 | PINEVIEW_DFT_WM, | ||
3686 | PINEVIEW_GUARD_WM, | ||
3687 | PINEVIEW_FIFO_LINE_SIZE | ||
3688 | }; | ||
3689 | static const struct intel_watermark_params pineview_display_hplloff_wm = { | ||
3690 | PINEVIEW_DISPLAY_FIFO, | ||
3691 | PINEVIEW_MAX_WM, | ||
3692 | PINEVIEW_DFT_HPLLOFF_WM, | ||
3693 | PINEVIEW_GUARD_WM, | ||
3694 | PINEVIEW_FIFO_LINE_SIZE | ||
3695 | }; | ||
3696 | static const struct intel_watermark_params pineview_cursor_wm = { | ||
3697 | PINEVIEW_CURSOR_FIFO, | ||
3698 | PINEVIEW_CURSOR_MAX_WM, | ||
3699 | PINEVIEW_CURSOR_DFT_WM, | ||
3700 | PINEVIEW_CURSOR_GUARD_WM, | ||
3701 | PINEVIEW_FIFO_LINE_SIZE, | ||
3702 | }; | ||
3703 | static const struct intel_watermark_params pineview_cursor_hplloff_wm = { | ||
3704 | PINEVIEW_CURSOR_FIFO, | ||
3705 | PINEVIEW_CURSOR_MAX_WM, | ||
3706 | PINEVIEW_CURSOR_DFT_WM, | ||
3707 | PINEVIEW_CURSOR_GUARD_WM, | ||
3708 | PINEVIEW_FIFO_LINE_SIZE | ||
3709 | }; | ||
3710 | static const struct intel_watermark_params g4x_wm_info = { | ||
3711 | G4X_FIFO_SIZE, | ||
3712 | G4X_MAX_WM, | ||
3713 | G4X_MAX_WM, | ||
3714 | 2, | ||
3715 | G4X_FIFO_LINE_SIZE, | ||
3716 | }; | ||
3717 | static const struct intel_watermark_params g4x_cursor_wm_info = { | ||
3718 | I965_CURSOR_FIFO, | ||
3719 | I965_CURSOR_MAX_WM, | ||
3720 | I965_CURSOR_DFT_WM, | ||
3721 | 2, | ||
3722 | G4X_FIFO_LINE_SIZE, | ||
3723 | }; | ||
3724 | static const struct intel_watermark_params valleyview_wm_info = { | ||
3725 | VALLEYVIEW_FIFO_SIZE, | ||
3726 | VALLEYVIEW_MAX_WM, | ||
3727 | VALLEYVIEW_MAX_WM, | ||
3728 | 2, | ||
3729 | G4X_FIFO_LINE_SIZE, | ||
3730 | }; | ||
3731 | static const struct intel_watermark_params valleyview_cursor_wm_info = { | ||
3732 | I965_CURSOR_FIFO, | ||
3733 | VALLEYVIEW_CURSOR_MAX_WM, | ||
3734 | I965_CURSOR_DFT_WM, | ||
3735 | 2, | ||
3736 | G4X_FIFO_LINE_SIZE, | ||
3737 | }; | ||
3738 | static const struct intel_watermark_params i965_cursor_wm_info = { | ||
3739 | I965_CURSOR_FIFO, | ||
3740 | I965_CURSOR_MAX_WM, | ||
3741 | I965_CURSOR_DFT_WM, | ||
3742 | 2, | ||
3743 | I915_FIFO_LINE_SIZE, | ||
3744 | }; | ||
3745 | static const struct intel_watermark_params i945_wm_info = { | ||
3746 | I945_FIFO_SIZE, | ||
3747 | I915_MAX_WM, | ||
3748 | 1, | ||
3749 | 2, | ||
3750 | I915_FIFO_LINE_SIZE | ||
3751 | }; | ||
3752 | static const struct intel_watermark_params i915_wm_info = { | ||
3753 | I915_FIFO_SIZE, | ||
3754 | I915_MAX_WM, | ||
3755 | 1, | ||
3756 | 2, | ||
3757 | I915_FIFO_LINE_SIZE | ||
3758 | }; | ||
3759 | static const struct intel_watermark_params i855_wm_info = { | ||
3760 | I855GM_FIFO_SIZE, | ||
3761 | I915_MAX_WM, | ||
3762 | 1, | ||
3763 | 2, | ||
3764 | I830_FIFO_LINE_SIZE | ||
3765 | }; | ||
3766 | static const struct intel_watermark_params i830_wm_info = { | ||
3767 | I830_FIFO_SIZE, | ||
3768 | I915_MAX_WM, | ||
3769 | 1, | ||
3770 | 2, | ||
3771 | I830_FIFO_LINE_SIZE | ||
3772 | }; | ||
3773 | |||
3774 | static const struct intel_watermark_params ironlake_display_wm_info = { | ||
3775 | ILK_DISPLAY_FIFO, | ||
3776 | ILK_DISPLAY_MAXWM, | ||
3777 | ILK_DISPLAY_DFTWM, | ||
3778 | 2, | ||
3779 | ILK_FIFO_LINE_SIZE | ||
3780 | }; | ||
3781 | static const struct intel_watermark_params ironlake_cursor_wm_info = { | ||
3782 | ILK_CURSOR_FIFO, | ||
3783 | ILK_CURSOR_MAXWM, | ||
3784 | ILK_CURSOR_DFTWM, | ||
3785 | 2, | ||
3786 | ILK_FIFO_LINE_SIZE | ||
3787 | }; | ||
3788 | static const struct intel_watermark_params ironlake_display_srwm_info = { | ||
3789 | ILK_DISPLAY_SR_FIFO, | ||
3790 | ILK_DISPLAY_MAX_SRWM, | ||
3791 | ILK_DISPLAY_DFT_SRWM, | ||
3792 | 2, | ||
3793 | ILK_FIFO_LINE_SIZE | ||
3794 | }; | ||
3795 | static const struct intel_watermark_params ironlake_cursor_srwm_info = { | ||
3796 | ILK_CURSOR_SR_FIFO, | ||
3797 | ILK_CURSOR_MAX_SRWM, | ||
3798 | ILK_CURSOR_DFT_SRWM, | ||
3799 | 2, | ||
3800 | ILK_FIFO_LINE_SIZE | ||
3801 | }; | ||
3802 | |||
3803 | static const struct intel_watermark_params sandybridge_display_wm_info = { | ||
3804 | SNB_DISPLAY_FIFO, | ||
3805 | SNB_DISPLAY_MAXWM, | ||
3806 | SNB_DISPLAY_DFTWM, | ||
3807 | 2, | ||
3808 | SNB_FIFO_LINE_SIZE | ||
3809 | }; | ||
3810 | static const struct intel_watermark_params sandybridge_cursor_wm_info = { | ||
3811 | SNB_CURSOR_FIFO, | ||
3812 | SNB_CURSOR_MAXWM, | ||
3813 | SNB_CURSOR_DFTWM, | ||
3814 | 2, | ||
3815 | SNB_FIFO_LINE_SIZE | ||
3816 | }; | ||
3817 | static const struct intel_watermark_params sandybridge_display_srwm_info = { | ||
3818 | SNB_DISPLAY_SR_FIFO, | ||
3819 | SNB_DISPLAY_MAX_SRWM, | ||
3820 | SNB_DISPLAY_DFT_SRWM, | ||
3821 | 2, | ||
3822 | SNB_FIFO_LINE_SIZE | ||
3823 | }; | ||
3824 | static const struct intel_watermark_params sandybridge_cursor_srwm_info = { | ||
3825 | SNB_CURSOR_SR_FIFO, | ||
3826 | SNB_CURSOR_MAX_SRWM, | ||
3827 | SNB_CURSOR_DFT_SRWM, | ||
3828 | 2, | ||
3829 | SNB_FIFO_LINE_SIZE | ||
3830 | }; | ||
3831 | |||
3832 | |||
3833 | /** | ||
3834 | * intel_calculate_wm - calculate watermark level | ||
3835 | * @clock_in_khz: pixel clock | ||
3836 | * @wm: chip FIFO params | ||
3837 | * @pixel_size: display pixel size | ||
3838 | * @latency_ns: memory latency for the platform | ||
3839 | * | ||
3840 | * Calculate the watermark level (the level at which the display plane will | ||
3841 | * start fetching from memory again). Each chip has a different display | ||
3842 | * FIFO size and allocation, so the caller needs to figure that out and pass | ||
3843 | * in the correct intel_watermark_params structure. | ||
3844 | * | ||
3845 | * As the pixel clock runs, the FIFO will be drained at a rate that depends | ||
3846 | * on the pixel size. When it reaches the watermark level, it'll start | ||
3847 | * fetching FIFO line sized based chunks from memory until the FIFO fills | ||
3848 | * past the watermark point. If the FIFO drains completely, a FIFO underrun | ||
3849 | * will occur, and a display engine hang could result. | ||
3850 | */ | ||
3851 | static unsigned long intel_calculate_wm(unsigned long clock_in_khz, | ||
3852 | const struct intel_watermark_params *wm, | ||
3853 | int fifo_size, | ||
3854 | int pixel_size, | ||
3855 | unsigned long latency_ns) | ||
3856 | { | ||
3857 | long entries_required, wm_size; | ||
3858 | |||
3859 | /* | ||
3860 | * Note: we need to make sure we don't overflow for various clock & | ||
3861 | * latency values. | ||
3862 | * clocks go from a few thousand to several hundred thousand. | ||
3863 | * latency is usually a few thousand | ||
3864 | */ | ||
3865 | entries_required = ((clock_in_khz / 1000) * pixel_size * latency_ns) / | ||
3866 | 1000; | ||
3867 | entries_required = DIV_ROUND_UP(entries_required, wm->cacheline_size); | ||
3868 | |||
3869 | DRM_DEBUG_KMS("FIFO entries required for mode: %ld\n", entries_required); | ||
3870 | |||
3871 | wm_size = fifo_size - (entries_required + wm->guard_size); | ||
3872 | |||
3873 | DRM_DEBUG_KMS("FIFO watermark level: %ld\n", wm_size); | ||
3874 | |||
3875 | /* Don't promote wm_size to unsigned... */ | ||
3876 | if (wm_size > (long)wm->max_wm) | ||
3877 | wm_size = wm->max_wm; | ||
3878 | if (wm_size <= 0) | ||
3879 | wm_size = wm->default_wm; | ||
3880 | return wm_size; | ||
3881 | } | ||
3882 | |||
3883 | struct cxsr_latency { | ||
3884 | int is_desktop; | ||
3885 | int is_ddr3; | ||
3886 | unsigned long fsb_freq; | ||
3887 | unsigned long mem_freq; | ||
3888 | unsigned long display_sr; | ||
3889 | unsigned long display_hpll_disable; | ||
3890 | unsigned long cursor_sr; | ||
3891 | unsigned long cursor_hpll_disable; | ||
3892 | }; | ||
3893 | |||
3894 | static const struct cxsr_latency cxsr_latency_table[] = { | ||
3895 | {1, 0, 800, 400, 3382, 33382, 3983, 33983}, /* DDR2-400 SC */ | ||
3896 | {1, 0, 800, 667, 3354, 33354, 3807, 33807}, /* DDR2-667 SC */ | ||
3897 | {1, 0, 800, 800, 3347, 33347, 3763, 33763}, /* DDR2-800 SC */ | ||
3898 | {1, 1, 800, 667, 6420, 36420, 6873, 36873}, /* DDR3-667 SC */ | ||
3899 | {1, 1, 800, 800, 5902, 35902, 6318, 36318}, /* DDR3-800 SC */ | ||
3900 | |||
3901 | {1, 0, 667, 400, 3400, 33400, 4021, 34021}, /* DDR2-400 SC */ | ||
3902 | {1, 0, 667, 667, 3372, 33372, 3845, 33845}, /* DDR2-667 SC */ | ||
3903 | {1, 0, 667, 800, 3386, 33386, 3822, 33822}, /* DDR2-800 SC */ | ||
3904 | {1, 1, 667, 667, 6438, 36438, 6911, 36911}, /* DDR3-667 SC */ | ||
3905 | {1, 1, 667, 800, 5941, 35941, 6377, 36377}, /* DDR3-800 SC */ | ||
3906 | |||
3907 | {1, 0, 400, 400, 3472, 33472, 4173, 34173}, /* DDR2-400 SC */ | ||
3908 | {1, 0, 400, 667, 3443, 33443, 3996, 33996}, /* DDR2-667 SC */ | ||
3909 | {1, 0, 400, 800, 3430, 33430, 3946, 33946}, /* DDR2-800 SC */ | ||
3910 | {1, 1, 400, 667, 6509, 36509, 7062, 37062}, /* DDR3-667 SC */ | ||
3911 | {1, 1, 400, 800, 5985, 35985, 6501, 36501}, /* DDR3-800 SC */ | ||
3912 | |||
3913 | {0, 0, 800, 400, 3438, 33438, 4065, 34065}, /* DDR2-400 SC */ | ||
3914 | {0, 0, 800, 667, 3410, 33410, 3889, 33889}, /* DDR2-667 SC */ | ||
3915 | {0, 0, 800, 800, 3403, 33403, 3845, 33845}, /* DDR2-800 SC */ | ||
3916 | {0, 1, 800, 667, 6476, 36476, 6955, 36955}, /* DDR3-667 SC */ | ||
3917 | {0, 1, 800, 800, 5958, 35958, 6400, 36400}, /* DDR3-800 SC */ | ||
3918 | |||
3919 | {0, 0, 667, 400, 3456, 33456, 4103, 34106}, /* DDR2-400 SC */ | ||
3920 | {0, 0, 667, 667, 3428, 33428, 3927, 33927}, /* DDR2-667 SC */ | ||
3921 | {0, 0, 667, 800, 3443, 33443, 3905, 33905}, /* DDR2-800 SC */ | ||
3922 | {0, 1, 667, 667, 6494, 36494, 6993, 36993}, /* DDR3-667 SC */ | ||
3923 | {0, 1, 667, 800, 5998, 35998, 6460, 36460}, /* DDR3-800 SC */ | ||
3924 | |||
3925 | {0, 0, 400, 400, 3528, 33528, 4255, 34255}, /* DDR2-400 SC */ | ||
3926 | {0, 0, 400, 667, 3500, 33500, 4079, 34079}, /* DDR2-667 SC */ | ||
3927 | {0, 0, 400, 800, 3487, 33487, 4029, 34029}, /* DDR2-800 SC */ | ||
3928 | {0, 1, 400, 667, 6566, 36566, 7145, 37145}, /* DDR3-667 SC */ | ||
3929 | {0, 1, 400, 800, 6042, 36042, 6584, 36584}, /* DDR3-800 SC */ | ||
3930 | }; | ||
3931 | |||
3932 | static const struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, | ||
3933 | int is_ddr3, | ||
3934 | int fsb, | ||
3935 | int mem) | ||
3936 | { | ||
3937 | const struct cxsr_latency *latency; | ||
3938 | int i; | ||
3939 | |||
3940 | if (fsb == 0 || mem == 0) | ||
3941 | return NULL; | ||
3942 | |||
3943 | for (i = 0; i < ARRAY_SIZE(cxsr_latency_table); i++) { | ||
3944 | latency = &cxsr_latency_table[i]; | ||
3945 | if (is_desktop == latency->is_desktop && | ||
3946 | is_ddr3 == latency->is_ddr3 && | ||
3947 | fsb == latency->fsb_freq && mem == latency->mem_freq) | ||
3948 | return latency; | ||
3949 | } | ||
3950 | |||
3951 | DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n"); | ||
3952 | |||
3953 | return NULL; | ||
3954 | } | ||
3955 | |||
3956 | static void pineview_disable_cxsr(struct drm_device *dev) | ||
3957 | { | ||
3958 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3959 | |||
3960 | /* deactivate cxsr */ | ||
3961 | I915_WRITE(DSPFW3, I915_READ(DSPFW3) & ~PINEVIEW_SELF_REFRESH_EN); | ||
3962 | } | ||
3963 | |||
3964 | /* | ||
3965 | * Latency for FIFO fetches is dependent on several factors: | ||
3966 | * - memory configuration (speed, channels) | ||
3967 | * - chipset | ||
3968 | * - current MCH state | ||
3969 | * It can be fairly high in some situations, so here we assume a fairly | ||
3970 | * pessimal value. It's a tradeoff between extra memory fetches (if we | ||
3971 | * set this value too high, the FIFO will fetch frequently to stay full) | ||
3972 | * and power consumption (set it too low to save power and we might see | ||
3973 | * FIFO underruns and display "flicker"). | ||
3974 | * | ||
3975 | * A value of 5us seems to be a good balance; safe for very low end | ||
3976 | * platforms but not overly aggressive on lower latency configs. | ||
3977 | */ | ||
3978 | static const int latency_ns = 5000; | ||
3979 | |||
3980 | static int i9xx_get_fifo_size(struct drm_device *dev, int plane) | ||
3981 | { | ||
3982 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3983 | uint32_t dsparb = I915_READ(DSPARB); | ||
3984 | int size; | ||
3985 | |||
3986 | size = dsparb & 0x7f; | ||
3987 | if (plane) | ||
3988 | size = ((dsparb >> DSPARB_CSTART_SHIFT) & 0x7f) - size; | ||
3989 | |||
3990 | DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb, | ||
3991 | plane ? "B" : "A", size); | ||
3992 | |||
3993 | return size; | ||
3994 | } | ||
3995 | |||
3996 | static int i85x_get_fifo_size(struct drm_device *dev, int plane) | ||
3997 | { | ||
3998 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3999 | uint32_t dsparb = I915_READ(DSPARB); | ||
4000 | int size; | ||
4001 | |||
4002 | size = dsparb & 0x1ff; | ||
4003 | if (plane) | ||
4004 | size = ((dsparb >> DSPARB_BEND_SHIFT) & 0x1ff) - size; | ||
4005 | size >>= 1; /* Convert to cachelines */ | ||
4006 | |||
4007 | DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb, | ||
4008 | plane ? "B" : "A", size); | ||
4009 | |||
4010 | return size; | ||
4011 | } | ||
4012 | |||
4013 | static int i845_get_fifo_size(struct drm_device *dev, int plane) | ||
4014 | { | ||
4015 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
4016 | uint32_t dsparb = I915_READ(DSPARB); | ||
4017 | int size; | ||
4018 | |||
4019 | size = dsparb & 0x7f; | ||
4020 | size >>= 2; /* Convert to cachelines */ | ||
4021 | |||
4022 | DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb, | ||
4023 | plane ? "B" : "A", | ||
4024 | size); | ||
4025 | |||
4026 | return size; | ||
4027 | } | ||
4028 | |||
4029 | static int i830_get_fifo_size(struct drm_device *dev, int plane) | ||
4030 | { | ||
4031 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
4032 | uint32_t dsparb = I915_READ(DSPARB); | ||
4033 | int size; | ||
4034 | |||
4035 | size = dsparb & 0x7f; | ||
4036 | size >>= 1; /* Convert to cachelines */ | ||
4037 | |||
4038 | DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb, | ||
4039 | plane ? "B" : "A", size); | ||
4040 | |||
4041 | return size; | ||
4042 | } | ||
4043 | |||
4044 | static struct drm_crtc *single_enabled_crtc(struct drm_device *dev) | ||
4045 | { | ||
4046 | struct drm_crtc *crtc, *enabled = NULL; | ||
4047 | |||
4048 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | ||
4049 | if (crtc->enabled && crtc->fb) { | ||
4050 | if (enabled) | ||
4051 | return NULL; | ||
4052 | enabled = crtc; | ||
4053 | } | ||
4054 | } | ||
4055 | |||
4056 | return enabled; | ||
4057 | } | ||
4058 | |||
4059 | static void pineview_update_wm(struct drm_device *dev) | ||
4060 | { | ||
4061 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
4062 | struct drm_crtc *crtc; | ||
4063 | const struct cxsr_latency *latency; | ||
4064 | u32 reg; | ||
4065 | unsigned long wm; | ||
4066 | |||
4067 | latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->is_ddr3, | ||
4068 | dev_priv->fsb_freq, dev_priv->mem_freq); | ||
4069 | if (!latency) { | ||
4070 | DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n"); | ||
4071 | pineview_disable_cxsr(dev); | ||
4072 | return; | ||
4073 | } | ||
4074 | |||
4075 | crtc = single_enabled_crtc(dev); | ||
4076 | if (crtc) { | ||
4077 | int clock = crtc->mode.clock; | ||
4078 | int pixel_size = crtc->fb->bits_per_pixel / 8; | ||
4079 | |||
4080 | /* Display SR */ | ||
4081 | wm = intel_calculate_wm(clock, &pineview_display_wm, | ||
4082 | pineview_display_wm.fifo_size, | ||
4083 | pixel_size, latency->display_sr); | ||
4084 | reg = I915_READ(DSPFW1); | ||
4085 | reg &= ~DSPFW_SR_MASK; | ||
4086 | reg |= wm << DSPFW_SR_SHIFT; | ||
4087 | I915_WRITE(DSPFW1, reg); | ||
4088 | DRM_DEBUG_KMS("DSPFW1 register is %x\n", reg); | ||
4089 | |||
4090 | /* cursor SR */ | ||
4091 | wm = intel_calculate_wm(clock, &pineview_cursor_wm, | ||
4092 | pineview_display_wm.fifo_size, | ||
4093 | pixel_size, latency->cursor_sr); | ||
4094 | reg = I915_READ(DSPFW3); | ||
4095 | reg &= ~DSPFW_CURSOR_SR_MASK; | ||
4096 | reg |= (wm & 0x3f) << DSPFW_CURSOR_SR_SHIFT; | ||
4097 | I915_WRITE(DSPFW3, reg); | ||
4098 | |||
4099 | /* Display HPLL off SR */ | ||
4100 | wm = intel_calculate_wm(clock, &pineview_display_hplloff_wm, | ||
4101 | pineview_display_hplloff_wm.fifo_size, | ||
4102 | pixel_size, latency->display_hpll_disable); | ||
4103 | reg = I915_READ(DSPFW3); | ||
4104 | reg &= ~DSPFW_HPLL_SR_MASK; | ||
4105 | reg |= wm & DSPFW_HPLL_SR_MASK; | ||
4106 | I915_WRITE(DSPFW3, reg); | ||
4107 | |||
4108 | /* cursor HPLL off SR */ | ||
4109 | wm = intel_calculate_wm(clock, &pineview_cursor_hplloff_wm, | ||
4110 | pineview_display_hplloff_wm.fifo_size, | ||
4111 | pixel_size, latency->cursor_hpll_disable); | ||
4112 | reg = I915_READ(DSPFW3); | ||
4113 | reg &= ~DSPFW_HPLL_CURSOR_MASK; | ||
4114 | reg |= (wm & 0x3f) << DSPFW_HPLL_CURSOR_SHIFT; | ||
4115 | I915_WRITE(DSPFW3, reg); | ||
4116 | DRM_DEBUG_KMS("DSPFW3 register is %x\n", reg); | ||
4117 | |||
4118 | /* activate cxsr */ | ||
4119 | I915_WRITE(DSPFW3, | ||
4120 | I915_READ(DSPFW3) | PINEVIEW_SELF_REFRESH_EN); | ||
4121 | DRM_DEBUG_KMS("Self-refresh is enabled\n"); | ||
4122 | } else { | ||
4123 | pineview_disable_cxsr(dev); | ||
4124 | DRM_DEBUG_KMS("Self-refresh is disabled\n"); | ||
4125 | } | ||
4126 | } | ||
4127 | |||
4128 | static bool g4x_compute_wm0(struct drm_device *dev, | ||
4129 | int plane, | ||
4130 | const struct intel_watermark_params *display, | ||
4131 | int display_latency_ns, | ||
4132 | const struct intel_watermark_params *cursor, | ||
4133 | int cursor_latency_ns, | ||
4134 | int *plane_wm, | ||
4135 | int *cursor_wm) | ||
4136 | { | ||
4137 | struct drm_crtc *crtc; | ||
4138 | int htotal, hdisplay, clock, pixel_size; | ||
4139 | int line_time_us, line_count; | ||
4140 | int entries, tlb_miss; | ||
4141 | |||
4142 | crtc = intel_get_crtc_for_plane(dev, plane); | ||
4143 | if (crtc->fb == NULL || !crtc->enabled) { | ||
4144 | *cursor_wm = cursor->guard_size; | ||
4145 | *plane_wm = display->guard_size; | ||
4146 | return false; | ||
4147 | } | ||
4148 | |||
4149 | htotal = crtc->mode.htotal; | ||
4150 | hdisplay = crtc->mode.hdisplay; | ||
4151 | clock = crtc->mode.clock; | ||
4152 | pixel_size = crtc->fb->bits_per_pixel / 8; | ||
4153 | |||
4154 | /* Use the small buffer method to calculate plane watermark */ | ||
4155 | entries = ((clock * pixel_size / 1000) * display_latency_ns) / 1000; | ||
4156 | tlb_miss = display->fifo_size*display->cacheline_size - hdisplay * 8; | ||
4157 | if (tlb_miss > 0) | ||
4158 | entries += tlb_miss; | ||
4159 | entries = DIV_ROUND_UP(entries, display->cacheline_size); | ||
4160 | *plane_wm = entries + display->guard_size; | ||
4161 | if (*plane_wm > (int)display->max_wm) | ||
4162 | *plane_wm = display->max_wm; | ||
4163 | |||
4164 | /* Use the large buffer method to calculate cursor watermark */ | ||
4165 | line_time_us = ((htotal * 1000) / clock); | ||
4166 | line_count = (cursor_latency_ns / line_time_us + 1000) / 1000; | ||
4167 | entries = line_count * 64 * pixel_size; | ||
4168 | tlb_miss = cursor->fifo_size*cursor->cacheline_size - hdisplay * 8; | ||
4169 | if (tlb_miss > 0) | ||
4170 | entries += tlb_miss; | ||
4171 | entries = DIV_ROUND_UP(entries, cursor->cacheline_size); | ||
4172 | *cursor_wm = entries + cursor->guard_size; | ||
4173 | if (*cursor_wm > (int)cursor->max_wm) | ||
4174 | *cursor_wm = (int)cursor->max_wm; | ||
4175 | |||
4176 | return true; | ||
4177 | } | ||
4178 | |||
4179 | /* | ||
4180 | * Check the wm result. | ||
4181 | * | ||
4182 | * If any calculated watermark values is larger than the maximum value that | ||
4183 | * can be programmed into the associated watermark register, that watermark | ||
4184 | * must be disabled. | ||
4185 | */ | ||
4186 | static bool g4x_check_srwm(struct drm_device *dev, | ||
4187 | int display_wm, int cursor_wm, | ||
4188 | const struct intel_watermark_params *display, | ||
4189 | const struct intel_watermark_params *cursor) | ||
4190 | { | ||
4191 | DRM_DEBUG_KMS("SR watermark: display plane %d, cursor %d\n", | ||
4192 | display_wm, cursor_wm); | ||
4193 | |||
4194 | if (display_wm > display->max_wm) { | ||
4195 | DRM_DEBUG_KMS("display watermark is too large(%d/%ld), disabling\n", | ||
4196 | display_wm, display->max_wm); | ||
4197 | return false; | ||
4198 | } | ||
4199 | |||
4200 | if (cursor_wm > cursor->max_wm) { | ||
4201 | DRM_DEBUG_KMS("cursor watermark is too large(%d/%ld), disabling\n", | ||
4202 | cursor_wm, cursor->max_wm); | ||
4203 | return false; | ||
4204 | } | ||
4205 | |||
4206 | if (!(display_wm || cursor_wm)) { | ||
4207 | DRM_DEBUG_KMS("SR latency is 0, disabling\n"); | ||
4208 | return false; | ||
4209 | } | ||
4210 | |||
4211 | return true; | ||
4212 | } | ||
4213 | |||
4214 | static bool g4x_compute_srwm(struct drm_device *dev, | ||
4215 | int plane, | ||
4216 | int latency_ns, | ||
4217 | const struct intel_watermark_params *display, | ||
4218 | const struct intel_watermark_params *cursor, | ||
4219 | int *display_wm, int *cursor_wm) | ||
4220 | { | ||
4221 | struct drm_crtc *crtc; | ||
4222 | int hdisplay, htotal, pixel_size, clock; | ||
4223 | unsigned long line_time_us; | ||
4224 | int line_count, line_size; | ||
4225 | int small, large; | ||
4226 | int entries; | ||
4227 | |||
4228 | if (!latency_ns) { | ||
4229 | *display_wm = *cursor_wm = 0; | ||
4230 | return false; | ||
4231 | } | ||
4232 | |||
4233 | crtc = intel_get_crtc_for_plane(dev, plane); | ||
4234 | hdisplay = crtc->mode.hdisplay; | ||
4235 | htotal = crtc->mode.htotal; | ||
4236 | clock = crtc->mode.clock; | ||
4237 | pixel_size = crtc->fb->bits_per_pixel / 8; | ||
4238 | |||
4239 | line_time_us = (htotal * 1000) / clock; | ||
4240 | line_count = (latency_ns / line_time_us + 1000) / 1000; | ||
4241 | line_size = hdisplay * pixel_size; | ||
4242 | |||
4243 | /* Use the minimum of the small and large buffer method for primary */ | ||
4244 | small = ((clock * pixel_size / 1000) * latency_ns) / 1000; | ||
4245 | large = line_count * line_size; | ||
4246 | |||
4247 | entries = DIV_ROUND_UP(min(small, large), display->cacheline_size); | ||
4248 | *display_wm = entries + display->guard_size; | ||
4249 | |||
4250 | /* calculate the self-refresh watermark for display cursor */ | ||
4251 | entries = line_count * pixel_size * 64; | ||
4252 | entries = DIV_ROUND_UP(entries, cursor->cacheline_size); | ||
4253 | *cursor_wm = entries + cursor->guard_size; | ||
4254 | |||
4255 | return g4x_check_srwm(dev, | ||
4256 | *display_wm, *cursor_wm, | ||
4257 | display, cursor); | ||
4258 | } | ||
4259 | |||
4260 | static bool vlv_compute_drain_latency(struct drm_device *dev, | ||
4261 | int plane, | ||
4262 | int *plane_prec_mult, | ||
4263 | int *plane_dl, | ||
4264 | int *cursor_prec_mult, | ||
4265 | int *cursor_dl) | ||
4266 | { | ||
4267 | struct drm_crtc *crtc; | ||
4268 | int clock, pixel_size; | ||
4269 | int entries; | ||
4270 | |||
4271 | crtc = intel_get_crtc_for_plane(dev, plane); | ||
4272 | if (crtc->fb == NULL || !crtc->enabled) | ||
4273 | return false; | ||
4274 | |||
4275 | clock = crtc->mode.clock; /* VESA DOT Clock */ | ||
4276 | pixel_size = crtc->fb->bits_per_pixel / 8; /* BPP */ | ||
4277 | |||
4278 | entries = (clock / 1000) * pixel_size; | ||
4279 | *plane_prec_mult = (entries > 256) ? | ||
4280 | DRAIN_LATENCY_PRECISION_32 : DRAIN_LATENCY_PRECISION_16; | ||
4281 | *plane_dl = (64 * (*plane_prec_mult) * 4) / ((clock / 1000) * | ||
4282 | pixel_size); | ||
4283 | |||
4284 | entries = (clock / 1000) * 4; /* BPP is always 4 for cursor */ | ||
4285 | *cursor_prec_mult = (entries > 256) ? | ||
4286 | DRAIN_LATENCY_PRECISION_32 : DRAIN_LATENCY_PRECISION_16; | ||
4287 | *cursor_dl = (64 * (*cursor_prec_mult) * 4) / ((clock / 1000) * 4); | ||
4288 | |||
4289 | return true; | ||
4290 | } | ||
4291 | |||
4292 | /* | ||
4293 | * Update drain latency registers of memory arbiter | ||
4294 | * | ||
4295 | * Valleyview SoC has a new memory arbiter and needs drain latency registers | ||
4296 | * to be programmed. Each plane has a drain latency multiplier and a drain | ||
4297 | * latency value. | ||
4298 | */ | ||
4299 | |||
4300 | static void vlv_update_drain_latency(struct drm_device *dev) | ||
4301 | { | ||
4302 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
4303 | int planea_prec, planea_dl, planeb_prec, planeb_dl; | ||
4304 | int cursora_prec, cursora_dl, cursorb_prec, cursorb_dl; | ||
4305 | int plane_prec_mult, cursor_prec_mult; /* Precision multiplier is | ||
4306 | either 16 or 32 */ | ||
4307 | |||
4308 | /* For plane A, Cursor A */ | ||
4309 | if (vlv_compute_drain_latency(dev, 0, &plane_prec_mult, &planea_dl, | ||
4310 | &cursor_prec_mult, &cursora_dl)) { | ||
4311 | cursora_prec = (cursor_prec_mult == DRAIN_LATENCY_PRECISION_32) ? | ||
4312 | DDL_CURSORA_PRECISION_32 : DDL_CURSORA_PRECISION_16; | ||
4313 | planea_prec = (plane_prec_mult == DRAIN_LATENCY_PRECISION_32) ? | ||
4314 | DDL_PLANEA_PRECISION_32 : DDL_PLANEA_PRECISION_16; | ||
4315 | |||
4316 | I915_WRITE(VLV_DDL1, cursora_prec | | ||
4317 | (cursora_dl << DDL_CURSORA_SHIFT) | | ||
4318 | planea_prec | planea_dl); | ||
4319 | } | ||
4320 | |||
4321 | /* For plane B, Cursor B */ | ||
4322 | if (vlv_compute_drain_latency(dev, 1, &plane_prec_mult, &planeb_dl, | ||
4323 | &cursor_prec_mult, &cursorb_dl)) { | ||
4324 | cursorb_prec = (cursor_prec_mult == DRAIN_LATENCY_PRECISION_32) ? | ||
4325 | DDL_CURSORB_PRECISION_32 : DDL_CURSORB_PRECISION_16; | ||
4326 | planeb_prec = (plane_prec_mult == DRAIN_LATENCY_PRECISION_32) ? | ||
4327 | DDL_PLANEB_PRECISION_32 : DDL_PLANEB_PRECISION_16; | ||
4328 | |||
4329 | I915_WRITE(VLV_DDL2, cursorb_prec | | ||
4330 | (cursorb_dl << DDL_CURSORB_SHIFT) | | ||
4331 | planeb_prec | planeb_dl); | ||
4332 | } | ||
4333 | } | ||
4334 | |||
4335 | #define single_plane_enabled(mask) is_power_of_2(mask) | ||
4336 | |||
4337 | static void valleyview_update_wm(struct drm_device *dev) | ||
4338 | { | ||
4339 | static const int sr_latency_ns = 12000; | ||
4340 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
4341 | int planea_wm, planeb_wm, cursora_wm, cursorb_wm; | ||
4342 | int plane_sr, cursor_sr; | ||
4343 | unsigned int enabled = 0; | ||
4344 | |||
4345 | vlv_update_drain_latency(dev); | ||
4346 | |||
4347 | if (g4x_compute_wm0(dev, 0, | ||
4348 | &valleyview_wm_info, latency_ns, | ||
4349 | &valleyview_cursor_wm_info, latency_ns, | ||
4350 | &planea_wm, &cursora_wm)) | ||
4351 | enabled |= 1; | ||
4352 | |||
4353 | if (g4x_compute_wm0(dev, 1, | ||
4354 | &valleyview_wm_info, latency_ns, | ||
4355 | &valleyview_cursor_wm_info, latency_ns, | ||
4356 | &planeb_wm, &cursorb_wm)) | ||
4357 | enabled |= 2; | ||
4358 | |||
4359 | plane_sr = cursor_sr = 0; | ||
4360 | if (single_plane_enabled(enabled) && | ||
4361 | g4x_compute_srwm(dev, ffs(enabled) - 1, | ||
4362 | sr_latency_ns, | ||
4363 | &valleyview_wm_info, | ||
4364 | &valleyview_cursor_wm_info, | ||
4365 | &plane_sr, &cursor_sr)) | ||
4366 | I915_WRITE(FW_BLC_SELF_VLV, FW_CSPWRDWNEN); | ||
4367 | else | ||
4368 | I915_WRITE(FW_BLC_SELF_VLV, | ||
4369 | I915_READ(FW_BLC_SELF_VLV) & ~FW_CSPWRDWNEN); | ||
4370 | |||
4371 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: plane=%d, cursor=%d, B: plane=%d, cursor=%d, SR: plane=%d, cursor=%d\n", | ||
4372 | planea_wm, cursora_wm, | ||
4373 | planeb_wm, cursorb_wm, | ||
4374 | plane_sr, cursor_sr); | ||
4375 | |||
4376 | I915_WRITE(DSPFW1, | ||
4377 | (plane_sr << DSPFW_SR_SHIFT) | | ||
4378 | (cursorb_wm << DSPFW_CURSORB_SHIFT) | | ||
4379 | (planeb_wm << DSPFW_PLANEB_SHIFT) | | ||
4380 | planea_wm); | ||
4381 | I915_WRITE(DSPFW2, | ||
4382 | (I915_READ(DSPFW2) & DSPFW_CURSORA_MASK) | | ||
4383 | (cursora_wm << DSPFW_CURSORA_SHIFT)); | ||
4384 | I915_WRITE(DSPFW3, | ||
4385 | (I915_READ(DSPFW3) | (cursor_sr << DSPFW_CURSOR_SR_SHIFT))); | ||
4386 | } | ||
4387 | |||
4388 | static void g4x_update_wm(struct drm_device *dev) | ||
4389 | { | ||
4390 | static const int sr_latency_ns = 12000; | ||
4391 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
4392 | int planea_wm, planeb_wm, cursora_wm, cursorb_wm; | ||
4393 | int plane_sr, cursor_sr; | ||
4394 | unsigned int enabled = 0; | ||
4395 | |||
4396 | if (g4x_compute_wm0(dev, 0, | ||
4397 | &g4x_wm_info, latency_ns, | ||
4398 | &g4x_cursor_wm_info, latency_ns, | ||
4399 | &planea_wm, &cursora_wm)) | ||
4400 | enabled |= 1; | ||
4401 | |||
4402 | if (g4x_compute_wm0(dev, 1, | ||
4403 | &g4x_wm_info, latency_ns, | ||
4404 | &g4x_cursor_wm_info, latency_ns, | ||
4405 | &planeb_wm, &cursorb_wm)) | ||
4406 | enabled |= 2; | ||
4407 | |||
4408 | plane_sr = cursor_sr = 0; | ||
4409 | if (single_plane_enabled(enabled) && | ||
4410 | g4x_compute_srwm(dev, ffs(enabled) - 1, | ||
4411 | sr_latency_ns, | ||
4412 | &g4x_wm_info, | ||
4413 | &g4x_cursor_wm_info, | ||
4414 | &plane_sr, &cursor_sr)) | ||
4415 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); | ||
4416 | else | ||
4417 | I915_WRITE(FW_BLC_SELF, | ||
4418 | I915_READ(FW_BLC_SELF) & ~FW_BLC_SELF_EN); | ||
4419 | |||
4420 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: plane=%d, cursor=%d, B: plane=%d, cursor=%d, SR: plane=%d, cursor=%d\n", | ||
4421 | planea_wm, cursora_wm, | ||
4422 | planeb_wm, cursorb_wm, | ||
4423 | plane_sr, cursor_sr); | ||
4424 | |||
4425 | I915_WRITE(DSPFW1, | ||
4426 | (plane_sr << DSPFW_SR_SHIFT) | | ||
4427 | (cursorb_wm << DSPFW_CURSORB_SHIFT) | | ||
4428 | (planeb_wm << DSPFW_PLANEB_SHIFT) | | ||
4429 | planea_wm); | ||
4430 | I915_WRITE(DSPFW2, | ||
4431 | (I915_READ(DSPFW2) & DSPFW_CURSORA_MASK) | | ||
4432 | (cursora_wm << DSPFW_CURSORA_SHIFT)); | ||
4433 | /* HPLL off in SR has some issues on G4x... disable it */ | ||
4434 | I915_WRITE(DSPFW3, | ||
4435 | (I915_READ(DSPFW3) & ~DSPFW_HPLL_SR_EN) | | ||
4436 | (cursor_sr << DSPFW_CURSOR_SR_SHIFT)); | ||
4437 | } | ||
4438 | |||
4439 | static void i965_update_wm(struct drm_device *dev) | ||
4440 | { | ||
4441 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
4442 | struct drm_crtc *crtc; | ||
4443 | int srwm = 1; | ||
4444 | int cursor_sr = 16; | ||
4445 | |||
4446 | /* Calc sr entries for one plane configs */ | ||
4447 | crtc = single_enabled_crtc(dev); | ||
4448 | if (crtc) { | ||
4449 | /* self-refresh has much higher latency */ | ||
4450 | static const int sr_latency_ns = 12000; | ||
4451 | int clock = crtc->mode.clock; | ||
4452 | int htotal = crtc->mode.htotal; | ||
4453 | int hdisplay = crtc->mode.hdisplay; | ||
4454 | int pixel_size = crtc->fb->bits_per_pixel / 8; | ||
4455 | unsigned long line_time_us; | ||
4456 | int entries; | ||
4457 | |||
4458 | line_time_us = ((htotal * 1000) / clock); | ||
4459 | |||
4460 | /* Use ns/us then divide to preserve precision */ | ||
4461 | entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * | ||
4462 | pixel_size * hdisplay; | ||
4463 | entries = DIV_ROUND_UP(entries, I915_FIFO_LINE_SIZE); | ||
4464 | srwm = I965_FIFO_SIZE - entries; | ||
4465 | if (srwm < 0) | ||
4466 | srwm = 1; | ||
4467 | srwm &= 0x1ff; | ||
4468 | DRM_DEBUG_KMS("self-refresh entries: %d, wm: %d\n", | ||
4469 | entries, srwm); | ||
4470 | |||
4471 | entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * | ||
4472 | pixel_size * 64; | ||
4473 | entries = DIV_ROUND_UP(entries, | ||
4474 | i965_cursor_wm_info.cacheline_size); | ||
4475 | cursor_sr = i965_cursor_wm_info.fifo_size - | ||
4476 | (entries + i965_cursor_wm_info.guard_size); | ||
4477 | |||
4478 | if (cursor_sr > i965_cursor_wm_info.max_wm) | ||
4479 | cursor_sr = i965_cursor_wm_info.max_wm; | ||
4480 | |||
4481 | DRM_DEBUG_KMS("self-refresh watermark: display plane %d " | ||
4482 | "cursor %d\n", srwm, cursor_sr); | ||
4483 | |||
4484 | if (IS_CRESTLINE(dev)) | ||
4485 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); | ||
4486 | } else { | ||
4487 | /* Turn off self refresh if both pipes are enabled */ | ||
4488 | if (IS_CRESTLINE(dev)) | ||
4489 | I915_WRITE(FW_BLC_SELF, I915_READ(FW_BLC_SELF) | ||
4490 | & ~FW_BLC_SELF_EN); | ||
4491 | } | ||
4492 | |||
4493 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: 8, B: 8, C: 8, SR %d\n", | ||
4494 | srwm); | ||
4495 | |||
4496 | /* 965 has limitations... */ | ||
4497 | I915_WRITE(DSPFW1, (srwm << DSPFW_SR_SHIFT) | | ||
4498 | (8 << 16) | (8 << 8) | (8 << 0)); | ||
4499 | I915_WRITE(DSPFW2, (8 << 8) | (8 << 0)); | ||
4500 | /* update cursor SR watermark */ | ||
4501 | I915_WRITE(DSPFW3, (cursor_sr << DSPFW_CURSOR_SR_SHIFT)); | ||
4502 | } | ||
4503 | |||
4504 | static void i9xx_update_wm(struct drm_device *dev) | ||
4505 | { | ||
4506 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
4507 | const struct intel_watermark_params *wm_info; | ||
4508 | uint32_t fwater_lo; | ||
4509 | uint32_t fwater_hi; | ||
4510 | int cwm, srwm = 1; | ||
4511 | int fifo_size; | ||
4512 | int planea_wm, planeb_wm; | ||
4513 | struct drm_crtc *crtc, *enabled = NULL; | ||
4514 | |||
4515 | if (IS_I945GM(dev)) | ||
4516 | wm_info = &i945_wm_info; | ||
4517 | else if (!IS_GEN2(dev)) | ||
4518 | wm_info = &i915_wm_info; | ||
4519 | else | ||
4520 | wm_info = &i855_wm_info; | ||
4521 | |||
4522 | fifo_size = dev_priv->display.get_fifo_size(dev, 0); | ||
4523 | crtc = intel_get_crtc_for_plane(dev, 0); | ||
4524 | if (crtc->enabled && crtc->fb) { | ||
4525 | planea_wm = intel_calculate_wm(crtc->mode.clock, | ||
4526 | wm_info, fifo_size, | ||
4527 | crtc->fb->bits_per_pixel / 8, | ||
4528 | latency_ns); | ||
4529 | enabled = crtc; | ||
4530 | } else | ||
4531 | planea_wm = fifo_size - wm_info->guard_size; | ||
4532 | |||
4533 | fifo_size = dev_priv->display.get_fifo_size(dev, 1); | ||
4534 | crtc = intel_get_crtc_for_plane(dev, 1); | ||
4535 | if (crtc->enabled && crtc->fb) { | ||
4536 | planeb_wm = intel_calculate_wm(crtc->mode.clock, | ||
4537 | wm_info, fifo_size, | ||
4538 | crtc->fb->bits_per_pixel / 8, | ||
4539 | latency_ns); | ||
4540 | if (enabled == NULL) | ||
4541 | enabled = crtc; | ||
4542 | else | ||
4543 | enabled = NULL; | ||
4544 | } else | ||
4545 | planeb_wm = fifo_size - wm_info->guard_size; | ||
4546 | |||
4547 | DRM_DEBUG_KMS("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm); | ||
4548 | |||
4549 | /* | ||
4550 | * Overlay gets an aggressive default since video jitter is bad. | ||
4551 | */ | ||
4552 | cwm = 2; | ||
4553 | |||
4554 | /* Play safe and disable self-refresh before adjusting watermarks. */ | ||
4555 | if (IS_I945G(dev) || IS_I945GM(dev)) | ||
4556 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN_MASK | 0); | ||
4557 | else if (IS_I915GM(dev)) | ||
4558 | I915_WRITE(INSTPM, I915_READ(INSTPM) & ~INSTPM_SELF_EN); | ||
4559 | |||
4560 | /* Calc sr entries for one plane configs */ | ||
4561 | if (HAS_FW_BLC(dev) && enabled) { | ||
4562 | /* self-refresh has much higher latency */ | ||
4563 | static const int sr_latency_ns = 6000; | ||
4564 | int clock = enabled->mode.clock; | ||
4565 | int htotal = enabled->mode.htotal; | ||
4566 | int hdisplay = enabled->mode.hdisplay; | ||
4567 | int pixel_size = enabled->fb->bits_per_pixel / 8; | ||
4568 | unsigned long line_time_us; | ||
4569 | int entries; | ||
4570 | |||
4571 | line_time_us = (htotal * 1000) / clock; | ||
4572 | |||
4573 | /* Use ns/us then divide to preserve precision */ | ||
4574 | entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * | ||
4575 | pixel_size * hdisplay; | ||
4576 | entries = DIV_ROUND_UP(entries, wm_info->cacheline_size); | ||
4577 | DRM_DEBUG_KMS("self-refresh entries: %d\n", entries); | ||
4578 | srwm = wm_info->fifo_size - entries; | ||
4579 | if (srwm < 0) | ||
4580 | srwm = 1; | ||
4581 | |||
4582 | if (IS_I945G(dev) || IS_I945GM(dev)) | ||
4583 | I915_WRITE(FW_BLC_SELF, | ||
4584 | FW_BLC_SELF_FIFO_MASK | (srwm & 0xff)); | ||
4585 | else if (IS_I915GM(dev)) | ||
4586 | I915_WRITE(FW_BLC_SELF, srwm & 0x3f); | ||
4587 | } | ||
4588 | |||
4589 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n", | ||
4590 | planea_wm, planeb_wm, cwm, srwm); | ||
4591 | |||
4592 | fwater_lo = ((planeb_wm & 0x3f) << 16) | (planea_wm & 0x3f); | ||
4593 | fwater_hi = (cwm & 0x1f); | ||
4594 | |||
4595 | /* Set request length to 8 cachelines per fetch */ | ||
4596 | fwater_lo = fwater_lo | (1 << 24) | (1 << 8); | ||
4597 | fwater_hi = fwater_hi | (1 << 8); | ||
4598 | |||
4599 | I915_WRITE(FW_BLC, fwater_lo); | ||
4600 | I915_WRITE(FW_BLC2, fwater_hi); | ||
4601 | |||
4602 | if (HAS_FW_BLC(dev)) { | ||
4603 | if (enabled) { | ||
4604 | if (IS_I945G(dev) || IS_I945GM(dev)) | ||
4605 | I915_WRITE(FW_BLC_SELF, | ||
4606 | FW_BLC_SELF_EN_MASK | FW_BLC_SELF_EN); | ||
4607 | else if (IS_I915GM(dev)) | ||
4608 | I915_WRITE(INSTPM, I915_READ(INSTPM) | INSTPM_SELF_EN); | ||
4609 | DRM_DEBUG_KMS("memory self refresh enabled\n"); | ||
4610 | } else | ||
4611 | DRM_DEBUG_KMS("memory self refresh disabled\n"); | ||
4612 | } | ||
4613 | } | ||
4614 | |||
4615 | static void i830_update_wm(struct drm_device *dev) | ||
4616 | { | ||
4617 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
4618 | struct drm_crtc *crtc; | ||
4619 | uint32_t fwater_lo; | ||
4620 | int planea_wm; | ||
4621 | |||
4622 | crtc = single_enabled_crtc(dev); | ||
4623 | if (crtc == NULL) | ||
4624 | return; | ||
4625 | |||
4626 | planea_wm = intel_calculate_wm(crtc->mode.clock, &i830_wm_info, | ||
4627 | dev_priv->display.get_fifo_size(dev, 0), | ||
4628 | crtc->fb->bits_per_pixel / 8, | ||
4629 | latency_ns); | ||
4630 | fwater_lo = I915_READ(FW_BLC) & ~0xfff; | ||
4631 | fwater_lo |= (3<<8) | planea_wm; | ||
4632 | |||
4633 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: %d\n", planea_wm); | ||
4634 | |||
4635 | I915_WRITE(FW_BLC, fwater_lo); | ||
4636 | } | ||
4637 | |||
4638 | #define ILK_LP0_PLANE_LATENCY 700 | ||
4639 | #define ILK_LP0_CURSOR_LATENCY 1300 | ||
4640 | |||
4641 | /* | ||
4642 | * Check the wm result. | ||
4643 | * | ||
4644 | * If any calculated watermark values is larger than the maximum value that | ||
4645 | * can be programmed into the associated watermark register, that watermark | ||
4646 | * must be disabled. | ||
4647 | */ | ||
4648 | static bool ironlake_check_srwm(struct drm_device *dev, int level, | ||
4649 | int fbc_wm, int display_wm, int cursor_wm, | ||
4650 | const struct intel_watermark_params *display, | ||
4651 | const struct intel_watermark_params *cursor) | ||
4652 | { | ||
4653 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
4654 | |||
4655 | DRM_DEBUG_KMS("watermark %d: display plane %d, fbc lines %d," | ||
4656 | " cursor %d\n", level, display_wm, fbc_wm, cursor_wm); | ||
4657 | |||
4658 | if (fbc_wm > SNB_FBC_MAX_SRWM) { | ||
4659 | DRM_DEBUG_KMS("fbc watermark(%d) is too large(%d), disabling wm%d+\n", | ||
4660 | fbc_wm, SNB_FBC_MAX_SRWM, level); | ||
4661 | |||
4662 | /* fbc has it's own way to disable FBC WM */ | ||
4663 | I915_WRITE(DISP_ARB_CTL, | ||
4664 | I915_READ(DISP_ARB_CTL) | DISP_FBC_WM_DIS); | ||
4665 | return false; | ||
4666 | } | ||
4667 | |||
4668 | if (display_wm > display->max_wm) { | ||
4669 | DRM_DEBUG_KMS("display watermark(%d) is too large(%d), disabling wm%d+\n", | ||
4670 | display_wm, SNB_DISPLAY_MAX_SRWM, level); | ||
4671 | return false; | ||
4672 | } | ||
4673 | |||
4674 | if (cursor_wm > cursor->max_wm) { | ||
4675 | DRM_DEBUG_KMS("cursor watermark(%d) is too large(%d), disabling wm%d+\n", | ||
4676 | cursor_wm, SNB_CURSOR_MAX_SRWM, level); | ||
4677 | return false; | ||
4678 | } | ||
4679 | |||
4680 | if (!(fbc_wm || display_wm || cursor_wm)) { | ||
4681 | DRM_DEBUG_KMS("latency %d is 0, disabling wm%d+\n", level, level); | ||
4682 | return false; | ||
4683 | } | ||
4684 | |||
4685 | return true; | ||
4686 | } | ||
4687 | |||
4688 | /* | ||
4689 | * Compute watermark values of WM[1-3], | ||
4690 | */ | ||
4691 | static bool ironlake_compute_srwm(struct drm_device *dev, int level, int plane, | ||
4692 | int latency_ns, | ||
4693 | const struct intel_watermark_params *display, | ||
4694 | const struct intel_watermark_params *cursor, | ||
4695 | int *fbc_wm, int *display_wm, int *cursor_wm) | ||
4696 | { | ||
4697 | struct drm_crtc *crtc; | ||
4698 | unsigned long line_time_us; | ||
4699 | int hdisplay, htotal, pixel_size, clock; | ||
4700 | int line_count, line_size; | ||
4701 | int small, large; | ||
4702 | int entries; | ||
4703 | |||
4704 | if (!latency_ns) { | ||
4705 | *fbc_wm = *display_wm = *cursor_wm = 0; | ||
4706 | return false; | ||
4707 | } | ||
4708 | |||
4709 | crtc = intel_get_crtc_for_plane(dev, plane); | ||
4710 | hdisplay = crtc->mode.hdisplay; | ||
4711 | htotal = crtc->mode.htotal; | ||
4712 | clock = crtc->mode.clock; | ||
4713 | pixel_size = crtc->fb->bits_per_pixel / 8; | ||
4714 | |||
4715 | line_time_us = (htotal * 1000) / clock; | ||
4716 | line_count = (latency_ns / line_time_us + 1000) / 1000; | ||
4717 | line_size = hdisplay * pixel_size; | ||
4718 | |||
4719 | /* Use the minimum of the small and large buffer method for primary */ | ||
4720 | small = ((clock * pixel_size / 1000) * latency_ns) / 1000; | ||
4721 | large = line_count * line_size; | ||
4722 | |||
4723 | entries = DIV_ROUND_UP(min(small, large), display->cacheline_size); | ||
4724 | *display_wm = entries + display->guard_size; | ||
4725 | |||
4726 | /* | ||
4727 | * Spec says: | ||
4728 | * FBC WM = ((Final Primary WM * 64) / number of bytes per line) + 2 | ||
4729 | */ | ||
4730 | *fbc_wm = DIV_ROUND_UP(*display_wm * 64, line_size) + 2; | ||
4731 | |||
4732 | /* calculate the self-refresh watermark for display cursor */ | ||
4733 | entries = line_count * pixel_size * 64; | ||
4734 | entries = DIV_ROUND_UP(entries, cursor->cacheline_size); | ||
4735 | *cursor_wm = entries + cursor->guard_size; | ||
4736 | |||
4737 | return ironlake_check_srwm(dev, level, | ||
4738 | *fbc_wm, *display_wm, *cursor_wm, | ||
4739 | display, cursor); | ||
4740 | } | ||
4741 | |||
4742 | static void ironlake_update_wm(struct drm_device *dev) | ||
4743 | { | ||
4744 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
4745 | int fbc_wm, plane_wm, cursor_wm; | ||
4746 | unsigned int enabled; | ||
4747 | |||
4748 | enabled = 0; | ||
4749 | if (g4x_compute_wm0(dev, 0, | ||
4750 | &ironlake_display_wm_info, | ||
4751 | ILK_LP0_PLANE_LATENCY, | ||
4752 | &ironlake_cursor_wm_info, | ||
4753 | ILK_LP0_CURSOR_LATENCY, | ||
4754 | &plane_wm, &cursor_wm)) { | ||
4755 | I915_WRITE(WM0_PIPEA_ILK, | ||
4756 | (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); | ||
4757 | DRM_DEBUG_KMS("FIFO watermarks For pipe A -" | ||
4758 | " plane %d, " "cursor: %d\n", | ||
4759 | plane_wm, cursor_wm); | ||
4760 | enabled |= 1; | ||
4761 | } | ||
4762 | |||
4763 | if (g4x_compute_wm0(dev, 1, | ||
4764 | &ironlake_display_wm_info, | ||
4765 | ILK_LP0_PLANE_LATENCY, | ||
4766 | &ironlake_cursor_wm_info, | ||
4767 | ILK_LP0_CURSOR_LATENCY, | ||
4768 | &plane_wm, &cursor_wm)) { | ||
4769 | I915_WRITE(WM0_PIPEB_ILK, | ||
4770 | (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); | ||
4771 | DRM_DEBUG_KMS("FIFO watermarks For pipe B -" | ||
4772 | " plane %d, cursor: %d\n", | ||
4773 | plane_wm, cursor_wm); | ||
4774 | enabled |= 2; | ||
4775 | } | ||
4776 | |||
4777 | /* | ||
4778 | * Calculate and update the self-refresh watermark only when one | ||
4779 | * display plane is used. | ||
4780 | */ | ||
4781 | I915_WRITE(WM3_LP_ILK, 0); | ||
4782 | I915_WRITE(WM2_LP_ILK, 0); | ||
4783 | I915_WRITE(WM1_LP_ILK, 0); | ||
4784 | |||
4785 | if (!single_plane_enabled(enabled)) | ||
4786 | return; | ||
4787 | enabled = ffs(enabled) - 1; | ||
4788 | |||
4789 | /* WM1 */ | ||
4790 | if (!ironlake_compute_srwm(dev, 1, enabled, | ||
4791 | ILK_READ_WM1_LATENCY() * 500, | ||
4792 | &ironlake_display_srwm_info, | ||
4793 | &ironlake_cursor_srwm_info, | ||
4794 | &fbc_wm, &plane_wm, &cursor_wm)) | ||
4795 | return; | ||
4796 | |||
4797 | I915_WRITE(WM1_LP_ILK, | ||
4798 | WM1_LP_SR_EN | | ||
4799 | (ILK_READ_WM1_LATENCY() << WM1_LP_LATENCY_SHIFT) | | ||
4800 | (fbc_wm << WM1_LP_FBC_SHIFT) | | ||
4801 | (plane_wm << WM1_LP_SR_SHIFT) | | ||
4802 | cursor_wm); | ||
4803 | |||
4804 | /* WM2 */ | ||
4805 | if (!ironlake_compute_srwm(dev, 2, enabled, | ||
4806 | ILK_READ_WM2_LATENCY() * 500, | ||
4807 | &ironlake_display_srwm_info, | ||
4808 | &ironlake_cursor_srwm_info, | ||
4809 | &fbc_wm, &plane_wm, &cursor_wm)) | ||
4810 | return; | ||
4811 | |||
4812 | I915_WRITE(WM2_LP_ILK, | ||
4813 | WM2_LP_EN | | ||
4814 | (ILK_READ_WM2_LATENCY() << WM1_LP_LATENCY_SHIFT) | | ||
4815 | (fbc_wm << WM1_LP_FBC_SHIFT) | | ||
4816 | (plane_wm << WM1_LP_SR_SHIFT) | | ||
4817 | cursor_wm); | ||
4818 | |||
4819 | /* | ||
4820 | * WM3 is unsupported on ILK, probably because we don't have latency | ||
4821 | * data for that power state | ||
4822 | */ | ||
4823 | } | ||
4824 | |||
4825 | void sandybridge_update_wm(struct drm_device *dev) | ||
4826 | { | ||
4827 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
4828 | int latency = SNB_READ_WM0_LATENCY() * 100; /* In unit 0.1us */ | ||
4829 | u32 val; | ||
4830 | int fbc_wm, plane_wm, cursor_wm; | ||
4831 | unsigned int enabled; | ||
4832 | |||
4833 | enabled = 0; | ||
4834 | if (g4x_compute_wm0(dev, 0, | ||
4835 | &sandybridge_display_wm_info, latency, | ||
4836 | &sandybridge_cursor_wm_info, latency, | ||
4837 | &plane_wm, &cursor_wm)) { | ||
4838 | val = I915_READ(WM0_PIPEA_ILK); | ||
4839 | val &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK); | ||
4840 | I915_WRITE(WM0_PIPEA_ILK, val | | ||
4841 | ((plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm)); | ||
4842 | DRM_DEBUG_KMS("FIFO watermarks For pipe A -" | ||
4843 | " plane %d, " "cursor: %d\n", | ||
4844 | plane_wm, cursor_wm); | ||
4845 | enabled |= 1; | ||
4846 | } | ||
4847 | |||
4848 | if (g4x_compute_wm0(dev, 1, | ||
4849 | &sandybridge_display_wm_info, latency, | ||
4850 | &sandybridge_cursor_wm_info, latency, | ||
4851 | &plane_wm, &cursor_wm)) { | ||
4852 | val = I915_READ(WM0_PIPEB_ILK); | ||
4853 | val &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK); | ||
4854 | I915_WRITE(WM0_PIPEB_ILK, val | | ||
4855 | ((plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm)); | ||
4856 | DRM_DEBUG_KMS("FIFO watermarks For pipe B -" | ||
4857 | " plane %d, cursor: %d\n", | ||
4858 | plane_wm, cursor_wm); | ||
4859 | enabled |= 2; | ||
4860 | } | ||
4861 | |||
4862 | /* IVB has 3 pipes */ | ||
4863 | if (IS_IVYBRIDGE(dev) && | ||
4864 | g4x_compute_wm0(dev, 2, | ||
4865 | &sandybridge_display_wm_info, latency, | ||
4866 | &sandybridge_cursor_wm_info, latency, | ||
4867 | &plane_wm, &cursor_wm)) { | ||
4868 | val = I915_READ(WM0_PIPEC_IVB); | ||
4869 | val &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK); | ||
4870 | I915_WRITE(WM0_PIPEC_IVB, val | | ||
4871 | ((plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm)); | ||
4872 | DRM_DEBUG_KMS("FIFO watermarks For pipe C -" | ||
4873 | " plane %d, cursor: %d\n", | ||
4874 | plane_wm, cursor_wm); | ||
4875 | enabled |= 3; | ||
4876 | } | ||
4877 | |||
4878 | /* | ||
4879 | * Calculate and update the self-refresh watermark only when one | ||
4880 | * display plane is used. | ||
4881 | * | ||
4882 | * SNB support 3 levels of watermark. | ||
4883 | * | ||
4884 | * WM1/WM2/WM2 watermarks have to be enabled in the ascending order, | ||
4885 | * and disabled in the descending order | ||
4886 | * | ||
4887 | */ | ||
4888 | I915_WRITE(WM3_LP_ILK, 0); | ||
4889 | I915_WRITE(WM2_LP_ILK, 0); | ||
4890 | I915_WRITE(WM1_LP_ILK, 0); | ||
4891 | |||
4892 | if (!single_plane_enabled(enabled) || | ||
4893 | dev_priv->sprite_scaling_enabled) | ||
4894 | return; | ||
4895 | enabled = ffs(enabled) - 1; | ||
4896 | |||
4897 | /* WM1 */ | ||
4898 | if (!ironlake_compute_srwm(dev, 1, enabled, | ||
4899 | SNB_READ_WM1_LATENCY() * 500, | ||
4900 | &sandybridge_display_srwm_info, | ||
4901 | &sandybridge_cursor_srwm_info, | ||
4902 | &fbc_wm, &plane_wm, &cursor_wm)) | ||
4903 | return; | ||
4904 | |||
4905 | I915_WRITE(WM1_LP_ILK, | ||
4906 | WM1_LP_SR_EN | | ||
4907 | (SNB_READ_WM1_LATENCY() << WM1_LP_LATENCY_SHIFT) | | ||
4908 | (fbc_wm << WM1_LP_FBC_SHIFT) | | ||
4909 | (plane_wm << WM1_LP_SR_SHIFT) | | ||
4910 | cursor_wm); | ||
4911 | |||
4912 | /* WM2 */ | ||
4913 | if (!ironlake_compute_srwm(dev, 2, enabled, | ||
4914 | SNB_READ_WM2_LATENCY() * 500, | ||
4915 | &sandybridge_display_srwm_info, | ||
4916 | &sandybridge_cursor_srwm_info, | ||
4917 | &fbc_wm, &plane_wm, &cursor_wm)) | ||
4918 | return; | ||
4919 | |||
4920 | I915_WRITE(WM2_LP_ILK, | ||
4921 | WM2_LP_EN | | ||
4922 | (SNB_READ_WM2_LATENCY() << WM1_LP_LATENCY_SHIFT) | | ||
4923 | (fbc_wm << WM1_LP_FBC_SHIFT) | | ||
4924 | (plane_wm << WM1_LP_SR_SHIFT) | | ||
4925 | cursor_wm); | ||
4926 | |||
4927 | /* WM3 */ | ||
4928 | if (!ironlake_compute_srwm(dev, 3, enabled, | ||
4929 | SNB_READ_WM3_LATENCY() * 500, | ||
4930 | &sandybridge_display_srwm_info, | ||
4931 | &sandybridge_cursor_srwm_info, | ||
4932 | &fbc_wm, &plane_wm, &cursor_wm)) | ||
4933 | return; | ||
4934 | |||
4935 | I915_WRITE(WM3_LP_ILK, | ||
4936 | WM3_LP_EN | | ||
4937 | (SNB_READ_WM3_LATENCY() << WM1_LP_LATENCY_SHIFT) | | ||
4938 | (fbc_wm << WM1_LP_FBC_SHIFT) | | ||
4939 | (plane_wm << WM1_LP_SR_SHIFT) | | ||
4940 | cursor_wm); | ||
4941 | } | ||
4942 | |||
4943 | static bool | ||
4944 | sandybridge_compute_sprite_wm(struct drm_device *dev, int plane, | ||
4945 | uint32_t sprite_width, int pixel_size, | ||
4946 | const struct intel_watermark_params *display, | ||
4947 | int display_latency_ns, int *sprite_wm) | ||
4948 | { | ||
4949 | struct drm_crtc *crtc; | ||
4950 | int clock; | ||
4951 | int entries, tlb_miss; | ||
4952 | |||
4953 | crtc = intel_get_crtc_for_plane(dev, plane); | ||
4954 | if (crtc->fb == NULL || !crtc->enabled) { | ||
4955 | *sprite_wm = display->guard_size; | ||
4956 | return false; | ||
4957 | } | ||
4958 | |||
4959 | clock = crtc->mode.clock; | ||
4960 | |||
4961 | /* Use the small buffer method to calculate the sprite watermark */ | ||
4962 | entries = ((clock * pixel_size / 1000) * display_latency_ns) / 1000; | ||
4963 | tlb_miss = display->fifo_size*display->cacheline_size - | ||
4964 | sprite_width * 8; | ||
4965 | if (tlb_miss > 0) | ||
4966 | entries += tlb_miss; | ||
4967 | entries = DIV_ROUND_UP(entries, display->cacheline_size); | ||
4968 | *sprite_wm = entries + display->guard_size; | ||
4969 | if (*sprite_wm > (int)display->max_wm) | ||
4970 | *sprite_wm = display->max_wm; | ||
4971 | |||
4972 | return true; | ||
4973 | } | ||
4974 | |||
4975 | static bool | ||
4976 | sandybridge_compute_sprite_srwm(struct drm_device *dev, int plane, | ||
4977 | uint32_t sprite_width, int pixel_size, | ||
4978 | const struct intel_watermark_params *display, | ||
4979 | int latency_ns, int *sprite_wm) | ||
4980 | { | ||
4981 | struct drm_crtc *crtc; | ||
4982 | unsigned long line_time_us; | ||
4983 | int clock; | ||
4984 | int line_count, line_size; | ||
4985 | int small, large; | ||
4986 | int entries; | ||
4987 | |||
4988 | if (!latency_ns) { | ||
4989 | *sprite_wm = 0; | ||
4990 | return false; | ||
4991 | } | ||
4992 | |||
4993 | crtc = intel_get_crtc_for_plane(dev, plane); | ||
4994 | clock = crtc->mode.clock; | ||
4995 | if (!clock) { | ||
4996 | *sprite_wm = 0; | ||
4997 | return false; | ||
4998 | } | ||
4999 | |||
5000 | line_time_us = (sprite_width * 1000) / clock; | ||
5001 | if (!line_time_us) { | ||
5002 | *sprite_wm = 0; | ||
5003 | return false; | ||
5004 | } | ||
5005 | |||
5006 | line_count = (latency_ns / line_time_us + 1000) / 1000; | ||
5007 | line_size = sprite_width * pixel_size; | ||
5008 | |||
5009 | /* Use the minimum of the small and large buffer method for primary */ | ||
5010 | small = ((clock * pixel_size / 1000) * latency_ns) / 1000; | ||
5011 | large = line_count * line_size; | ||
5012 | |||
5013 | entries = DIV_ROUND_UP(min(small, large), display->cacheline_size); | ||
5014 | *sprite_wm = entries + display->guard_size; | ||
5015 | |||
5016 | return *sprite_wm > 0x3ff ? false : true; | ||
5017 | } | ||
5018 | |||
5019 | static void sandybridge_update_sprite_wm(struct drm_device *dev, int pipe, | ||
5020 | uint32_t sprite_width, int pixel_size) | ||
5021 | { | ||
5022 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
5023 | int latency = SNB_READ_WM0_LATENCY() * 100; /* In unit 0.1us */ | ||
5024 | u32 val; | ||
5025 | int sprite_wm, reg; | ||
5026 | int ret; | ||
5027 | |||
5028 | switch (pipe) { | ||
5029 | case 0: | ||
5030 | reg = WM0_PIPEA_ILK; | ||
5031 | break; | ||
5032 | case 1: | ||
5033 | reg = WM0_PIPEB_ILK; | ||
5034 | break; | ||
5035 | case 2: | ||
5036 | reg = WM0_PIPEC_IVB; | ||
5037 | break; | ||
5038 | default: | ||
5039 | return; /* bad pipe */ | ||
5040 | } | ||
5041 | |||
5042 | ret = sandybridge_compute_sprite_wm(dev, pipe, sprite_width, pixel_size, | ||
5043 | &sandybridge_display_wm_info, | ||
5044 | latency, &sprite_wm); | ||
5045 | if (!ret) { | ||
5046 | DRM_DEBUG_KMS("failed to compute sprite wm for pipe %d\n", | ||
5047 | pipe); | ||
5048 | return; | ||
5049 | } | ||
5050 | |||
5051 | val = I915_READ(reg); | ||
5052 | val &= ~WM0_PIPE_SPRITE_MASK; | ||
5053 | I915_WRITE(reg, val | (sprite_wm << WM0_PIPE_SPRITE_SHIFT)); | ||
5054 | DRM_DEBUG_KMS("sprite watermarks For pipe %d - %d\n", pipe, sprite_wm); | ||
5055 | |||
5056 | |||
5057 | ret = sandybridge_compute_sprite_srwm(dev, pipe, sprite_width, | ||
5058 | pixel_size, | ||
5059 | &sandybridge_display_srwm_info, | ||
5060 | SNB_READ_WM1_LATENCY() * 500, | ||
5061 | &sprite_wm); | ||
5062 | if (!ret) { | ||
5063 | DRM_DEBUG_KMS("failed to compute sprite lp1 wm on pipe %d\n", | ||
5064 | pipe); | ||
5065 | return; | ||
5066 | } | ||
5067 | I915_WRITE(WM1S_LP_ILK, sprite_wm); | ||
5068 | |||
5069 | /* Only IVB has two more LP watermarks for sprite */ | ||
5070 | if (!IS_IVYBRIDGE(dev)) | ||
5071 | return; | ||
5072 | |||
5073 | ret = sandybridge_compute_sprite_srwm(dev, pipe, sprite_width, | ||
5074 | pixel_size, | ||
5075 | &sandybridge_display_srwm_info, | ||
5076 | SNB_READ_WM2_LATENCY() * 500, | ||
5077 | &sprite_wm); | ||
5078 | if (!ret) { | ||
5079 | DRM_DEBUG_KMS("failed to compute sprite lp2 wm on pipe %d\n", | ||
5080 | pipe); | ||
5081 | return; | ||
5082 | } | ||
5083 | I915_WRITE(WM2S_LP_IVB, sprite_wm); | ||
5084 | |||
5085 | ret = sandybridge_compute_sprite_srwm(dev, pipe, sprite_width, | ||
5086 | pixel_size, | ||
5087 | &sandybridge_display_srwm_info, | ||
5088 | SNB_READ_WM3_LATENCY() * 500, | ||
5089 | &sprite_wm); | ||
5090 | if (!ret) { | ||
5091 | DRM_DEBUG_KMS("failed to compute sprite lp3 wm on pipe %d\n", | ||
5092 | pipe); | ||
5093 | return; | ||
5094 | } | ||
5095 | I915_WRITE(WM3S_LP_IVB, sprite_wm); | ||
5096 | } | ||
5097 | |||
5098 | /** | ||
5099 | * intel_update_watermarks - update FIFO watermark values based on current modes | ||
5100 | * | ||
5101 | * Calculate watermark values for the various WM regs based on current mode | ||
5102 | * and plane configuration. | ||
5103 | * | ||
5104 | * There are several cases to deal with here: | ||
5105 | * - normal (i.e. non-self-refresh) | ||
5106 | * - self-refresh (SR) mode | ||
5107 | * - lines are large relative to FIFO size (buffer can hold up to 2) | ||
5108 | * - lines are small relative to FIFO size (buffer can hold more than 2 | ||
5109 | * lines), so need to account for TLB latency | ||
5110 | * | ||
5111 | * The normal calculation is: | ||
5112 | * watermark = dotclock * bytes per pixel * latency | ||
5113 | * where latency is platform & configuration dependent (we assume pessimal | ||
5114 | * values here). | ||
5115 | * | ||
5116 | * The SR calculation is: | ||
5117 | * watermark = (trunc(latency/line time)+1) * surface width * | ||
5118 | * bytes per pixel | ||
5119 | * where | ||
5120 | * line time = htotal / dotclock | ||
5121 | * surface width = hdisplay for normal plane and 64 for cursor | ||
5122 | * and latency is assumed to be high, as above. | ||
5123 | * | ||
5124 | * The final value programmed to the register should always be rounded up, | ||
5125 | * and include an extra 2 entries to account for clock crossings. | ||
5126 | * | ||
5127 | * We don't use the sprite, so we can ignore that. And on Crestline we have | ||
5128 | * to set the non-SR watermarks to 8. | ||
5129 | */ | ||
5130 | static void intel_update_watermarks(struct drm_device *dev) | ||
5131 | { | ||
5132 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
5133 | |||
5134 | if (dev_priv->display.update_wm) | ||
5135 | dev_priv->display.update_wm(dev); | ||
5136 | } | ||
5137 | |||
5138 | void intel_update_sprite_watermarks(struct drm_device *dev, int pipe, | ||
5139 | uint32_t sprite_width, int pixel_size) | ||
5140 | { | ||
5141 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
5142 | |||
5143 | if (dev_priv->display.update_sprite_wm) | ||
5144 | dev_priv->display.update_sprite_wm(dev, pipe, sprite_width, | ||
5145 | pixel_size); | ||
5146 | } | ||
5147 | |||
5148 | static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv) | 3189 | static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv) |
5149 | { | 3190 | { |
5150 | if (i915_panel_use_ssc >= 0) | 3191 | if (i915_panel_use_ssc >= 0) |
@@ -5375,7 +3416,7 @@ static void intel_update_lvds(struct drm_crtc *crtc, intel_clock_t *clock, | |||
5375 | struct drm_i915_private *dev_priv = dev->dev_private; | 3416 | struct drm_i915_private *dev_priv = dev->dev_private; |
5376 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 3417 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
5377 | int pipe = intel_crtc->pipe; | 3418 | int pipe = intel_crtc->pipe; |
5378 | u32 temp, lvds_sync = 0; | 3419 | u32 temp; |
5379 | 3420 | ||
5380 | temp = I915_READ(LVDS); | 3421 | temp = I915_READ(LVDS); |
5381 | temp |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP; | 3422 | temp |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP; |
@@ -5405,22 +3446,11 @@ static void intel_update_lvds(struct drm_crtc *crtc, intel_clock_t *clock, | |||
5405 | else | 3446 | else |
5406 | temp &= ~LVDS_ENABLE_DITHER; | 3447 | temp &= ~LVDS_ENABLE_DITHER; |
5407 | } | 3448 | } |
3449 | temp &= ~(LVDS_HSYNC_POLARITY | LVDS_VSYNC_POLARITY); | ||
5408 | if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) | 3450 | if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) |
5409 | lvds_sync |= LVDS_HSYNC_POLARITY; | 3451 | temp |= LVDS_HSYNC_POLARITY; |
5410 | if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) | 3452 | if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) |
5411 | lvds_sync |= LVDS_VSYNC_POLARITY; | 3453 | temp |= LVDS_VSYNC_POLARITY; |
5412 | if ((temp & (LVDS_HSYNC_POLARITY | LVDS_VSYNC_POLARITY)) | ||
5413 | != lvds_sync) { | ||
5414 | char flags[2] = "-+"; | ||
5415 | DRM_INFO("Changing LVDS panel from " | ||
5416 | "(%chsync, %cvsync) to (%chsync, %cvsync)\n", | ||
5417 | flags[!(temp & LVDS_HSYNC_POLARITY)], | ||
5418 | flags[!(temp & LVDS_VSYNC_POLARITY)], | ||
5419 | flags[!(lvds_sync & LVDS_HSYNC_POLARITY)], | ||
5420 | flags[!(lvds_sync & LVDS_VSYNC_POLARITY)]); | ||
5421 | temp &= ~(LVDS_HSYNC_POLARITY | LVDS_VSYNC_POLARITY); | ||
5422 | temp |= lvds_sync; | ||
5423 | } | ||
5424 | I915_WRITE(LVDS, temp); | 3454 | I915_WRITE(LVDS, temp); |
5425 | } | 3455 | } |
5426 | 3456 | ||
@@ -5965,17 +3995,16 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
5965 | u32 dpll, fp = 0, fp2 = 0, dspcntr, pipeconf; | 3995 | u32 dpll, fp = 0, fp2 = 0, dspcntr, pipeconf; |
5966 | bool ok, has_reduced_clock = false, is_sdvo = false; | 3996 | bool ok, has_reduced_clock = false, is_sdvo = false; |
5967 | bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; | 3997 | bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; |
5968 | struct intel_encoder *has_edp_encoder = NULL; | ||
5969 | struct drm_mode_config *mode_config = &dev->mode_config; | 3998 | struct drm_mode_config *mode_config = &dev->mode_config; |
5970 | struct intel_encoder *encoder; | 3999 | struct intel_encoder *encoder, *edp_encoder = NULL; |
5971 | const intel_limit_t *limit; | 4000 | const intel_limit_t *limit; |
5972 | int ret; | 4001 | int ret; |
5973 | struct fdi_m_n m_n = {0}; | 4002 | struct fdi_m_n m_n = {0}; |
5974 | u32 temp; | 4003 | u32 temp; |
5975 | u32 lvds_sync = 0; | ||
5976 | int target_clock, pixel_multiplier, lane, link_bw, factor; | 4004 | int target_clock, pixel_multiplier, lane, link_bw, factor; |
5977 | unsigned int pipe_bpp; | 4005 | unsigned int pipe_bpp; |
5978 | bool dither; | 4006 | bool dither; |
4007 | bool is_cpu_edp = false, is_pch_edp = false; | ||
5979 | 4008 | ||
5980 | list_for_each_entry(encoder, &mode_config->encoder_list, base.head) { | 4009 | list_for_each_entry(encoder, &mode_config->encoder_list, base.head) { |
5981 | if (encoder->base.crtc != crtc) | 4010 | if (encoder->base.crtc != crtc) |
@@ -6001,7 +4030,12 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
6001 | is_dp = true; | 4030 | is_dp = true; |
6002 | break; | 4031 | break; |
6003 | case INTEL_OUTPUT_EDP: | 4032 | case INTEL_OUTPUT_EDP: |
6004 | has_edp_encoder = encoder; | 4033 | is_dp = true; |
4034 | if (intel_encoder_is_pch_edp(&encoder->base)) | ||
4035 | is_pch_edp = true; | ||
4036 | else | ||
4037 | is_cpu_edp = true; | ||
4038 | edp_encoder = encoder; | ||
6005 | break; | 4039 | break; |
6006 | } | 4040 | } |
6007 | 4041 | ||
@@ -6064,15 +4098,13 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
6064 | lane = 0; | 4098 | lane = 0; |
6065 | /* CPU eDP doesn't require FDI link, so just set DP M/N | 4099 | /* CPU eDP doesn't require FDI link, so just set DP M/N |
6066 | according to current link config */ | 4100 | according to current link config */ |
6067 | if (has_edp_encoder && | 4101 | if (is_cpu_edp) { |
6068 | !intel_encoder_is_pch_edp(&has_edp_encoder->base)) { | ||
6069 | target_clock = mode->clock; | 4102 | target_clock = mode->clock; |
6070 | intel_edp_link_config(has_edp_encoder, | 4103 | intel_edp_link_config(edp_encoder, &lane, &link_bw); |
6071 | &lane, &link_bw); | ||
6072 | } else { | 4104 | } else { |
6073 | /* [e]DP over FDI requires target mode clock | 4105 | /* [e]DP over FDI requires target mode clock |
6074 | instead of link clock */ | 4106 | instead of link clock */ |
6075 | if (is_dp || intel_encoder_is_pch_edp(&has_edp_encoder->base)) | 4107 | if (is_dp) |
6076 | target_clock = mode->clock; | 4108 | target_clock = mode->clock; |
6077 | else | 4109 | else |
6078 | target_clock = adjusted_mode->clock; | 4110 | target_clock = adjusted_mode->clock; |
@@ -6163,7 +4195,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
6163 | } | 4195 | } |
6164 | dpll |= DPLL_DVO_HIGH_SPEED; | 4196 | dpll |= DPLL_DVO_HIGH_SPEED; |
6165 | } | 4197 | } |
6166 | if (is_dp || intel_encoder_is_pch_edp(&has_edp_encoder->base)) | 4198 | if (is_dp && !is_cpu_edp) |
6167 | dpll |= DPLL_DVO_HIGH_SPEED; | 4199 | dpll |= DPLL_DVO_HIGH_SPEED; |
6168 | 4200 | ||
6169 | /* compute bitmask from p1 value */ | 4201 | /* compute bitmask from p1 value */ |
@@ -6208,8 +4240,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
6208 | 4240 | ||
6209 | /* PCH eDP needs FDI, but CPU eDP does not */ | 4241 | /* PCH eDP needs FDI, but CPU eDP does not */ |
6210 | if (!intel_crtc->no_pll) { | 4242 | if (!intel_crtc->no_pll) { |
6211 | if (!has_edp_encoder || | 4243 | if (!is_cpu_edp) { |
6212 | intel_encoder_is_pch_edp(&has_edp_encoder->base)) { | ||
6213 | I915_WRITE(PCH_FP0(pipe), fp); | 4244 | I915_WRITE(PCH_FP0(pipe), fp); |
6214 | I915_WRITE(PCH_DPLL(pipe), dpll & ~DPLL_VCO_ENABLE); | 4245 | I915_WRITE(PCH_DPLL(pipe), dpll & ~DPLL_VCO_ENABLE); |
6215 | 4246 | ||
@@ -6262,22 +4293,11 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
6262 | * appropriately here, but we need to look more thoroughly into how | 4293 | * appropriately here, but we need to look more thoroughly into how |
6263 | * panels behave in the two modes. | 4294 | * panels behave in the two modes. |
6264 | */ | 4295 | */ |
4296 | temp &= ~(LVDS_HSYNC_POLARITY | LVDS_VSYNC_POLARITY); | ||
6265 | if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) | 4297 | if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) |
6266 | lvds_sync |= LVDS_HSYNC_POLARITY; | 4298 | temp |= LVDS_HSYNC_POLARITY; |
6267 | if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) | 4299 | if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) |
6268 | lvds_sync |= LVDS_VSYNC_POLARITY; | 4300 | temp |= LVDS_VSYNC_POLARITY; |
6269 | if ((temp & (LVDS_HSYNC_POLARITY | LVDS_VSYNC_POLARITY)) | ||
6270 | != lvds_sync) { | ||
6271 | char flags[2] = "-+"; | ||
6272 | DRM_INFO("Changing LVDS panel from " | ||
6273 | "(%chsync, %cvsync) to (%chsync, %cvsync)\n", | ||
6274 | flags[!(temp & LVDS_HSYNC_POLARITY)], | ||
6275 | flags[!(temp & LVDS_VSYNC_POLARITY)], | ||
6276 | flags[!(lvds_sync & LVDS_HSYNC_POLARITY)], | ||
6277 | flags[!(lvds_sync & LVDS_VSYNC_POLARITY)]); | ||
6278 | temp &= ~(LVDS_HSYNC_POLARITY | LVDS_VSYNC_POLARITY); | ||
6279 | temp |= lvds_sync; | ||
6280 | } | ||
6281 | I915_WRITE(PCH_LVDS, temp); | 4301 | I915_WRITE(PCH_LVDS, temp); |
6282 | } | 4302 | } |
6283 | 4303 | ||
@@ -6287,7 +4307,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
6287 | pipeconf |= PIPECONF_DITHER_EN; | 4307 | pipeconf |= PIPECONF_DITHER_EN; |
6288 | pipeconf |= PIPECONF_DITHER_TYPE_SP; | 4308 | pipeconf |= PIPECONF_DITHER_TYPE_SP; |
6289 | } | 4309 | } |
6290 | if (is_dp || intel_encoder_is_pch_edp(&has_edp_encoder->base)) { | 4310 | if (is_dp && !is_cpu_edp) { |
6291 | intel_dp_set_m_n(crtc, mode, adjusted_mode); | 4311 | intel_dp_set_m_n(crtc, mode, adjusted_mode); |
6292 | } else { | 4312 | } else { |
6293 | /* For non-DP output, clear any trans DP clock recovery setting.*/ | 4313 | /* For non-DP output, clear any trans DP clock recovery setting.*/ |
@@ -6297,9 +4317,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
6297 | I915_WRITE(TRANSDPLINK_N1(pipe), 0); | 4317 | I915_WRITE(TRANSDPLINK_N1(pipe), 0); |
6298 | } | 4318 | } |
6299 | 4319 | ||
6300 | if (!intel_crtc->no_pll && | 4320 | if (!intel_crtc->no_pll && (!edp_encoder || is_pch_edp)) { |
6301 | (!has_edp_encoder || | ||
6302 | intel_encoder_is_pch_edp(&has_edp_encoder->base))) { | ||
6303 | I915_WRITE(PCH_DPLL(pipe), dpll); | 4321 | I915_WRITE(PCH_DPLL(pipe), dpll); |
6304 | 4322 | ||
6305 | /* Wait for the clocks to stabilize. */ | 4323 | /* Wait for the clocks to stabilize. */ |
@@ -6377,10 +4395,8 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
6377 | I915_WRITE(PIPE_LINK_M1(pipe), m_n.link_m); | 4395 | I915_WRITE(PIPE_LINK_M1(pipe), m_n.link_m); |
6378 | I915_WRITE(PIPE_LINK_N1(pipe), m_n.link_n); | 4396 | I915_WRITE(PIPE_LINK_N1(pipe), m_n.link_n); |
6379 | 4397 | ||
6380 | if (has_edp_encoder && | 4398 | if (is_cpu_edp) |
6381 | !intel_encoder_is_pch_edp(&has_edp_encoder->base)) { | ||
6382 | ironlake_set_pll_edp(crtc, adjusted_mode->clock); | 4399 | ironlake_set_pll_edp(crtc, adjusted_mode->clock); |
6383 | } | ||
6384 | 4400 | ||
6385 | I915_WRITE(PIPECONF(pipe), pipeconf); | 4401 | I915_WRITE(PIPECONF(pipe), pipeconf); |
6386 | POSTING_READ(PIPECONF(pipe)); | 4402 | POSTING_READ(PIPECONF(pipe)); |
@@ -6748,7 +4764,7 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc, | |||
6748 | if (!visible && !intel_crtc->cursor_visible) | 4764 | if (!visible && !intel_crtc->cursor_visible) |
6749 | return; | 4765 | return; |
6750 | 4766 | ||
6751 | if (IS_IVYBRIDGE(dev)) { | 4767 | if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) { |
6752 | I915_WRITE(CURPOS_IVB(pipe), pos); | 4768 | I915_WRITE(CURPOS_IVB(pipe), pos); |
6753 | ivb_update_cursor(crtc, base); | 4769 | ivb_update_cursor(crtc, base); |
6754 | } else { | 4770 | } else { |
@@ -7636,14 +5652,14 @@ static int intel_gen2_queue_flip(struct drm_device *dev, | |||
7636 | 5652 | ||
7637 | ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv)); | 5653 | ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv)); |
7638 | if (ret) | 5654 | if (ret) |
7639 | goto out; | 5655 | goto err; |
7640 | 5656 | ||
7641 | /* Offset into the new buffer for cases of shared fbs between CRTCs */ | 5657 | /* Offset into the new buffer for cases of shared fbs between CRTCs */ |
7642 | offset = crtc->y * fb->pitches[0] + crtc->x * fb->bits_per_pixel/8; | 5658 | offset = crtc->y * fb->pitches[0] + crtc->x * fb->bits_per_pixel/8; |
7643 | 5659 | ||
7644 | ret = BEGIN_LP_RING(6); | 5660 | ret = BEGIN_LP_RING(6); |
7645 | if (ret) | 5661 | if (ret) |
7646 | goto out; | 5662 | goto err_unpin; |
7647 | 5663 | ||
7648 | /* Can't queue multiple flips, so wait for the previous | 5664 | /* Can't queue multiple flips, so wait for the previous |
7649 | * one to finish before executing the next. | 5665 | * one to finish before executing the next. |
@@ -7660,7 +5676,11 @@ static int intel_gen2_queue_flip(struct drm_device *dev, | |||
7660 | OUT_RING(obj->gtt_offset + offset); | 5676 | OUT_RING(obj->gtt_offset + offset); |
7661 | OUT_RING(0); /* aux display base address, unused */ | 5677 | OUT_RING(0); /* aux display base address, unused */ |
7662 | ADVANCE_LP_RING(); | 5678 | ADVANCE_LP_RING(); |
7663 | out: | 5679 | return 0; |
5680 | |||
5681 | err_unpin: | ||
5682 | intel_unpin_fb_obj(obj); | ||
5683 | err: | ||
7664 | return ret; | 5684 | return ret; |
7665 | } | 5685 | } |
7666 | 5686 | ||
@@ -7677,14 +5697,14 @@ static int intel_gen3_queue_flip(struct drm_device *dev, | |||
7677 | 5697 | ||
7678 | ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv)); | 5698 | ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv)); |
7679 | if (ret) | 5699 | if (ret) |
7680 | goto out; | 5700 | goto err; |
7681 | 5701 | ||
7682 | /* Offset into the new buffer for cases of shared fbs between CRTCs */ | 5702 | /* Offset into the new buffer for cases of shared fbs between CRTCs */ |
7683 | offset = crtc->y * fb->pitches[0] + crtc->x * fb->bits_per_pixel/8; | 5703 | offset = crtc->y * fb->pitches[0] + crtc->x * fb->bits_per_pixel/8; |
7684 | 5704 | ||
7685 | ret = BEGIN_LP_RING(6); | 5705 | ret = BEGIN_LP_RING(6); |
7686 | if (ret) | 5706 | if (ret) |
7687 | goto out; | 5707 | goto err_unpin; |
7688 | 5708 | ||
7689 | if (intel_crtc->plane) | 5709 | if (intel_crtc->plane) |
7690 | flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; | 5710 | flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; |
@@ -7699,7 +5719,11 @@ static int intel_gen3_queue_flip(struct drm_device *dev, | |||
7699 | OUT_RING(MI_NOOP); | 5719 | OUT_RING(MI_NOOP); |
7700 | 5720 | ||
7701 | ADVANCE_LP_RING(); | 5721 | ADVANCE_LP_RING(); |
7702 | out: | 5722 | return 0; |
5723 | |||
5724 | err_unpin: | ||
5725 | intel_unpin_fb_obj(obj); | ||
5726 | err: | ||
7703 | return ret; | 5727 | return ret; |
7704 | } | 5728 | } |
7705 | 5729 | ||
@@ -7715,11 +5739,11 @@ static int intel_gen4_queue_flip(struct drm_device *dev, | |||
7715 | 5739 | ||
7716 | ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv)); | 5740 | ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv)); |
7717 | if (ret) | 5741 | if (ret) |
7718 | goto out; | 5742 | goto err; |
7719 | 5743 | ||
7720 | ret = BEGIN_LP_RING(4); | 5744 | ret = BEGIN_LP_RING(4); |
7721 | if (ret) | 5745 | if (ret) |
7722 | goto out; | 5746 | goto err_unpin; |
7723 | 5747 | ||
7724 | /* i965+ uses the linear or tiled offsets from the | 5748 | /* i965+ uses the linear or tiled offsets from the |
7725 | * Display Registers (which do not change across a page-flip) | 5749 | * Display Registers (which do not change across a page-flip) |
@@ -7738,7 +5762,11 @@ static int intel_gen4_queue_flip(struct drm_device *dev, | |||
7738 | pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff; | 5762 | pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff; |
7739 | OUT_RING(pf | pipesrc); | 5763 | OUT_RING(pf | pipesrc); |
7740 | ADVANCE_LP_RING(); | 5764 | ADVANCE_LP_RING(); |
7741 | out: | 5765 | return 0; |
5766 | |||
5767 | err_unpin: | ||
5768 | intel_unpin_fb_obj(obj); | ||
5769 | err: | ||
7742 | return ret; | 5770 | return ret; |
7743 | } | 5771 | } |
7744 | 5772 | ||
@@ -7754,11 +5782,11 @@ static int intel_gen6_queue_flip(struct drm_device *dev, | |||
7754 | 5782 | ||
7755 | ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv)); | 5783 | ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv)); |
7756 | if (ret) | 5784 | if (ret) |
7757 | goto out; | 5785 | goto err; |
7758 | 5786 | ||
7759 | ret = BEGIN_LP_RING(4); | 5787 | ret = BEGIN_LP_RING(4); |
7760 | if (ret) | 5788 | if (ret) |
7761 | goto out; | 5789 | goto err_unpin; |
7762 | 5790 | ||
7763 | OUT_RING(MI_DISPLAY_FLIP | | 5791 | OUT_RING(MI_DISPLAY_FLIP | |
7764 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | 5792 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); |
@@ -7769,7 +5797,11 @@ static int intel_gen6_queue_flip(struct drm_device *dev, | |||
7769 | pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff; | 5797 | pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff; |
7770 | OUT_RING(pf | pipesrc); | 5798 | OUT_RING(pf | pipesrc); |
7771 | ADVANCE_LP_RING(); | 5799 | ADVANCE_LP_RING(); |
7772 | out: | 5800 | return 0; |
5801 | |||
5802 | err_unpin: | ||
5803 | intel_unpin_fb_obj(obj); | ||
5804 | err: | ||
7773 | return ret; | 5805 | return ret; |
7774 | } | 5806 | } |
7775 | 5807 | ||
@@ -7791,18 +5823,22 @@ static int intel_gen7_queue_flip(struct drm_device *dev, | |||
7791 | 5823 | ||
7792 | ret = intel_pin_and_fence_fb_obj(dev, obj, ring); | 5824 | ret = intel_pin_and_fence_fb_obj(dev, obj, ring); |
7793 | if (ret) | 5825 | if (ret) |
7794 | goto out; | 5826 | goto err; |
7795 | 5827 | ||
7796 | ret = intel_ring_begin(ring, 4); | 5828 | ret = intel_ring_begin(ring, 4); |
7797 | if (ret) | 5829 | if (ret) |
7798 | goto out; | 5830 | goto err_unpin; |
7799 | 5831 | ||
7800 | intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | (intel_crtc->plane << 19)); | 5832 | intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | (intel_crtc->plane << 19)); |
7801 | intel_ring_emit(ring, (fb->pitches[0] | obj->tiling_mode)); | 5833 | intel_ring_emit(ring, (fb->pitches[0] | obj->tiling_mode)); |
7802 | intel_ring_emit(ring, (obj->gtt_offset)); | 5834 | intel_ring_emit(ring, (obj->gtt_offset)); |
7803 | intel_ring_emit(ring, (MI_NOOP)); | 5835 | intel_ring_emit(ring, (MI_NOOP)); |
7804 | intel_ring_advance(ring); | 5836 | intel_ring_advance(ring); |
7805 | out: | 5837 | return 0; |
5838 | |||
5839 | err_unpin: | ||
5840 | intel_unpin_fb_obj(obj); | ||
5841 | err: | ||
7806 | return ret; | 5842 | return ret; |
7807 | } | 5843 | } |
7808 | 5844 | ||
@@ -8292,926 +6328,6 @@ static const struct drm_mode_config_funcs intel_mode_funcs = { | |||
8292 | .output_poll_changed = intel_fb_output_poll_changed, | 6328 | .output_poll_changed = intel_fb_output_poll_changed, |
8293 | }; | 6329 | }; |
8294 | 6330 | ||
8295 | static struct drm_i915_gem_object * | ||
8296 | intel_alloc_context_page(struct drm_device *dev) | ||
8297 | { | ||
8298 | struct drm_i915_gem_object *ctx; | ||
8299 | int ret; | ||
8300 | |||
8301 | WARN_ON(!mutex_is_locked(&dev->struct_mutex)); | ||
8302 | |||
8303 | ctx = i915_gem_alloc_object(dev, 4096); | ||
8304 | if (!ctx) { | ||
8305 | DRM_DEBUG("failed to alloc power context, RC6 disabled\n"); | ||
8306 | return NULL; | ||
8307 | } | ||
8308 | |||
8309 | ret = i915_gem_object_pin(ctx, 4096, true); | ||
8310 | if (ret) { | ||
8311 | DRM_ERROR("failed to pin power context: %d\n", ret); | ||
8312 | goto err_unref; | ||
8313 | } | ||
8314 | |||
8315 | ret = i915_gem_object_set_to_gtt_domain(ctx, 1); | ||
8316 | if (ret) { | ||
8317 | DRM_ERROR("failed to set-domain on power context: %d\n", ret); | ||
8318 | goto err_unpin; | ||
8319 | } | ||
8320 | |||
8321 | return ctx; | ||
8322 | |||
8323 | err_unpin: | ||
8324 | i915_gem_object_unpin(ctx); | ||
8325 | err_unref: | ||
8326 | drm_gem_object_unreference(&ctx->base); | ||
8327 | mutex_unlock(&dev->struct_mutex); | ||
8328 | return NULL; | ||
8329 | } | ||
8330 | |||
8331 | bool ironlake_set_drps(struct drm_device *dev, u8 val) | ||
8332 | { | ||
8333 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
8334 | u16 rgvswctl; | ||
8335 | |||
8336 | rgvswctl = I915_READ16(MEMSWCTL); | ||
8337 | if (rgvswctl & MEMCTL_CMD_STS) { | ||
8338 | DRM_DEBUG("gpu busy, RCS change rejected\n"); | ||
8339 | return false; /* still busy with another command */ | ||
8340 | } | ||
8341 | |||
8342 | rgvswctl = (MEMCTL_CMD_CHFREQ << MEMCTL_CMD_SHIFT) | | ||
8343 | (val << MEMCTL_FREQ_SHIFT) | MEMCTL_SFCAVM; | ||
8344 | I915_WRITE16(MEMSWCTL, rgvswctl); | ||
8345 | POSTING_READ16(MEMSWCTL); | ||
8346 | |||
8347 | rgvswctl |= MEMCTL_CMD_STS; | ||
8348 | I915_WRITE16(MEMSWCTL, rgvswctl); | ||
8349 | |||
8350 | return true; | ||
8351 | } | ||
8352 | |||
8353 | void ironlake_enable_drps(struct drm_device *dev) | ||
8354 | { | ||
8355 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
8356 | u32 rgvmodectl = I915_READ(MEMMODECTL); | ||
8357 | u8 fmax, fmin, fstart, vstart; | ||
8358 | |||
8359 | /* Enable temp reporting */ | ||
8360 | I915_WRITE16(PMMISC, I915_READ(PMMISC) | MCPPCE_EN); | ||
8361 | I915_WRITE16(TSC1, I915_READ(TSC1) | TSE); | ||
8362 | |||
8363 | /* 100ms RC evaluation intervals */ | ||
8364 | I915_WRITE(RCUPEI, 100000); | ||
8365 | I915_WRITE(RCDNEI, 100000); | ||
8366 | |||
8367 | /* Set max/min thresholds to 90ms and 80ms respectively */ | ||
8368 | I915_WRITE(RCBMAXAVG, 90000); | ||
8369 | I915_WRITE(RCBMINAVG, 80000); | ||
8370 | |||
8371 | I915_WRITE(MEMIHYST, 1); | ||
8372 | |||
8373 | /* Set up min, max, and cur for interrupt handling */ | ||
8374 | fmax = (rgvmodectl & MEMMODE_FMAX_MASK) >> MEMMODE_FMAX_SHIFT; | ||
8375 | fmin = (rgvmodectl & MEMMODE_FMIN_MASK); | ||
8376 | fstart = (rgvmodectl & MEMMODE_FSTART_MASK) >> | ||
8377 | MEMMODE_FSTART_SHIFT; | ||
8378 | |||
8379 | vstart = (I915_READ(PXVFREQ_BASE + (fstart * 4)) & PXVFREQ_PX_MASK) >> | ||
8380 | PXVFREQ_PX_SHIFT; | ||
8381 | |||
8382 | dev_priv->fmax = fmax; /* IPS callback will increase this */ | ||
8383 | dev_priv->fstart = fstart; | ||
8384 | |||
8385 | dev_priv->max_delay = fstart; | ||
8386 | dev_priv->min_delay = fmin; | ||
8387 | dev_priv->cur_delay = fstart; | ||
8388 | |||
8389 | DRM_DEBUG_DRIVER("fmax: %d, fmin: %d, fstart: %d\n", | ||
8390 | fmax, fmin, fstart); | ||
8391 | |||
8392 | I915_WRITE(MEMINTREN, MEMINT_CX_SUPR_EN | MEMINT_EVAL_CHG_EN); | ||
8393 | |||
8394 | /* | ||
8395 | * Interrupts will be enabled in ironlake_irq_postinstall | ||
8396 | */ | ||
8397 | |||
8398 | I915_WRITE(VIDSTART, vstart); | ||
8399 | POSTING_READ(VIDSTART); | ||
8400 | |||
8401 | rgvmodectl |= MEMMODE_SWMODE_EN; | ||
8402 | I915_WRITE(MEMMODECTL, rgvmodectl); | ||
8403 | |||
8404 | if (wait_for((I915_READ(MEMSWCTL) & MEMCTL_CMD_STS) == 0, 10)) | ||
8405 | DRM_ERROR("stuck trying to change perf mode\n"); | ||
8406 | msleep(1); | ||
8407 | |||
8408 | ironlake_set_drps(dev, fstart); | ||
8409 | |||
8410 | dev_priv->last_count1 = I915_READ(0x112e4) + I915_READ(0x112e8) + | ||
8411 | I915_READ(0x112e0); | ||
8412 | dev_priv->last_time1 = jiffies_to_msecs(jiffies); | ||
8413 | dev_priv->last_count2 = I915_READ(0x112f4); | ||
8414 | getrawmonotonic(&dev_priv->last_time2); | ||
8415 | } | ||
8416 | |||
8417 | void ironlake_disable_drps(struct drm_device *dev) | ||
8418 | { | ||
8419 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
8420 | u16 rgvswctl = I915_READ16(MEMSWCTL); | ||
8421 | |||
8422 | /* Ack interrupts, disable EFC interrupt */ | ||
8423 | I915_WRITE(MEMINTREN, I915_READ(MEMINTREN) & ~MEMINT_EVAL_CHG_EN); | ||
8424 | I915_WRITE(MEMINTRSTS, MEMINT_EVAL_CHG); | ||
8425 | I915_WRITE(DEIER, I915_READ(DEIER) & ~DE_PCU_EVENT); | ||
8426 | I915_WRITE(DEIIR, DE_PCU_EVENT); | ||
8427 | I915_WRITE(DEIMR, I915_READ(DEIMR) | DE_PCU_EVENT); | ||
8428 | |||
8429 | /* Go back to the starting frequency */ | ||
8430 | ironlake_set_drps(dev, dev_priv->fstart); | ||
8431 | msleep(1); | ||
8432 | rgvswctl |= MEMCTL_CMD_STS; | ||
8433 | I915_WRITE(MEMSWCTL, rgvswctl); | ||
8434 | msleep(1); | ||
8435 | |||
8436 | } | ||
8437 | |||
8438 | void gen6_set_rps(struct drm_device *dev, u8 val) | ||
8439 | { | ||
8440 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
8441 | u32 swreq; | ||
8442 | |||
8443 | swreq = (val & 0x3ff) << 25; | ||
8444 | I915_WRITE(GEN6_RPNSWREQ, swreq); | ||
8445 | } | ||
8446 | |||
8447 | void gen6_disable_rps(struct drm_device *dev) | ||
8448 | { | ||
8449 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
8450 | |||
8451 | I915_WRITE(GEN6_RPNSWREQ, 1 << 31); | ||
8452 | I915_WRITE(GEN6_PMINTRMSK, 0xffffffff); | ||
8453 | I915_WRITE(GEN6_PMIER, 0); | ||
8454 | /* Complete PM interrupt masking here doesn't race with the rps work | ||
8455 | * item again unmasking PM interrupts because that is using a different | ||
8456 | * register (PMIMR) to mask PM interrupts. The only risk is in leaving | ||
8457 | * stale bits in PMIIR and PMIMR which gen6_enable_rps will clean up. */ | ||
8458 | |||
8459 | spin_lock_irq(&dev_priv->rps_lock); | ||
8460 | dev_priv->pm_iir = 0; | ||
8461 | spin_unlock_irq(&dev_priv->rps_lock); | ||
8462 | |||
8463 | I915_WRITE(GEN6_PMIIR, I915_READ(GEN6_PMIIR)); | ||
8464 | } | ||
8465 | |||
8466 | static unsigned long intel_pxfreq(u32 vidfreq) | ||
8467 | { | ||
8468 | unsigned long freq; | ||
8469 | int div = (vidfreq & 0x3f0000) >> 16; | ||
8470 | int post = (vidfreq & 0x3000) >> 12; | ||
8471 | int pre = (vidfreq & 0x7); | ||
8472 | |||
8473 | if (!pre) | ||
8474 | return 0; | ||
8475 | |||
8476 | freq = ((div * 133333) / ((1<<post) * pre)); | ||
8477 | |||
8478 | return freq; | ||
8479 | } | ||
8480 | |||
8481 | void intel_init_emon(struct drm_device *dev) | ||
8482 | { | ||
8483 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
8484 | u32 lcfuse; | ||
8485 | u8 pxw[16]; | ||
8486 | int i; | ||
8487 | |||
8488 | /* Disable to program */ | ||
8489 | I915_WRITE(ECR, 0); | ||
8490 | POSTING_READ(ECR); | ||
8491 | |||
8492 | /* Program energy weights for various events */ | ||
8493 | I915_WRITE(SDEW, 0x15040d00); | ||
8494 | I915_WRITE(CSIEW0, 0x007f0000); | ||
8495 | I915_WRITE(CSIEW1, 0x1e220004); | ||
8496 | I915_WRITE(CSIEW2, 0x04000004); | ||
8497 | |||
8498 | for (i = 0; i < 5; i++) | ||
8499 | I915_WRITE(PEW + (i * 4), 0); | ||
8500 | for (i = 0; i < 3; i++) | ||
8501 | I915_WRITE(DEW + (i * 4), 0); | ||
8502 | |||
8503 | /* Program P-state weights to account for frequency power adjustment */ | ||
8504 | for (i = 0; i < 16; i++) { | ||
8505 | u32 pxvidfreq = I915_READ(PXVFREQ_BASE + (i * 4)); | ||
8506 | unsigned long freq = intel_pxfreq(pxvidfreq); | ||
8507 | unsigned long vid = (pxvidfreq & PXVFREQ_PX_MASK) >> | ||
8508 | PXVFREQ_PX_SHIFT; | ||
8509 | unsigned long val; | ||
8510 | |||
8511 | val = vid * vid; | ||
8512 | val *= (freq / 1000); | ||
8513 | val *= 255; | ||
8514 | val /= (127*127*900); | ||
8515 | if (val > 0xff) | ||
8516 | DRM_ERROR("bad pxval: %ld\n", val); | ||
8517 | pxw[i] = val; | ||
8518 | } | ||
8519 | /* Render standby states get 0 weight */ | ||
8520 | pxw[14] = 0; | ||
8521 | pxw[15] = 0; | ||
8522 | |||
8523 | for (i = 0; i < 4; i++) { | ||
8524 | u32 val = (pxw[i*4] << 24) | (pxw[(i*4)+1] << 16) | | ||
8525 | (pxw[(i*4)+2] << 8) | (pxw[(i*4)+3]); | ||
8526 | I915_WRITE(PXW + (i * 4), val); | ||
8527 | } | ||
8528 | |||
8529 | /* Adjust magic regs to magic values (more experimental results) */ | ||
8530 | I915_WRITE(OGW0, 0); | ||
8531 | I915_WRITE(OGW1, 0); | ||
8532 | I915_WRITE(EG0, 0x00007f00); | ||
8533 | I915_WRITE(EG1, 0x0000000e); | ||
8534 | I915_WRITE(EG2, 0x000e0000); | ||
8535 | I915_WRITE(EG3, 0x68000300); | ||
8536 | I915_WRITE(EG4, 0x42000000); | ||
8537 | I915_WRITE(EG5, 0x00140031); | ||
8538 | I915_WRITE(EG6, 0); | ||
8539 | I915_WRITE(EG7, 0); | ||
8540 | |||
8541 | for (i = 0; i < 8; i++) | ||
8542 | I915_WRITE(PXWL + (i * 4), 0); | ||
8543 | |||
8544 | /* Enable PMON + select events */ | ||
8545 | I915_WRITE(ECR, 0x80000019); | ||
8546 | |||
8547 | lcfuse = I915_READ(LCFUSE02); | ||
8548 | |||
8549 | dev_priv->corr = (lcfuse & LCFUSE_HIV_MASK); | ||
8550 | } | ||
8551 | |||
8552 | static int intel_enable_rc6(struct drm_device *dev) | ||
8553 | { | ||
8554 | /* | ||
8555 | * Respect the kernel parameter if it is set | ||
8556 | */ | ||
8557 | if (i915_enable_rc6 >= 0) | ||
8558 | return i915_enable_rc6; | ||
8559 | |||
8560 | /* | ||
8561 | * Disable RC6 on Ironlake | ||
8562 | */ | ||
8563 | if (INTEL_INFO(dev)->gen == 5) | ||
8564 | return 0; | ||
8565 | |||
8566 | /* | ||
8567 | * Disable rc6 on Sandybridge | ||
8568 | */ | ||
8569 | if (INTEL_INFO(dev)->gen == 6) { | ||
8570 | DRM_DEBUG_DRIVER("Sandybridge: deep RC6 disabled\n"); | ||
8571 | return INTEL_RC6_ENABLE; | ||
8572 | } | ||
8573 | DRM_DEBUG_DRIVER("RC6 and deep RC6 enabled\n"); | ||
8574 | return (INTEL_RC6_ENABLE | INTEL_RC6p_ENABLE); | ||
8575 | } | ||
8576 | |||
8577 | void gen6_enable_rps(struct drm_i915_private *dev_priv) | ||
8578 | { | ||
8579 | u32 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); | ||
8580 | u32 gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS); | ||
8581 | u32 pcu_mbox, rc6_mask = 0; | ||
8582 | u32 gtfifodbg; | ||
8583 | int cur_freq, min_freq, max_freq; | ||
8584 | int rc6_mode; | ||
8585 | int i; | ||
8586 | |||
8587 | /* Here begins a magic sequence of register writes to enable | ||
8588 | * auto-downclocking. | ||
8589 | * | ||
8590 | * Perhaps there might be some value in exposing these to | ||
8591 | * userspace... | ||
8592 | */ | ||
8593 | I915_WRITE(GEN6_RC_STATE, 0); | ||
8594 | mutex_lock(&dev_priv->dev->struct_mutex); | ||
8595 | |||
8596 | /* Clear the DBG now so we don't confuse earlier errors */ | ||
8597 | if ((gtfifodbg = I915_READ(GTFIFODBG))) { | ||
8598 | DRM_ERROR("GT fifo had a previous error %x\n", gtfifodbg); | ||
8599 | I915_WRITE(GTFIFODBG, gtfifodbg); | ||
8600 | } | ||
8601 | |||
8602 | gen6_gt_force_wake_get(dev_priv); | ||
8603 | |||
8604 | /* disable the counters and set deterministic thresholds */ | ||
8605 | I915_WRITE(GEN6_RC_CONTROL, 0); | ||
8606 | |||
8607 | I915_WRITE(GEN6_RC1_WAKE_RATE_LIMIT, 1000 << 16); | ||
8608 | I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16 | 30); | ||
8609 | I915_WRITE(GEN6_RC6pp_WAKE_RATE_LIMIT, 30); | ||
8610 | I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); | ||
8611 | I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); | ||
8612 | |||
8613 | for (i = 0; i < I915_NUM_RINGS; i++) | ||
8614 | I915_WRITE(RING_MAX_IDLE(dev_priv->ring[i].mmio_base), 10); | ||
8615 | |||
8616 | I915_WRITE(GEN6_RC_SLEEP, 0); | ||
8617 | I915_WRITE(GEN6_RC1e_THRESHOLD, 1000); | ||
8618 | I915_WRITE(GEN6_RC6_THRESHOLD, 50000); | ||
8619 | I915_WRITE(GEN6_RC6p_THRESHOLD, 100000); | ||
8620 | I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */ | ||
8621 | |||
8622 | rc6_mode = intel_enable_rc6(dev_priv->dev); | ||
8623 | if (rc6_mode & INTEL_RC6_ENABLE) | ||
8624 | rc6_mask |= GEN6_RC_CTL_RC6_ENABLE; | ||
8625 | |||
8626 | if (rc6_mode & INTEL_RC6p_ENABLE) | ||
8627 | rc6_mask |= GEN6_RC_CTL_RC6p_ENABLE; | ||
8628 | |||
8629 | if (rc6_mode & INTEL_RC6pp_ENABLE) | ||
8630 | rc6_mask |= GEN6_RC_CTL_RC6pp_ENABLE; | ||
8631 | |||
8632 | DRM_INFO("Enabling RC6 states: RC6 %s, RC6p %s, RC6pp %s\n", | ||
8633 | (rc6_mode & INTEL_RC6_ENABLE) ? "on" : "off", | ||
8634 | (rc6_mode & INTEL_RC6p_ENABLE) ? "on" : "off", | ||
8635 | (rc6_mode & INTEL_RC6pp_ENABLE) ? "on" : "off"); | ||
8636 | |||
8637 | I915_WRITE(GEN6_RC_CONTROL, | ||
8638 | rc6_mask | | ||
8639 | GEN6_RC_CTL_EI_MODE(1) | | ||
8640 | GEN6_RC_CTL_HW_ENABLE); | ||
8641 | |||
8642 | I915_WRITE(GEN6_RPNSWREQ, | ||
8643 | GEN6_FREQUENCY(10) | | ||
8644 | GEN6_OFFSET(0) | | ||
8645 | GEN6_AGGRESSIVE_TURBO); | ||
8646 | I915_WRITE(GEN6_RC_VIDEO_FREQ, | ||
8647 | GEN6_FREQUENCY(12)); | ||
8648 | |||
8649 | I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 1000000); | ||
8650 | I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, | ||
8651 | 18 << 24 | | ||
8652 | 6 << 16); | ||
8653 | I915_WRITE(GEN6_RP_UP_THRESHOLD, 10000); | ||
8654 | I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 1000000); | ||
8655 | I915_WRITE(GEN6_RP_UP_EI, 100000); | ||
8656 | I915_WRITE(GEN6_RP_DOWN_EI, 5000000); | ||
8657 | I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); | ||
8658 | I915_WRITE(GEN6_RP_CONTROL, | ||
8659 | GEN6_RP_MEDIA_TURBO | | ||
8660 | GEN6_RP_MEDIA_HW_MODE | | ||
8661 | GEN6_RP_MEDIA_IS_GFX | | ||
8662 | GEN6_RP_ENABLE | | ||
8663 | GEN6_RP_UP_BUSY_AVG | | ||
8664 | GEN6_RP_DOWN_IDLE_CONT); | ||
8665 | |||
8666 | if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0, | ||
8667 | 500)) | ||
8668 | DRM_ERROR("timeout waiting for pcode mailbox to become idle\n"); | ||
8669 | |||
8670 | I915_WRITE(GEN6_PCODE_DATA, 0); | ||
8671 | I915_WRITE(GEN6_PCODE_MAILBOX, | ||
8672 | GEN6_PCODE_READY | | ||
8673 | GEN6_PCODE_WRITE_MIN_FREQ_TABLE); | ||
8674 | if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0, | ||
8675 | 500)) | ||
8676 | DRM_ERROR("timeout waiting for pcode mailbox to finish\n"); | ||
8677 | |||
8678 | min_freq = (rp_state_cap & 0xff0000) >> 16; | ||
8679 | max_freq = rp_state_cap & 0xff; | ||
8680 | cur_freq = (gt_perf_status & 0xff00) >> 8; | ||
8681 | |||
8682 | /* Check for overclock support */ | ||
8683 | if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0, | ||
8684 | 500)) | ||
8685 | DRM_ERROR("timeout waiting for pcode mailbox to become idle\n"); | ||
8686 | I915_WRITE(GEN6_PCODE_MAILBOX, GEN6_READ_OC_PARAMS); | ||
8687 | pcu_mbox = I915_READ(GEN6_PCODE_DATA); | ||
8688 | if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0, | ||
8689 | 500)) | ||
8690 | DRM_ERROR("timeout waiting for pcode mailbox to finish\n"); | ||
8691 | if (pcu_mbox & (1<<31)) { /* OC supported */ | ||
8692 | max_freq = pcu_mbox & 0xff; | ||
8693 | DRM_DEBUG_DRIVER("overclocking supported, adjusting frequency max to %dMHz\n", pcu_mbox * 50); | ||
8694 | } | ||
8695 | |||
8696 | /* In units of 100MHz */ | ||
8697 | dev_priv->max_delay = max_freq; | ||
8698 | dev_priv->min_delay = min_freq; | ||
8699 | dev_priv->cur_delay = cur_freq; | ||
8700 | |||
8701 | /* requires MSI enabled */ | ||
8702 | I915_WRITE(GEN6_PMIER, | ||
8703 | GEN6_PM_MBOX_EVENT | | ||
8704 | GEN6_PM_THERMAL_EVENT | | ||
8705 | GEN6_PM_RP_DOWN_TIMEOUT | | ||
8706 | GEN6_PM_RP_UP_THRESHOLD | | ||
8707 | GEN6_PM_RP_DOWN_THRESHOLD | | ||
8708 | GEN6_PM_RP_UP_EI_EXPIRED | | ||
8709 | GEN6_PM_RP_DOWN_EI_EXPIRED); | ||
8710 | spin_lock_irq(&dev_priv->rps_lock); | ||
8711 | WARN_ON(dev_priv->pm_iir != 0); | ||
8712 | I915_WRITE(GEN6_PMIMR, 0); | ||
8713 | spin_unlock_irq(&dev_priv->rps_lock); | ||
8714 | /* enable all PM interrupts */ | ||
8715 | I915_WRITE(GEN6_PMINTRMSK, 0); | ||
8716 | |||
8717 | gen6_gt_force_wake_put(dev_priv); | ||
8718 | mutex_unlock(&dev_priv->dev->struct_mutex); | ||
8719 | } | ||
8720 | |||
8721 | void gen6_update_ring_freq(struct drm_i915_private *dev_priv) | ||
8722 | { | ||
8723 | int min_freq = 15; | ||
8724 | int gpu_freq, ia_freq, max_ia_freq; | ||
8725 | int scaling_factor = 180; | ||
8726 | |||
8727 | max_ia_freq = cpufreq_quick_get_max(0); | ||
8728 | /* | ||
8729 | * Default to measured freq if none found, PCU will ensure we don't go | ||
8730 | * over | ||
8731 | */ | ||
8732 | if (!max_ia_freq) | ||
8733 | max_ia_freq = tsc_khz; | ||
8734 | |||
8735 | /* Convert from kHz to MHz */ | ||
8736 | max_ia_freq /= 1000; | ||
8737 | |||
8738 | mutex_lock(&dev_priv->dev->struct_mutex); | ||
8739 | |||
8740 | /* | ||
8741 | * For each potential GPU frequency, load a ring frequency we'd like | ||
8742 | * to use for memory access. We do this by specifying the IA frequency | ||
8743 | * the PCU should use as a reference to determine the ring frequency. | ||
8744 | */ | ||
8745 | for (gpu_freq = dev_priv->max_delay; gpu_freq >= dev_priv->min_delay; | ||
8746 | gpu_freq--) { | ||
8747 | int diff = dev_priv->max_delay - gpu_freq; | ||
8748 | |||
8749 | /* | ||
8750 | * For GPU frequencies less than 750MHz, just use the lowest | ||
8751 | * ring freq. | ||
8752 | */ | ||
8753 | if (gpu_freq < min_freq) | ||
8754 | ia_freq = 800; | ||
8755 | else | ||
8756 | ia_freq = max_ia_freq - ((diff * scaling_factor) / 2); | ||
8757 | ia_freq = DIV_ROUND_CLOSEST(ia_freq, 100); | ||
8758 | |||
8759 | I915_WRITE(GEN6_PCODE_DATA, | ||
8760 | (ia_freq << GEN6_PCODE_FREQ_IA_RATIO_SHIFT) | | ||
8761 | gpu_freq); | ||
8762 | I915_WRITE(GEN6_PCODE_MAILBOX, GEN6_PCODE_READY | | ||
8763 | GEN6_PCODE_WRITE_MIN_FREQ_TABLE); | ||
8764 | if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & | ||
8765 | GEN6_PCODE_READY) == 0, 10)) { | ||
8766 | DRM_ERROR("pcode write of freq table timed out\n"); | ||
8767 | continue; | ||
8768 | } | ||
8769 | } | ||
8770 | |||
8771 | mutex_unlock(&dev_priv->dev->struct_mutex); | ||
8772 | } | ||
8773 | |||
8774 | static void ironlake_init_clock_gating(struct drm_device *dev) | ||
8775 | { | ||
8776 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
8777 | uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE; | ||
8778 | |||
8779 | /* Required for FBC */ | ||
8780 | dspclk_gate |= DPFCUNIT_CLOCK_GATE_DISABLE | | ||
8781 | DPFCRUNIT_CLOCK_GATE_DISABLE | | ||
8782 | DPFDUNIT_CLOCK_GATE_DISABLE; | ||
8783 | /* Required for CxSR */ | ||
8784 | dspclk_gate |= DPARBUNIT_CLOCK_GATE_DISABLE; | ||
8785 | |||
8786 | I915_WRITE(PCH_3DCGDIS0, | ||
8787 | MARIUNIT_CLOCK_GATE_DISABLE | | ||
8788 | SVSMUNIT_CLOCK_GATE_DISABLE); | ||
8789 | I915_WRITE(PCH_3DCGDIS1, | ||
8790 | VFMUNIT_CLOCK_GATE_DISABLE); | ||
8791 | |||
8792 | I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate); | ||
8793 | |||
8794 | /* | ||
8795 | * According to the spec the following bits should be set in | ||
8796 | * order to enable memory self-refresh | ||
8797 | * The bit 22/21 of 0x42004 | ||
8798 | * The bit 5 of 0x42020 | ||
8799 | * The bit 15 of 0x45000 | ||
8800 | */ | ||
8801 | I915_WRITE(ILK_DISPLAY_CHICKEN2, | ||
8802 | (I915_READ(ILK_DISPLAY_CHICKEN2) | | ||
8803 | ILK_DPARB_GATE | ILK_VSDPFD_FULL)); | ||
8804 | I915_WRITE(ILK_DSPCLK_GATE, | ||
8805 | (I915_READ(ILK_DSPCLK_GATE) | | ||
8806 | ILK_DPARB_CLK_GATE)); | ||
8807 | I915_WRITE(DISP_ARB_CTL, | ||
8808 | (I915_READ(DISP_ARB_CTL) | | ||
8809 | DISP_FBC_WM_DIS)); | ||
8810 | I915_WRITE(WM3_LP_ILK, 0); | ||
8811 | I915_WRITE(WM2_LP_ILK, 0); | ||
8812 | I915_WRITE(WM1_LP_ILK, 0); | ||
8813 | |||
8814 | /* | ||
8815 | * Based on the document from hardware guys the following bits | ||
8816 | * should be set unconditionally in order to enable FBC. | ||
8817 | * The bit 22 of 0x42000 | ||
8818 | * The bit 22 of 0x42004 | ||
8819 | * The bit 7,8,9 of 0x42020. | ||
8820 | */ | ||
8821 | if (IS_IRONLAKE_M(dev)) { | ||
8822 | I915_WRITE(ILK_DISPLAY_CHICKEN1, | ||
8823 | I915_READ(ILK_DISPLAY_CHICKEN1) | | ||
8824 | ILK_FBCQ_DIS); | ||
8825 | I915_WRITE(ILK_DISPLAY_CHICKEN2, | ||
8826 | I915_READ(ILK_DISPLAY_CHICKEN2) | | ||
8827 | ILK_DPARB_GATE); | ||
8828 | I915_WRITE(ILK_DSPCLK_GATE, | ||
8829 | I915_READ(ILK_DSPCLK_GATE) | | ||
8830 | ILK_DPFC_DIS1 | | ||
8831 | ILK_DPFC_DIS2 | | ||
8832 | ILK_CLK_FBC); | ||
8833 | } | ||
8834 | |||
8835 | I915_WRITE(ILK_DISPLAY_CHICKEN2, | ||
8836 | I915_READ(ILK_DISPLAY_CHICKEN2) | | ||
8837 | ILK_ELPIN_409_SELECT); | ||
8838 | I915_WRITE(_3D_CHICKEN2, | ||
8839 | _3D_CHICKEN2_WM_READ_PIPELINED << 16 | | ||
8840 | _3D_CHICKEN2_WM_READ_PIPELINED); | ||
8841 | } | ||
8842 | |||
8843 | static void gen6_init_clock_gating(struct drm_device *dev) | ||
8844 | { | ||
8845 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
8846 | int pipe; | ||
8847 | uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE; | ||
8848 | |||
8849 | I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate); | ||
8850 | |||
8851 | I915_WRITE(ILK_DISPLAY_CHICKEN2, | ||
8852 | I915_READ(ILK_DISPLAY_CHICKEN2) | | ||
8853 | ILK_ELPIN_409_SELECT); | ||
8854 | |||
8855 | I915_WRITE(WM3_LP_ILK, 0); | ||
8856 | I915_WRITE(WM2_LP_ILK, 0); | ||
8857 | I915_WRITE(WM1_LP_ILK, 0); | ||
8858 | |||
8859 | /* According to the BSpec vol1g, bit 12 (RCPBUNIT) clock | ||
8860 | * gating disable must be set. Failure to set it results in | ||
8861 | * flickering pixels due to Z write ordering failures after | ||
8862 | * some amount of runtime in the Mesa "fire" demo, and Unigine | ||
8863 | * Sanctuary and Tropics, and apparently anything else with | ||
8864 | * alpha test or pixel discard. | ||
8865 | * | ||
8866 | * According to the spec, bit 11 (RCCUNIT) must also be set, | ||
8867 | * but we didn't debug actual testcases to find it out. | ||
8868 | */ | ||
8869 | I915_WRITE(GEN6_UCGCTL2, | ||
8870 | GEN6_RCPBUNIT_CLOCK_GATE_DISABLE | | ||
8871 | GEN6_RCCUNIT_CLOCK_GATE_DISABLE); | ||
8872 | |||
8873 | /* | ||
8874 | * According to the spec the following bits should be | ||
8875 | * set in order to enable memory self-refresh and fbc: | ||
8876 | * The bit21 and bit22 of 0x42000 | ||
8877 | * The bit21 and bit22 of 0x42004 | ||
8878 | * The bit5 and bit7 of 0x42020 | ||
8879 | * The bit14 of 0x70180 | ||
8880 | * The bit14 of 0x71180 | ||
8881 | */ | ||
8882 | I915_WRITE(ILK_DISPLAY_CHICKEN1, | ||
8883 | I915_READ(ILK_DISPLAY_CHICKEN1) | | ||
8884 | ILK_FBCQ_DIS | ILK_PABSTRETCH_DIS); | ||
8885 | I915_WRITE(ILK_DISPLAY_CHICKEN2, | ||
8886 | I915_READ(ILK_DISPLAY_CHICKEN2) | | ||
8887 | ILK_DPARB_GATE | ILK_VSDPFD_FULL); | ||
8888 | I915_WRITE(ILK_DSPCLK_GATE, | ||
8889 | I915_READ(ILK_DSPCLK_GATE) | | ||
8890 | ILK_DPARB_CLK_GATE | | ||
8891 | ILK_DPFD_CLK_GATE); | ||
8892 | |||
8893 | for_each_pipe(pipe) { | ||
8894 | I915_WRITE(DSPCNTR(pipe), | ||
8895 | I915_READ(DSPCNTR(pipe)) | | ||
8896 | DISPPLANE_TRICKLE_FEED_DISABLE); | ||
8897 | intel_flush_display_plane(dev_priv, pipe); | ||
8898 | } | ||
8899 | } | ||
8900 | |||
8901 | static void ivybridge_init_clock_gating(struct drm_device *dev) | ||
8902 | { | ||
8903 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
8904 | int pipe; | ||
8905 | uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE; | ||
8906 | |||
8907 | I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate); | ||
8908 | |||
8909 | I915_WRITE(WM3_LP_ILK, 0); | ||
8910 | I915_WRITE(WM2_LP_ILK, 0); | ||
8911 | I915_WRITE(WM1_LP_ILK, 0); | ||
8912 | |||
8913 | /* According to the spec, bit 13 (RCZUNIT) must be set on IVB. | ||
8914 | * This implements the WaDisableRCZUnitClockGating workaround. | ||
8915 | */ | ||
8916 | I915_WRITE(GEN6_UCGCTL2, GEN6_RCZUNIT_CLOCK_GATE_DISABLE); | ||
8917 | |||
8918 | I915_WRITE(ILK_DSPCLK_GATE, IVB_VRHUNIT_CLK_GATE); | ||
8919 | |||
8920 | I915_WRITE(IVB_CHICKEN3, | ||
8921 | CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE | | ||
8922 | CHICKEN3_DGMG_DONE_FIX_DISABLE); | ||
8923 | |||
8924 | /* Apply the WaDisableRHWOOptimizationForRenderHang workaround. */ | ||
8925 | I915_WRITE(GEN7_COMMON_SLICE_CHICKEN1, | ||
8926 | GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC); | ||
8927 | |||
8928 | /* WaApplyL3ControlAndL3ChickenMode requires those two on Ivy Bridge */ | ||
8929 | I915_WRITE(GEN7_L3CNTLREG1, | ||
8930 | GEN7_WA_FOR_GEN7_L3_CONTROL); | ||
8931 | I915_WRITE(GEN7_L3_CHICKEN_MODE_REGISTER, | ||
8932 | GEN7_WA_L3_CHICKEN_MODE); | ||
8933 | |||
8934 | /* This is required by WaCatErrorRejectionIssue */ | ||
8935 | I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, | ||
8936 | I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | | ||
8937 | GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); | ||
8938 | |||
8939 | for_each_pipe(pipe) { | ||
8940 | I915_WRITE(DSPCNTR(pipe), | ||
8941 | I915_READ(DSPCNTR(pipe)) | | ||
8942 | DISPPLANE_TRICKLE_FEED_DISABLE); | ||
8943 | intel_flush_display_plane(dev_priv, pipe); | ||
8944 | } | ||
8945 | } | ||
8946 | |||
8947 | static void valleyview_init_clock_gating(struct drm_device *dev) | ||
8948 | { | ||
8949 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
8950 | int pipe; | ||
8951 | uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE; | ||
8952 | |||
8953 | I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate); | ||
8954 | |||
8955 | I915_WRITE(WM3_LP_ILK, 0); | ||
8956 | I915_WRITE(WM2_LP_ILK, 0); | ||
8957 | I915_WRITE(WM1_LP_ILK, 0); | ||
8958 | |||
8959 | /* According to the spec, bit 13 (RCZUNIT) must be set on IVB. | ||
8960 | * This implements the WaDisableRCZUnitClockGating workaround. | ||
8961 | */ | ||
8962 | I915_WRITE(GEN6_UCGCTL2, GEN6_RCZUNIT_CLOCK_GATE_DISABLE); | ||
8963 | |||
8964 | I915_WRITE(ILK_DSPCLK_GATE, IVB_VRHUNIT_CLK_GATE); | ||
8965 | |||
8966 | I915_WRITE(IVB_CHICKEN3, | ||
8967 | CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE | | ||
8968 | CHICKEN3_DGMG_DONE_FIX_DISABLE); | ||
8969 | |||
8970 | /* Apply the WaDisableRHWOOptimizationForRenderHang workaround. */ | ||
8971 | I915_WRITE(GEN7_COMMON_SLICE_CHICKEN1, | ||
8972 | GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC); | ||
8973 | |||
8974 | /* WaApplyL3ControlAndL3ChickenMode requires those two on Ivy Bridge */ | ||
8975 | I915_WRITE(GEN7_L3CNTLREG1, GEN7_WA_FOR_GEN7_L3_CONTROL); | ||
8976 | I915_WRITE(GEN7_L3_CHICKEN_MODE_REGISTER, GEN7_WA_L3_CHICKEN_MODE); | ||
8977 | |||
8978 | /* This is required by WaCatErrorRejectionIssue */ | ||
8979 | I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, | ||
8980 | I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | | ||
8981 | GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); | ||
8982 | |||
8983 | for_each_pipe(pipe) { | ||
8984 | I915_WRITE(DSPCNTR(pipe), | ||
8985 | I915_READ(DSPCNTR(pipe)) | | ||
8986 | DISPPLANE_TRICKLE_FEED_DISABLE); | ||
8987 | intel_flush_display_plane(dev_priv, pipe); | ||
8988 | } | ||
8989 | |||
8990 | I915_WRITE(CACHE_MODE_1, I915_READ(CACHE_MODE_1) | | ||
8991 | (PIXEL_SUBSPAN_COLLECT_OPT_DISABLE << 16) | | ||
8992 | PIXEL_SUBSPAN_COLLECT_OPT_DISABLE); | ||
8993 | } | ||
8994 | |||
8995 | static void g4x_init_clock_gating(struct drm_device *dev) | ||
8996 | { | ||
8997 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
8998 | uint32_t dspclk_gate; | ||
8999 | |||
9000 | I915_WRITE(RENCLK_GATE_D1, 0); | ||
9001 | I915_WRITE(RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE | | ||
9002 | GS_UNIT_CLOCK_GATE_DISABLE | | ||
9003 | CL_UNIT_CLOCK_GATE_DISABLE); | ||
9004 | I915_WRITE(RAMCLK_GATE_D, 0); | ||
9005 | dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE | | ||
9006 | OVRUNIT_CLOCK_GATE_DISABLE | | ||
9007 | OVCUNIT_CLOCK_GATE_DISABLE; | ||
9008 | if (IS_GM45(dev)) | ||
9009 | dspclk_gate |= DSSUNIT_CLOCK_GATE_DISABLE; | ||
9010 | I915_WRITE(DSPCLK_GATE_D, dspclk_gate); | ||
9011 | } | ||
9012 | |||
9013 | static void crestline_init_clock_gating(struct drm_device *dev) | ||
9014 | { | ||
9015 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
9016 | |||
9017 | I915_WRITE(RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE); | ||
9018 | I915_WRITE(RENCLK_GATE_D2, 0); | ||
9019 | I915_WRITE(DSPCLK_GATE_D, 0); | ||
9020 | I915_WRITE(RAMCLK_GATE_D, 0); | ||
9021 | I915_WRITE16(DEUC, 0); | ||
9022 | } | ||
9023 | |||
9024 | static void broadwater_init_clock_gating(struct drm_device *dev) | ||
9025 | { | ||
9026 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
9027 | |||
9028 | I915_WRITE(RENCLK_GATE_D1, I965_RCZ_CLOCK_GATE_DISABLE | | ||
9029 | I965_RCC_CLOCK_GATE_DISABLE | | ||
9030 | I965_RCPB_CLOCK_GATE_DISABLE | | ||
9031 | I965_ISC_CLOCK_GATE_DISABLE | | ||
9032 | I965_FBC_CLOCK_GATE_DISABLE); | ||
9033 | I915_WRITE(RENCLK_GATE_D2, 0); | ||
9034 | } | ||
9035 | |||
9036 | static void gen3_init_clock_gating(struct drm_device *dev) | ||
9037 | { | ||
9038 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
9039 | u32 dstate = I915_READ(D_STATE); | ||
9040 | |||
9041 | dstate |= DSTATE_PLL_D3_OFF | DSTATE_GFX_CLOCK_GATING | | ||
9042 | DSTATE_DOT_CLOCK_GATING; | ||
9043 | I915_WRITE(D_STATE, dstate); | ||
9044 | } | ||
9045 | |||
9046 | static void i85x_init_clock_gating(struct drm_device *dev) | ||
9047 | { | ||
9048 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
9049 | |||
9050 | I915_WRITE(RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE); | ||
9051 | } | ||
9052 | |||
9053 | static void i830_init_clock_gating(struct drm_device *dev) | ||
9054 | { | ||
9055 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
9056 | |||
9057 | I915_WRITE(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE); | ||
9058 | } | ||
9059 | |||
9060 | static void ibx_init_clock_gating(struct drm_device *dev) | ||
9061 | { | ||
9062 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
9063 | |||
9064 | /* | ||
9065 | * On Ibex Peak and Cougar Point, we need to disable clock | ||
9066 | * gating for the panel power sequencer or it will fail to | ||
9067 | * start up when no ports are active. | ||
9068 | */ | ||
9069 | I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE); | ||
9070 | } | ||
9071 | |||
9072 | static void cpt_init_clock_gating(struct drm_device *dev) | ||
9073 | { | ||
9074 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
9075 | int pipe; | ||
9076 | |||
9077 | /* | ||
9078 | * On Ibex Peak and Cougar Point, we need to disable clock | ||
9079 | * gating for the panel power sequencer or it will fail to | ||
9080 | * start up when no ports are active. | ||
9081 | */ | ||
9082 | I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE); | ||
9083 | I915_WRITE(SOUTH_CHICKEN2, I915_READ(SOUTH_CHICKEN2) | | ||
9084 | DPLS_EDP_PPS_FIX_DIS); | ||
9085 | /* Without this, mode sets may fail silently on FDI */ | ||
9086 | for_each_pipe(pipe) | ||
9087 | I915_WRITE(TRANS_CHICKEN2(pipe), TRANS_AUTOTRAIN_GEN_STALL_DIS); | ||
9088 | } | ||
9089 | |||
9090 | static void ironlake_teardown_rc6(struct drm_device *dev) | ||
9091 | { | ||
9092 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
9093 | |||
9094 | if (dev_priv->renderctx) { | ||
9095 | i915_gem_object_unpin(dev_priv->renderctx); | ||
9096 | drm_gem_object_unreference(&dev_priv->renderctx->base); | ||
9097 | dev_priv->renderctx = NULL; | ||
9098 | } | ||
9099 | |||
9100 | if (dev_priv->pwrctx) { | ||
9101 | i915_gem_object_unpin(dev_priv->pwrctx); | ||
9102 | drm_gem_object_unreference(&dev_priv->pwrctx->base); | ||
9103 | dev_priv->pwrctx = NULL; | ||
9104 | } | ||
9105 | } | ||
9106 | |||
9107 | static void ironlake_disable_rc6(struct drm_device *dev) | ||
9108 | { | ||
9109 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
9110 | |||
9111 | if (I915_READ(PWRCTXA)) { | ||
9112 | /* Wake the GPU, prevent RC6, then restore RSTDBYCTL */ | ||
9113 | I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) | RCX_SW_EXIT); | ||
9114 | wait_for(((I915_READ(RSTDBYCTL) & RSX_STATUS_MASK) == RSX_STATUS_ON), | ||
9115 | 50); | ||
9116 | |||
9117 | I915_WRITE(PWRCTXA, 0); | ||
9118 | POSTING_READ(PWRCTXA); | ||
9119 | |||
9120 | I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) & ~RCX_SW_EXIT); | ||
9121 | POSTING_READ(RSTDBYCTL); | ||
9122 | } | ||
9123 | |||
9124 | ironlake_teardown_rc6(dev); | ||
9125 | } | ||
9126 | |||
9127 | static int ironlake_setup_rc6(struct drm_device *dev) | ||
9128 | { | ||
9129 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
9130 | |||
9131 | if (dev_priv->renderctx == NULL) | ||
9132 | dev_priv->renderctx = intel_alloc_context_page(dev); | ||
9133 | if (!dev_priv->renderctx) | ||
9134 | return -ENOMEM; | ||
9135 | |||
9136 | if (dev_priv->pwrctx == NULL) | ||
9137 | dev_priv->pwrctx = intel_alloc_context_page(dev); | ||
9138 | if (!dev_priv->pwrctx) { | ||
9139 | ironlake_teardown_rc6(dev); | ||
9140 | return -ENOMEM; | ||
9141 | } | ||
9142 | |||
9143 | return 0; | ||
9144 | } | ||
9145 | |||
9146 | void ironlake_enable_rc6(struct drm_device *dev) | ||
9147 | { | ||
9148 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
9149 | int ret; | ||
9150 | |||
9151 | /* rc6 disabled by default due to repeated reports of hanging during | ||
9152 | * boot and resume. | ||
9153 | */ | ||
9154 | if (!intel_enable_rc6(dev)) | ||
9155 | return; | ||
9156 | |||
9157 | mutex_lock(&dev->struct_mutex); | ||
9158 | ret = ironlake_setup_rc6(dev); | ||
9159 | if (ret) { | ||
9160 | mutex_unlock(&dev->struct_mutex); | ||
9161 | return; | ||
9162 | } | ||
9163 | |||
9164 | /* | ||
9165 | * GPU can automatically power down the render unit if given a page | ||
9166 | * to save state. | ||
9167 | */ | ||
9168 | ret = BEGIN_LP_RING(6); | ||
9169 | if (ret) { | ||
9170 | ironlake_teardown_rc6(dev); | ||
9171 | mutex_unlock(&dev->struct_mutex); | ||
9172 | return; | ||
9173 | } | ||
9174 | |||
9175 | OUT_RING(MI_SUSPEND_FLUSH | MI_SUSPEND_FLUSH_EN); | ||
9176 | OUT_RING(MI_SET_CONTEXT); | ||
9177 | OUT_RING(dev_priv->renderctx->gtt_offset | | ||
9178 | MI_MM_SPACE_GTT | | ||
9179 | MI_SAVE_EXT_STATE_EN | | ||
9180 | MI_RESTORE_EXT_STATE_EN | | ||
9181 | MI_RESTORE_INHIBIT); | ||
9182 | OUT_RING(MI_SUSPEND_FLUSH); | ||
9183 | OUT_RING(MI_NOOP); | ||
9184 | OUT_RING(MI_FLUSH); | ||
9185 | ADVANCE_LP_RING(); | ||
9186 | |||
9187 | /* | ||
9188 | * Wait for the command parser to advance past MI_SET_CONTEXT. The HW | ||
9189 | * does an implicit flush, combined with MI_FLUSH above, it should be | ||
9190 | * safe to assume that renderctx is valid | ||
9191 | */ | ||
9192 | ret = intel_wait_ring_idle(LP_RING(dev_priv)); | ||
9193 | if (ret) { | ||
9194 | DRM_ERROR("failed to enable ironlake power power savings\n"); | ||
9195 | ironlake_teardown_rc6(dev); | ||
9196 | mutex_unlock(&dev->struct_mutex); | ||
9197 | return; | ||
9198 | } | ||
9199 | |||
9200 | I915_WRITE(PWRCTXA, dev_priv->pwrctx->gtt_offset | PWRCTX_EN); | ||
9201 | I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) & ~RCX_SW_EXIT); | ||
9202 | mutex_unlock(&dev->struct_mutex); | ||
9203 | } | ||
9204 | |||
9205 | void intel_init_clock_gating(struct drm_device *dev) | ||
9206 | { | ||
9207 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
9208 | |||
9209 | dev_priv->display.init_clock_gating(dev); | ||
9210 | |||
9211 | if (dev_priv->display.init_pch_clock_gating) | ||
9212 | dev_priv->display.init_pch_clock_gating(dev); | ||
9213 | } | ||
9214 | |||
9215 | /* Set up chip specific display functions */ | 6331 | /* Set up chip specific display functions */ |
9216 | static void intel_init_display(struct drm_device *dev) | 6332 | static void intel_init_display(struct drm_device *dev) |
9217 | { | 6333 | { |
@@ -9228,23 +6344,6 @@ static void intel_init_display(struct drm_device *dev) | |||
9228 | dev_priv->display.update_plane = i9xx_update_plane; | 6344 | dev_priv->display.update_plane = i9xx_update_plane; |
9229 | } | 6345 | } |
9230 | 6346 | ||
9231 | if (I915_HAS_FBC(dev)) { | ||
9232 | if (HAS_PCH_SPLIT(dev)) { | ||
9233 | dev_priv->display.fbc_enabled = ironlake_fbc_enabled; | ||
9234 | dev_priv->display.enable_fbc = ironlake_enable_fbc; | ||
9235 | dev_priv->display.disable_fbc = ironlake_disable_fbc; | ||
9236 | } else if (IS_GM45(dev)) { | ||
9237 | dev_priv->display.fbc_enabled = g4x_fbc_enabled; | ||
9238 | dev_priv->display.enable_fbc = g4x_enable_fbc; | ||
9239 | dev_priv->display.disable_fbc = g4x_disable_fbc; | ||
9240 | } else if (IS_CRESTLINE(dev)) { | ||
9241 | dev_priv->display.fbc_enabled = i8xx_fbc_enabled; | ||
9242 | dev_priv->display.enable_fbc = i8xx_enable_fbc; | ||
9243 | dev_priv->display.disable_fbc = i8xx_disable_fbc; | ||
9244 | } | ||
9245 | /* 855GM needs testing */ | ||
9246 | } | ||
9247 | |||
9248 | /* Returns the core display clock speed */ | 6347 | /* Returns the core display clock speed */ |
9249 | if (IS_VALLEYVIEW(dev)) | 6348 | if (IS_VALLEYVIEW(dev)) |
9250 | dev_priv->display.get_display_clock_speed = | 6349 | dev_priv->display.get_display_clock_speed = |
@@ -9271,130 +6370,24 @@ static void intel_init_display(struct drm_device *dev) | |||
9271 | dev_priv->display.get_display_clock_speed = | 6370 | dev_priv->display.get_display_clock_speed = |
9272 | i830_get_display_clock_speed; | 6371 | i830_get_display_clock_speed; |
9273 | 6372 | ||
9274 | /* For FIFO watermark updates */ | ||
9275 | if (HAS_PCH_SPLIT(dev)) { | 6373 | if (HAS_PCH_SPLIT(dev)) { |
9276 | dev_priv->display.force_wake_get = __gen6_gt_force_wake_get; | ||
9277 | dev_priv->display.force_wake_put = __gen6_gt_force_wake_put; | ||
9278 | |||
9279 | /* IVB configs may use multi-threaded forcewake */ | ||
9280 | if (IS_IVYBRIDGE(dev)) { | ||
9281 | u32 ecobus; | ||
9282 | |||
9283 | /* A small trick here - if the bios hasn't configured MT forcewake, | ||
9284 | * and if the device is in RC6, then force_wake_mt_get will not wake | ||
9285 | * the device and the ECOBUS read will return zero. Which will be | ||
9286 | * (correctly) interpreted by the test below as MT forcewake being | ||
9287 | * disabled. | ||
9288 | */ | ||
9289 | mutex_lock(&dev->struct_mutex); | ||
9290 | __gen6_gt_force_wake_mt_get(dev_priv); | ||
9291 | ecobus = I915_READ_NOTRACE(ECOBUS); | ||
9292 | __gen6_gt_force_wake_mt_put(dev_priv); | ||
9293 | mutex_unlock(&dev->struct_mutex); | ||
9294 | |||
9295 | if (ecobus & FORCEWAKE_MT_ENABLE) { | ||
9296 | DRM_DEBUG_KMS("Using MT version of forcewake\n"); | ||
9297 | dev_priv->display.force_wake_get = | ||
9298 | __gen6_gt_force_wake_mt_get; | ||
9299 | dev_priv->display.force_wake_put = | ||
9300 | __gen6_gt_force_wake_mt_put; | ||
9301 | } | ||
9302 | } | ||
9303 | |||
9304 | if (HAS_PCH_IBX(dev)) | ||
9305 | dev_priv->display.init_pch_clock_gating = ibx_init_clock_gating; | ||
9306 | else if (HAS_PCH_CPT(dev)) | ||
9307 | dev_priv->display.init_pch_clock_gating = cpt_init_clock_gating; | ||
9308 | |||
9309 | if (IS_GEN5(dev)) { | 6374 | if (IS_GEN5(dev)) { |
9310 | if (I915_READ(MLTR_ILK) & ILK_SRLT_MASK) | ||
9311 | dev_priv->display.update_wm = ironlake_update_wm; | ||
9312 | else { | ||
9313 | DRM_DEBUG_KMS("Failed to get proper latency. " | ||
9314 | "Disable CxSR\n"); | ||
9315 | dev_priv->display.update_wm = NULL; | ||
9316 | } | ||
9317 | dev_priv->display.fdi_link_train = ironlake_fdi_link_train; | 6375 | dev_priv->display.fdi_link_train = ironlake_fdi_link_train; |
9318 | dev_priv->display.init_clock_gating = ironlake_init_clock_gating; | ||
9319 | dev_priv->display.write_eld = ironlake_write_eld; | 6376 | dev_priv->display.write_eld = ironlake_write_eld; |
9320 | } else if (IS_GEN6(dev)) { | 6377 | } else if (IS_GEN6(dev)) { |
9321 | if (SNB_READ_WM0_LATENCY()) { | ||
9322 | dev_priv->display.update_wm = sandybridge_update_wm; | ||
9323 | dev_priv->display.update_sprite_wm = sandybridge_update_sprite_wm; | ||
9324 | } else { | ||
9325 | DRM_DEBUG_KMS("Failed to read display plane latency. " | ||
9326 | "Disable CxSR\n"); | ||
9327 | dev_priv->display.update_wm = NULL; | ||
9328 | } | ||
9329 | dev_priv->display.fdi_link_train = gen6_fdi_link_train; | 6378 | dev_priv->display.fdi_link_train = gen6_fdi_link_train; |
9330 | dev_priv->display.init_clock_gating = gen6_init_clock_gating; | ||
9331 | dev_priv->display.write_eld = ironlake_write_eld; | 6379 | dev_priv->display.write_eld = ironlake_write_eld; |
9332 | } else if (IS_IVYBRIDGE(dev)) { | 6380 | } else if (IS_IVYBRIDGE(dev)) { |
9333 | /* FIXME: detect B0+ stepping and use auto training */ | 6381 | /* FIXME: detect B0+ stepping and use auto training */ |
9334 | dev_priv->display.fdi_link_train = ivb_manual_fdi_link_train; | 6382 | dev_priv->display.fdi_link_train = ivb_manual_fdi_link_train; |
9335 | if (SNB_READ_WM0_LATENCY()) { | ||
9336 | dev_priv->display.update_wm = sandybridge_update_wm; | ||
9337 | dev_priv->display.update_sprite_wm = sandybridge_update_sprite_wm; | ||
9338 | } else { | ||
9339 | DRM_DEBUG_KMS("Failed to read display plane latency. " | ||
9340 | "Disable CxSR\n"); | ||
9341 | dev_priv->display.update_wm = NULL; | ||
9342 | } | ||
9343 | dev_priv->display.init_clock_gating = ivybridge_init_clock_gating; | ||
9344 | dev_priv->display.write_eld = ironlake_write_eld; | 6383 | dev_priv->display.write_eld = ironlake_write_eld; |
9345 | } else | 6384 | } else |
9346 | dev_priv->display.update_wm = NULL; | 6385 | dev_priv->display.update_wm = NULL; |
9347 | } else if (IS_VALLEYVIEW(dev)) { | 6386 | } else if (IS_VALLEYVIEW(dev)) { |
9348 | dev_priv->display.update_wm = valleyview_update_wm; | ||
9349 | dev_priv->display.init_clock_gating = | ||
9350 | valleyview_init_clock_gating; | ||
9351 | dev_priv->display.force_wake_get = vlv_force_wake_get; | 6387 | dev_priv->display.force_wake_get = vlv_force_wake_get; |
9352 | dev_priv->display.force_wake_put = vlv_force_wake_put; | 6388 | dev_priv->display.force_wake_put = vlv_force_wake_put; |
9353 | } else if (IS_PINEVIEW(dev)) { | ||
9354 | if (!intel_get_cxsr_latency(IS_PINEVIEW_G(dev), | ||
9355 | dev_priv->is_ddr3, | ||
9356 | dev_priv->fsb_freq, | ||
9357 | dev_priv->mem_freq)) { | ||
9358 | DRM_INFO("failed to find known CxSR latency " | ||
9359 | "(found ddr%s fsb freq %d, mem freq %d), " | ||
9360 | "disabling CxSR\n", | ||
9361 | (dev_priv->is_ddr3 == 1) ? "3" : "2", | ||
9362 | dev_priv->fsb_freq, dev_priv->mem_freq); | ||
9363 | /* Disable CxSR and never update its watermark again */ | ||
9364 | pineview_disable_cxsr(dev); | ||
9365 | dev_priv->display.update_wm = NULL; | ||
9366 | } else | ||
9367 | dev_priv->display.update_wm = pineview_update_wm; | ||
9368 | dev_priv->display.init_clock_gating = gen3_init_clock_gating; | ||
9369 | } else if (IS_G4X(dev)) { | 6389 | } else if (IS_G4X(dev)) { |
9370 | dev_priv->display.write_eld = g4x_write_eld; | 6390 | dev_priv->display.write_eld = g4x_write_eld; |
9371 | dev_priv->display.update_wm = g4x_update_wm; | ||
9372 | dev_priv->display.init_clock_gating = g4x_init_clock_gating; | ||
9373 | } else if (IS_GEN4(dev)) { | ||
9374 | dev_priv->display.update_wm = i965_update_wm; | ||
9375 | if (IS_CRESTLINE(dev)) | ||
9376 | dev_priv->display.init_clock_gating = crestline_init_clock_gating; | ||
9377 | else if (IS_BROADWATER(dev)) | ||
9378 | dev_priv->display.init_clock_gating = broadwater_init_clock_gating; | ||
9379 | } else if (IS_GEN3(dev)) { | ||
9380 | dev_priv->display.update_wm = i9xx_update_wm; | ||
9381 | dev_priv->display.get_fifo_size = i9xx_get_fifo_size; | ||
9382 | dev_priv->display.init_clock_gating = gen3_init_clock_gating; | ||
9383 | } else if (IS_I865G(dev)) { | ||
9384 | dev_priv->display.update_wm = i830_update_wm; | ||
9385 | dev_priv->display.init_clock_gating = i85x_init_clock_gating; | ||
9386 | dev_priv->display.get_fifo_size = i830_get_fifo_size; | ||
9387 | } else if (IS_I85X(dev)) { | ||
9388 | dev_priv->display.update_wm = i9xx_update_wm; | ||
9389 | dev_priv->display.get_fifo_size = i85x_get_fifo_size; | ||
9390 | dev_priv->display.init_clock_gating = i85x_init_clock_gating; | ||
9391 | } else { | ||
9392 | dev_priv->display.update_wm = i830_update_wm; | ||
9393 | dev_priv->display.init_clock_gating = i830_init_clock_gating; | ||
9394 | if (IS_845G(dev)) | ||
9395 | dev_priv->display.get_fifo_size = i845_get_fifo_size; | ||
9396 | else | ||
9397 | dev_priv->display.get_fifo_size = i830_get_fifo_size; | ||
9398 | } | 6391 | } |
9399 | 6392 | ||
9400 | /* Default just returns -ENODEV to indicate unsupported */ | 6393 | /* Default just returns -ENODEV to indicate unsupported */ |
@@ -9464,7 +6457,7 @@ struct intel_quirk { | |||
9464 | void (*hook)(struct drm_device *dev); | 6457 | void (*hook)(struct drm_device *dev); |
9465 | }; | 6458 | }; |
9466 | 6459 | ||
9467 | struct intel_quirk intel_quirks[] = { | 6460 | static struct intel_quirk intel_quirks[] = { |
9468 | /* HP Mini needs pipe A force quirk (LP: #322104) */ | 6461 | /* HP Mini needs pipe A force quirk (LP: #322104) */ |
9469 | { 0x27ae, 0x103c, 0x361a, quirk_pipea_force }, | 6462 | { 0x27ae, 0x103c, 0x361a, quirk_pipea_force }, |
9470 | 6463 | ||
@@ -9524,7 +6517,7 @@ static void i915_disable_vga(struct drm_device *dev) | |||
9524 | vga_reg = VGACNTRL; | 6517 | vga_reg = VGACNTRL; |
9525 | 6518 | ||
9526 | vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO); | 6519 | vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO); |
9527 | outb(1, VGA_SR_INDEX); | 6520 | outb(SR01, VGA_SR_INDEX); |
9528 | sr1 = inb(VGA_SR_DATA); | 6521 | sr1 = inb(VGA_SR_DATA); |
9529 | outb(sr1 | 1<<5, VGA_SR_DATA); | 6522 | outb(sr1 | 1<<5, VGA_SR_DATA); |
9530 | vga_put(dev->pdev, VGA_RSRC_LEGACY_IO); | 6523 | vga_put(dev->pdev, VGA_RSRC_LEGACY_IO); |
@@ -9534,6 +6527,39 @@ static void i915_disable_vga(struct drm_device *dev) | |||
9534 | POSTING_READ(vga_reg); | 6527 | POSTING_READ(vga_reg); |
9535 | } | 6528 | } |
9536 | 6529 | ||
6530 | static void ivb_pch_pwm_override(struct drm_device *dev) | ||
6531 | { | ||
6532 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
6533 | |||
6534 | /* | ||
6535 | * IVB has CPU eDP backlight regs too, set things up to let the | ||
6536 | * PCH regs control the backlight | ||
6537 | */ | ||
6538 | I915_WRITE(BLC_PWM_CPU_CTL2, PWM_ENABLE); | ||
6539 | I915_WRITE(BLC_PWM_CPU_CTL, 0); | ||
6540 | I915_WRITE(BLC_PWM_PCH_CTL1, PWM_ENABLE | (1<<30)); | ||
6541 | } | ||
6542 | |||
6543 | void intel_modeset_init_hw(struct drm_device *dev) | ||
6544 | { | ||
6545 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
6546 | |||
6547 | intel_init_clock_gating(dev); | ||
6548 | |||
6549 | if (IS_IRONLAKE_M(dev)) { | ||
6550 | ironlake_enable_drps(dev); | ||
6551 | intel_init_emon(dev); | ||
6552 | } | ||
6553 | |||
6554 | if ((IS_GEN6(dev) || IS_GEN7(dev)) && !IS_VALLEYVIEW(dev)) { | ||
6555 | gen6_enable_rps(dev_priv); | ||
6556 | gen6_update_ring_freq(dev_priv); | ||
6557 | } | ||
6558 | |||
6559 | if (IS_IVYBRIDGE(dev)) | ||
6560 | ivb_pch_pwm_override(dev); | ||
6561 | } | ||
6562 | |||
9537 | void intel_modeset_init(struct drm_device *dev) | 6563 | void intel_modeset_init(struct drm_device *dev) |
9538 | { | 6564 | { |
9539 | struct drm_i915_private *dev_priv = dev->dev_private; | 6565 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -9551,6 +6577,8 @@ void intel_modeset_init(struct drm_device *dev) | |||
9551 | 6577 | ||
9552 | intel_init_quirks(dev); | 6578 | intel_init_quirks(dev); |
9553 | 6579 | ||
6580 | intel_init_pm(dev); | ||
6581 | |||
9554 | intel_init_display(dev); | 6582 | intel_init_display(dev); |
9555 | 6583 | ||
9556 | if (IS_GEN2(dev)) { | 6584 | if (IS_GEN2(dev)) { |
@@ -9579,17 +6607,7 @@ void intel_modeset_init(struct drm_device *dev) | |||
9579 | i915_disable_vga(dev); | 6607 | i915_disable_vga(dev); |
9580 | intel_setup_outputs(dev); | 6608 | intel_setup_outputs(dev); |
9581 | 6609 | ||
9582 | intel_init_clock_gating(dev); | 6610 | intel_modeset_init_hw(dev); |
9583 | |||
9584 | if (IS_IRONLAKE_M(dev)) { | ||
9585 | ironlake_enable_drps(dev); | ||
9586 | intel_init_emon(dev); | ||
9587 | } | ||
9588 | |||
9589 | if (IS_GEN6(dev) || IS_GEN7(dev)) { | ||
9590 | gen6_enable_rps(dev_priv); | ||
9591 | gen6_update_ring_freq(dev_priv); | ||
9592 | } | ||
9593 | 6611 | ||
9594 | INIT_WORK(&dev_priv->idle_work, intel_idle_update); | 6612 | INIT_WORK(&dev_priv->idle_work, intel_idle_update); |
9595 | setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer, | 6613 | setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer, |
@@ -9629,7 +6647,7 @@ void intel_modeset_cleanup(struct drm_device *dev) | |||
9629 | 6647 | ||
9630 | if (IS_IRONLAKE_M(dev)) | 6648 | if (IS_IRONLAKE_M(dev)) |
9631 | ironlake_disable_drps(dev); | 6649 | ironlake_disable_drps(dev); |
9632 | if (IS_GEN6(dev) || IS_GEN7(dev)) | 6650 | if ((IS_GEN6(dev) || IS_GEN7(dev)) && !IS_VALLEYVIEW(dev)) |
9633 | gen6_disable_rps(dev); | 6651 | gen6_disable_rps(dev); |
9634 | 6652 | ||
9635 | if (IS_IRONLAKE_M(dev)) | 6653 | if (IS_IRONLAKE_M(dev)) |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 110552ff302c..44cf32c8bcbf 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -219,14 +219,38 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes) | |||
219 | return (max_link_clock * max_lanes * 8) / 10; | 219 | return (max_link_clock * max_lanes * 8) / 10; |
220 | } | 220 | } |
221 | 221 | ||
222 | static bool | ||
223 | intel_dp_adjust_dithering(struct intel_dp *intel_dp, | ||
224 | struct drm_display_mode *mode, | ||
225 | struct drm_display_mode *adjusted_mode) | ||
226 | { | ||
227 | int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp)); | ||
228 | int max_lanes = intel_dp_max_lane_count(intel_dp); | ||
229 | int max_rate, mode_rate; | ||
230 | |||
231 | mode_rate = intel_dp_link_required(mode->clock, 24); | ||
232 | max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes); | ||
233 | |||
234 | if (mode_rate > max_rate) { | ||
235 | mode_rate = intel_dp_link_required(mode->clock, 18); | ||
236 | if (mode_rate > max_rate) | ||
237 | return false; | ||
238 | |||
239 | if (adjusted_mode) | ||
240 | adjusted_mode->private_flags | ||
241 | |= INTEL_MODE_DP_FORCE_6BPC; | ||
242 | |||
243 | return true; | ||
244 | } | ||
245 | |||
246 | return true; | ||
247 | } | ||
248 | |||
222 | static int | 249 | static int |
223 | intel_dp_mode_valid(struct drm_connector *connector, | 250 | intel_dp_mode_valid(struct drm_connector *connector, |
224 | struct drm_display_mode *mode) | 251 | struct drm_display_mode *mode) |
225 | { | 252 | { |
226 | struct intel_dp *intel_dp = intel_attached_dp(connector); | 253 | struct intel_dp *intel_dp = intel_attached_dp(connector); |
227 | int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp)); | ||
228 | int max_lanes = intel_dp_max_lane_count(intel_dp); | ||
229 | int max_rate, mode_rate; | ||
230 | 254 | ||
231 | if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) { | 255 | if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) { |
232 | if (mode->hdisplay > intel_dp->panel_fixed_mode->hdisplay) | 256 | if (mode->hdisplay > intel_dp->panel_fixed_mode->hdisplay) |
@@ -236,16 +260,8 @@ intel_dp_mode_valid(struct drm_connector *connector, | |||
236 | return MODE_PANEL; | 260 | return MODE_PANEL; |
237 | } | 261 | } |
238 | 262 | ||
239 | mode_rate = intel_dp_link_required(mode->clock, 24); | 263 | if (!intel_dp_adjust_dithering(intel_dp, mode, NULL)) |
240 | max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes); | 264 | return MODE_CLOCK_HIGH; |
241 | |||
242 | if (mode_rate > max_rate) { | ||
243 | mode_rate = intel_dp_link_required(mode->clock, 18); | ||
244 | if (mode_rate > max_rate) | ||
245 | return MODE_CLOCK_HIGH; | ||
246 | else | ||
247 | mode->private_flags |= INTEL_MODE_DP_FORCE_6BPC; | ||
248 | } | ||
249 | 265 | ||
250 | if (mode->clock < 10000) | 266 | if (mode->clock < 10000) |
251 | return MODE_CLOCK_LOW; | 267 | return MODE_CLOCK_LOW; |
@@ -672,7 +688,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
672 | int lane_count, clock; | 688 | int lane_count, clock; |
673 | int max_lane_count = intel_dp_max_lane_count(intel_dp); | 689 | int max_lane_count = intel_dp_max_lane_count(intel_dp); |
674 | int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0; | 690 | int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0; |
675 | int bpp = mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24; | 691 | int bpp; |
676 | static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; | 692 | static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; |
677 | 693 | ||
678 | if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) { | 694 | if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) { |
@@ -686,6 +702,11 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
686 | mode->clock = intel_dp->panel_fixed_mode->clock; | 702 | mode->clock = intel_dp->panel_fixed_mode->clock; |
687 | } | 703 | } |
688 | 704 | ||
705 | if (!intel_dp_adjust_dithering(intel_dp, mode, adjusted_mode)) | ||
706 | return false; | ||
707 | |||
708 | bpp = adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24; | ||
709 | |||
689 | for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { | 710 | for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { |
690 | for (clock = 0; clock <= max_clock; clock++) { | 711 | for (clock = 0; clock <= max_clock; clock++) { |
691 | int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); | 712 | int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); |
@@ -1128,6 +1149,7 @@ static void ironlake_edp_panel_off(struct intel_dp *intel_dp) | |||
1128 | DRM_DEBUG_KMS("Turn eDP power off\n"); | 1149 | DRM_DEBUG_KMS("Turn eDP power off\n"); |
1129 | 1150 | ||
1130 | WARN(intel_dp->want_panel_vdd, "Cannot turn power off while VDD is on\n"); | 1151 | WARN(intel_dp->want_panel_vdd, "Cannot turn power off while VDD is on\n"); |
1152 | ironlake_panel_vdd_off_sync(intel_dp); /* finish any pending work */ | ||
1131 | 1153 | ||
1132 | pp = ironlake_get_pp_control(dev_priv); | 1154 | pp = ironlake_get_pp_control(dev_priv); |
1133 | pp &= ~(POWER_TARGET_ON | EDP_FORCE_VDD | PANEL_POWER_RESET | EDP_BLC_ENABLE); | 1155 | pp &= ~(POWER_TARGET_ON | EDP_FORCE_VDD | PANEL_POWER_RESET | EDP_BLC_ENABLE); |
@@ -2462,6 +2484,13 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
2462 | pp_off = I915_READ(PCH_PP_OFF_DELAYS); | 2484 | pp_off = I915_READ(PCH_PP_OFF_DELAYS); |
2463 | pp_div = I915_READ(PCH_PP_DIVISOR); | 2485 | pp_div = I915_READ(PCH_PP_DIVISOR); |
2464 | 2486 | ||
2487 | if (!pp_on || !pp_off || !pp_div) { | ||
2488 | DRM_INFO("bad panel power sequencing delays, disabling panel\n"); | ||
2489 | intel_dp_encoder_destroy(&intel_dp->base.base); | ||
2490 | intel_dp_destroy(&intel_connector->base); | ||
2491 | return; | ||
2492 | } | ||
2493 | |||
2465 | /* Pull timing values out of registers */ | 2494 | /* Pull timing values out of registers */ |
2466 | cur.t1_t3 = (pp_on & PANEL_POWER_UP_DELAY_MASK) >> | 2495 | cur.t1_t3 = (pp_on & PANEL_POWER_UP_DELAY_MASK) >> |
2467 | PANEL_POWER_UP_DELAY_SHIFT; | 2496 | PANEL_POWER_UP_DELAY_SHIFT; |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 79cabf58d877..c5bf8bebf0b0 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -204,6 +204,25 @@ struct intel_plane { | |||
204 | struct drm_intel_sprite_colorkey *key); | 204 | struct drm_intel_sprite_colorkey *key); |
205 | }; | 205 | }; |
206 | 206 | ||
207 | struct intel_watermark_params { | ||
208 | unsigned long fifo_size; | ||
209 | unsigned long max_wm; | ||
210 | unsigned long default_wm; | ||
211 | unsigned long guard_size; | ||
212 | unsigned long cacheline_size; | ||
213 | }; | ||
214 | |||
215 | struct cxsr_latency { | ||
216 | int is_desktop; | ||
217 | int is_ddr3; | ||
218 | unsigned long fsb_freq; | ||
219 | unsigned long mem_freq; | ||
220 | unsigned long display_sr; | ||
221 | unsigned long display_hpll_disable; | ||
222 | unsigned long cursor_sr; | ||
223 | unsigned long cursor_hpll_disable; | ||
224 | }; | ||
225 | |||
207 | #define to_intel_crtc(x) container_of(x, struct intel_crtc, base) | 226 | #define to_intel_crtc(x) container_of(x, struct intel_crtc, base) |
208 | #define to_intel_connector(x) container_of(x, struct intel_connector, base) | 227 | #define to_intel_connector(x) container_of(x, struct intel_connector, base) |
209 | #define to_intel_encoder(x) container_of(x, struct intel_encoder, base) | 228 | #define to_intel_encoder(x) container_of(x, struct intel_encoder, base) |
@@ -320,6 +339,8 @@ extern bool intel_dpd_is_edp(struct drm_device *dev); | |||
320 | extern void intel_edp_link_config(struct intel_encoder *, int *, int *); | 339 | extern void intel_edp_link_config(struct intel_encoder *, int *, int *); |
321 | extern bool intel_encoder_is_pch_edp(struct drm_encoder *encoder); | 340 | extern bool intel_encoder_is_pch_edp(struct drm_encoder *encoder); |
322 | extern int intel_plane_init(struct drm_device *dev, enum pipe pipe); | 341 | extern int intel_plane_init(struct drm_device *dev, enum pipe pipe); |
342 | extern void intel_flush_display_plane(struct drm_i915_private *dev_priv, | ||
343 | enum plane plane); | ||
323 | 344 | ||
324 | /* intel_panel.c */ | 345 | /* intel_panel.c */ |
325 | extern void intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, | 346 | extern void intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, |
@@ -377,6 +398,7 @@ extern void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, | |||
377 | extern void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, | 398 | extern void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, |
378 | u16 *blue, int regno); | 399 | u16 *blue, int regno); |
379 | extern void intel_enable_clock_gating(struct drm_device *dev); | 400 | extern void intel_enable_clock_gating(struct drm_device *dev); |
401 | extern void ironlake_disable_rc6(struct drm_device *dev); | ||
380 | extern void ironlake_enable_drps(struct drm_device *dev); | 402 | extern void ironlake_enable_drps(struct drm_device *dev); |
381 | extern void ironlake_disable_drps(struct drm_device *dev); | 403 | extern void ironlake_disable_drps(struct drm_device *dev); |
382 | extern void gen6_enable_rps(struct drm_i915_private *dev_priv); | 404 | extern void gen6_enable_rps(struct drm_i915_private *dev_priv); |
@@ -422,7 +444,7 @@ extern void intel_write_eld(struct drm_encoder *encoder, | |||
422 | extern void intel_cpt_verify_modeset(struct drm_device *dev, int pipe); | 444 | extern void intel_cpt_verify_modeset(struct drm_device *dev, int pipe); |
423 | 445 | ||
424 | /* For use by IVB LP watermark workaround in intel_sprite.c */ | 446 | /* For use by IVB LP watermark workaround in intel_sprite.c */ |
425 | extern void sandybridge_update_wm(struct drm_device *dev); | 447 | extern void intel_update_watermarks(struct drm_device *dev); |
426 | extern void intel_update_sprite_watermarks(struct drm_device *dev, int pipe, | 448 | extern void intel_update_sprite_watermarks(struct drm_device *dev, int pipe, |
427 | uint32_t sprite_width, | 449 | uint32_t sprite_width, |
428 | int pixel_size); | 450 | int pixel_size); |
@@ -434,4 +456,11 @@ extern int intel_sprite_get_colorkey(struct drm_device *dev, void *data, | |||
434 | 456 | ||
435 | extern u32 intel_dpio_read(struct drm_i915_private *dev_priv, int reg); | 457 | extern u32 intel_dpio_read(struct drm_i915_private *dev_priv, int reg); |
436 | 458 | ||
459 | /* Power-related functions, located in intel_pm.c */ | ||
460 | extern void intel_init_pm(struct drm_device *dev); | ||
461 | /* FBC */ | ||
462 | extern bool intel_fbc_enabled(struct drm_device *dev); | ||
463 | extern void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval); | ||
464 | extern void intel_update_fbc(struct drm_device *dev); | ||
465 | |||
437 | #endif /* __INTEL_DRV_H__ */ | 466 | #endif /* __INTEL_DRV_H__ */ |
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 19ecd78b8a2c..71ef2896be96 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c | |||
@@ -94,7 +94,7 @@ static int intelfb_create(struct intel_fbdev *ifbdev, | |||
94 | mutex_lock(&dev->struct_mutex); | 94 | mutex_lock(&dev->struct_mutex); |
95 | 95 | ||
96 | /* Flush everything out, we'll be doing GTT only from now on */ | 96 | /* Flush everything out, we'll be doing GTT only from now on */ |
97 | ret = intel_pin_and_fence_fb_obj(dev, obj, false); | 97 | ret = intel_pin_and_fence_fb_obj(dev, obj, NULL); |
98 | if (ret) { | 98 | if (ret) { |
99 | DRM_ERROR("failed to pin fb: %d\n", ret); | 99 | DRM_ERROR("failed to pin fb: %d\n", ret); |
100 | goto out_unref; | 100 | goto out_unref; |
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index c12db7265893..e04255edc801 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c | |||
@@ -205,27 +205,29 @@ intel_gpio_setup(struct intel_gmbus *bus, u32 pin) | |||
205 | 205 | ||
206 | static int | 206 | static int |
207 | gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg, | 207 | gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg, |
208 | bool last) | 208 | u32 gmbus1_index) |
209 | { | 209 | { |
210 | int reg_offset = dev_priv->gpio_mmio_base; | 210 | int reg_offset = dev_priv->gpio_mmio_base; |
211 | u16 len = msg->len; | 211 | u16 len = msg->len; |
212 | u8 *buf = msg->buf; | 212 | u8 *buf = msg->buf; |
213 | 213 | ||
214 | I915_WRITE(GMBUS1 + reg_offset, | 214 | I915_WRITE(GMBUS1 + reg_offset, |
215 | gmbus1_index | | ||
215 | GMBUS_CYCLE_WAIT | | 216 | GMBUS_CYCLE_WAIT | |
216 | (last ? GMBUS_CYCLE_STOP : 0) | | ||
217 | (len << GMBUS_BYTE_COUNT_SHIFT) | | 217 | (len << GMBUS_BYTE_COUNT_SHIFT) | |
218 | (msg->addr << GMBUS_SLAVE_ADDR_SHIFT) | | 218 | (msg->addr << GMBUS_SLAVE_ADDR_SHIFT) | |
219 | GMBUS_SLAVE_READ | GMBUS_SW_RDY); | 219 | GMBUS_SLAVE_READ | GMBUS_SW_RDY); |
220 | POSTING_READ(GMBUS2 + reg_offset); | 220 | while (len) { |
221 | do { | 221 | int ret; |
222 | u32 val, loop = 0; | 222 | u32 val, loop = 0; |
223 | u32 gmbus2; | ||
223 | 224 | ||
224 | if (wait_for(I915_READ(GMBUS2 + reg_offset) & | 225 | ret = wait_for((gmbus2 = I915_READ(GMBUS2 + reg_offset)) & |
225 | (GMBUS_SATOER | GMBUS_HW_RDY), | 226 | (GMBUS_SATOER | GMBUS_HW_RDY), |
226 | 50)) | 227 | 50); |
228 | if (ret) | ||
227 | return -ETIMEDOUT; | 229 | return -ETIMEDOUT; |
228 | if (I915_READ(GMBUS2 + reg_offset) & GMBUS_SATOER) | 230 | if (gmbus2 & GMBUS_SATOER) |
229 | return -ENXIO; | 231 | return -ENXIO; |
230 | 232 | ||
231 | val = I915_READ(GMBUS3 + reg_offset); | 233 | val = I915_READ(GMBUS3 + reg_offset); |
@@ -233,14 +235,13 @@ gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg, | |||
233 | *buf++ = val & 0xff; | 235 | *buf++ = val & 0xff; |
234 | val >>= 8; | 236 | val >>= 8; |
235 | } while (--len && ++loop < 4); | 237 | } while (--len && ++loop < 4); |
236 | } while (len); | 238 | } |
237 | 239 | ||
238 | return 0; | 240 | return 0; |
239 | } | 241 | } |
240 | 242 | ||
241 | static int | 243 | static int |
242 | gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg, | 244 | gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg) |
243 | bool last) | ||
244 | { | 245 | { |
245 | int reg_offset = dev_priv->gpio_mmio_base; | 246 | int reg_offset = dev_priv->gpio_mmio_base; |
246 | u16 len = msg->len; | 247 | u16 len = msg->len; |
@@ -248,25 +249,20 @@ gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg, | |||
248 | u32 val, loop; | 249 | u32 val, loop; |
249 | 250 | ||
250 | val = loop = 0; | 251 | val = loop = 0; |
251 | do { | 252 | while (len && loop < 4) { |
252 | val |= *buf++ << (8 * loop); | 253 | val |= *buf++ << (8 * loop++); |
253 | } while (--len && ++loop < 4); | 254 | len -= 1; |
255 | } | ||
254 | 256 | ||
255 | I915_WRITE(GMBUS3 + reg_offset, val); | 257 | I915_WRITE(GMBUS3 + reg_offset, val); |
256 | I915_WRITE(GMBUS1 + reg_offset, | 258 | I915_WRITE(GMBUS1 + reg_offset, |
257 | GMBUS_CYCLE_WAIT | | 259 | GMBUS_CYCLE_WAIT | |
258 | (last ? GMBUS_CYCLE_STOP : 0) | | ||
259 | (msg->len << GMBUS_BYTE_COUNT_SHIFT) | | 260 | (msg->len << GMBUS_BYTE_COUNT_SHIFT) | |
260 | (msg->addr << GMBUS_SLAVE_ADDR_SHIFT) | | 261 | (msg->addr << GMBUS_SLAVE_ADDR_SHIFT) | |
261 | GMBUS_SLAVE_WRITE | GMBUS_SW_RDY); | 262 | GMBUS_SLAVE_WRITE | GMBUS_SW_RDY); |
262 | POSTING_READ(GMBUS2 + reg_offset); | ||
263 | while (len) { | 263 | while (len) { |
264 | if (wait_for(I915_READ(GMBUS2 + reg_offset) & | 264 | int ret; |
265 | (GMBUS_SATOER | GMBUS_HW_RDY), | 265 | u32 gmbus2; |
266 | 50)) | ||
267 | return -ETIMEDOUT; | ||
268 | if (I915_READ(GMBUS2 + reg_offset) & GMBUS_SATOER) | ||
269 | return -ENXIO; | ||
270 | 266 | ||
271 | val = loop = 0; | 267 | val = loop = 0; |
272 | do { | 268 | do { |
@@ -274,11 +270,58 @@ gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg, | |||
274 | } while (--len && ++loop < 4); | 270 | } while (--len && ++loop < 4); |
275 | 271 | ||
276 | I915_WRITE(GMBUS3 + reg_offset, val); | 272 | I915_WRITE(GMBUS3 + reg_offset, val); |
277 | POSTING_READ(GMBUS2 + reg_offset); | 273 | |
274 | ret = wait_for((gmbus2 = I915_READ(GMBUS2 + reg_offset)) & | ||
275 | (GMBUS_SATOER | GMBUS_HW_RDY), | ||
276 | 50); | ||
277 | if (ret) | ||
278 | return -ETIMEDOUT; | ||
279 | if (gmbus2 & GMBUS_SATOER) | ||
280 | return -ENXIO; | ||
278 | } | 281 | } |
279 | return 0; | 282 | return 0; |
280 | } | 283 | } |
281 | 284 | ||
285 | /* | ||
286 | * The gmbus controller can combine a 1 or 2 byte write with a read that | ||
287 | * immediately follows it by using an "INDEX" cycle. | ||
288 | */ | ||
289 | static bool | ||
290 | gmbus_is_index_read(struct i2c_msg *msgs, int i, int num) | ||
291 | { | ||
292 | return (i + 1 < num && | ||
293 | !(msgs[i].flags & I2C_M_RD) && msgs[i].len <= 2 && | ||
294 | (msgs[i + 1].flags & I2C_M_RD)); | ||
295 | } | ||
296 | |||
297 | static int | ||
298 | gmbus_xfer_index_read(struct drm_i915_private *dev_priv, struct i2c_msg *msgs) | ||
299 | { | ||
300 | int reg_offset = dev_priv->gpio_mmio_base; | ||
301 | u32 gmbus1_index = 0; | ||
302 | u32 gmbus5 = 0; | ||
303 | int ret; | ||
304 | |||
305 | if (msgs[0].len == 2) | ||
306 | gmbus5 = GMBUS_2BYTE_INDEX_EN | | ||
307 | msgs[0].buf[1] | (msgs[0].buf[0] << 8); | ||
308 | if (msgs[0].len == 1) | ||
309 | gmbus1_index = GMBUS_CYCLE_INDEX | | ||
310 | (msgs[0].buf[0] << GMBUS_SLAVE_INDEX_SHIFT); | ||
311 | |||
312 | /* GMBUS5 holds 16-bit index */ | ||
313 | if (gmbus5) | ||
314 | I915_WRITE(GMBUS5 + reg_offset, gmbus5); | ||
315 | |||
316 | ret = gmbus_xfer_read(dev_priv, &msgs[1], gmbus1_index); | ||
317 | |||
318 | /* Clear GMBUS5 after each index transfer */ | ||
319 | if (gmbus5) | ||
320 | I915_WRITE(GMBUS5 + reg_offset, 0); | ||
321 | |||
322 | return ret; | ||
323 | } | ||
324 | |||
282 | static int | 325 | static int |
283 | gmbus_xfer(struct i2c_adapter *adapter, | 326 | gmbus_xfer(struct i2c_adapter *adapter, |
284 | struct i2c_msg *msgs, | 327 | struct i2c_msg *msgs, |
@@ -288,7 +331,8 @@ gmbus_xfer(struct i2c_adapter *adapter, | |||
288 | struct intel_gmbus, | 331 | struct intel_gmbus, |
289 | adapter); | 332 | adapter); |
290 | struct drm_i915_private *dev_priv = bus->dev_priv; | 333 | struct drm_i915_private *dev_priv = bus->dev_priv; |
291 | int i, reg_offset, ret; | 334 | int i, reg_offset; |
335 | int ret = 0; | ||
292 | 336 | ||
293 | mutex_lock(&dev_priv->gmbus_mutex); | 337 | mutex_lock(&dev_priv->gmbus_mutex); |
294 | 338 | ||
@@ -302,47 +346,82 @@ gmbus_xfer(struct i2c_adapter *adapter, | |||
302 | I915_WRITE(GMBUS0 + reg_offset, bus->reg0); | 346 | I915_WRITE(GMBUS0 + reg_offset, bus->reg0); |
303 | 347 | ||
304 | for (i = 0; i < num; i++) { | 348 | for (i = 0; i < num; i++) { |
305 | bool last = i + 1 == num; | 349 | u32 gmbus2; |
306 | 350 | ||
307 | if (msgs[i].flags & I2C_M_RD) | 351 | if (gmbus_is_index_read(msgs, i, num)) { |
308 | ret = gmbus_xfer_read(dev_priv, &msgs[i], last); | 352 | ret = gmbus_xfer_index_read(dev_priv, &msgs[i]); |
309 | else | 353 | i += 1; /* set i to the index of the read xfer */ |
310 | ret = gmbus_xfer_write(dev_priv, &msgs[i], last); | 354 | } else if (msgs[i].flags & I2C_M_RD) { |
355 | ret = gmbus_xfer_read(dev_priv, &msgs[i], 0); | ||
356 | } else { | ||
357 | ret = gmbus_xfer_write(dev_priv, &msgs[i]); | ||
358 | } | ||
311 | 359 | ||
312 | if (ret == -ETIMEDOUT) | 360 | if (ret == -ETIMEDOUT) |
313 | goto timeout; | 361 | goto timeout; |
314 | if (ret == -ENXIO) | 362 | if (ret == -ENXIO) |
315 | goto clear_err; | 363 | goto clear_err; |
316 | 364 | ||
317 | if (!last && | 365 | ret = wait_for((gmbus2 = I915_READ(GMBUS2 + reg_offset)) & |
318 | wait_for(I915_READ(GMBUS2 + reg_offset) & | 366 | (GMBUS_SATOER | GMBUS_HW_WAIT_PHASE), |
319 | (GMBUS_SATOER | GMBUS_HW_WAIT_PHASE), | 367 | 50); |
320 | 50)) | 368 | if (ret) |
321 | goto timeout; | 369 | goto timeout; |
322 | if (I915_READ(GMBUS2 + reg_offset) & GMBUS_SATOER) | 370 | if (gmbus2 & GMBUS_SATOER) |
323 | goto clear_err; | 371 | goto clear_err; |
324 | } | 372 | } |
325 | 373 | ||
326 | goto done; | 374 | /* Generate a STOP condition on the bus. Note that gmbus can't generata |
375 | * a STOP on the very first cycle. To simplify the code we | ||
376 | * unconditionally generate the STOP condition with an additional gmbus | ||
377 | * cycle. */ | ||
378 | I915_WRITE(GMBUS1 + reg_offset, GMBUS_CYCLE_STOP | GMBUS_SW_RDY); | ||
379 | |||
380 | /* Mark the GMBUS interface as disabled after waiting for idle. | ||
381 | * We will re-enable it at the start of the next xfer, | ||
382 | * till then let it sleep. | ||
383 | */ | ||
384 | if (wait_for((I915_READ(GMBUS2 + reg_offset) & GMBUS_ACTIVE) == 0, | ||
385 | 10)) { | ||
386 | DRM_DEBUG_KMS("GMBUS [%s] timed out waiting for idle\n", | ||
387 | adapter->name); | ||
388 | ret = -ETIMEDOUT; | ||
389 | } | ||
390 | I915_WRITE(GMBUS0 + reg_offset, 0); | ||
391 | ret = ret ?: i; | ||
392 | goto out; | ||
327 | 393 | ||
328 | clear_err: | 394 | clear_err: |
395 | /* | ||
396 | * Wait for bus to IDLE before clearing NAK. | ||
397 | * If we clear the NAK while bus is still active, then it will stay | ||
398 | * active and the next transaction may fail. | ||
399 | */ | ||
400 | if (wait_for((I915_READ(GMBUS2 + reg_offset) & GMBUS_ACTIVE) == 0, | ||
401 | 10)) | ||
402 | DRM_DEBUG_KMS("GMBUS [%s] timed out after NAK\n", | ||
403 | adapter->name); | ||
404 | |||
329 | /* Toggle the Software Clear Interrupt bit. This has the effect | 405 | /* Toggle the Software Clear Interrupt bit. This has the effect |
330 | * of resetting the GMBUS controller and so clearing the | 406 | * of resetting the GMBUS controller and so clearing the |
331 | * BUS_ERROR raised by the slave's NAK. | 407 | * BUS_ERROR raised by the slave's NAK. |
332 | */ | 408 | */ |
333 | I915_WRITE(GMBUS1 + reg_offset, GMBUS_SW_CLR_INT); | 409 | I915_WRITE(GMBUS1 + reg_offset, GMBUS_SW_CLR_INT); |
334 | I915_WRITE(GMBUS1 + reg_offset, 0); | 410 | I915_WRITE(GMBUS1 + reg_offset, 0); |
411 | I915_WRITE(GMBUS0 + reg_offset, 0); | ||
335 | 412 | ||
336 | done: | 413 | DRM_DEBUG_KMS("GMBUS [%s] NAK for addr: %04x %c(%d)\n", |
337 | /* Mark the GMBUS interface as disabled after waiting for idle. | 414 | adapter->name, msgs[i].addr, |
338 | * We will re-enable it at the start of the next xfer, | 415 | (msgs[i].flags & I2C_M_RD) ? 'r' : 'w', msgs[i].len); |
339 | * till then let it sleep. | 416 | |
417 | /* | ||
418 | * If no ACK is received during the address phase of a transaction, | ||
419 | * the adapter must report -ENXIO. | ||
420 | * It is not clear what to return if no ACK is received at other times. | ||
421 | * So, we always return -ENXIO in all NAK cases, to ensure we send | ||
422 | * it at least during the one case that is specified. | ||
340 | */ | 423 | */ |
341 | if (wait_for((I915_READ(GMBUS2 + reg_offset) & GMBUS_ACTIVE) == 0, 10)) | 424 | ret = -ENXIO; |
342 | DRM_INFO("GMBUS [%s] timed out waiting for idle\n", | ||
343 | bus->adapter.name); | ||
344 | I915_WRITE(GMBUS0 + reg_offset, 0); | ||
345 | ret = i; | ||
346 | goto out; | 425 | goto out; |
347 | 426 | ||
348 | timeout: | 427 | timeout: |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c new file mode 100644 index 000000000000..36940a390ef2 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -0,0 +1,3075 @@ | |||
1 | /* | ||
2 | * Copyright © 2012 Intel Corporation | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice (including the next | ||
12 | * paragraph) shall be included in all copies or substantial portions of the | ||
13 | * Software. | ||
14 | * | ||
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
21 | * IN THE SOFTWARE. | ||
22 | * | ||
23 | * Authors: | ||
24 | * Eugeni Dodonov <eugeni.dodonov@intel.com> | ||
25 | * | ||
26 | */ | ||
27 | |||
28 | #include <linux/cpufreq.h> | ||
29 | #include "i915_drv.h" | ||
30 | #include "intel_drv.h" | ||
31 | |||
32 | /* FBC, or Frame Buffer Compression, is a technique employed to compress the | ||
33 | * framebuffer contents in-memory, aiming at reducing the required bandwidth | ||
34 | * during in-memory transfers and, therefore, reduce the power packet. | ||
35 | * | ||
36 | * The benefits of FBC are mostly visible with solid backgrounds and | ||
37 | * variation-less patterns. | ||
38 | * | ||
39 | * FBC-related functionality can be enabled by the means of the | ||
40 | * i915.i915_enable_fbc parameter | ||
41 | */ | ||
42 | |||
43 | static void i8xx_disable_fbc(struct drm_device *dev) | ||
44 | { | ||
45 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
46 | u32 fbc_ctl; | ||
47 | |||
48 | /* Disable compression */ | ||
49 | fbc_ctl = I915_READ(FBC_CONTROL); | ||
50 | if ((fbc_ctl & FBC_CTL_EN) == 0) | ||
51 | return; | ||
52 | |||
53 | fbc_ctl &= ~FBC_CTL_EN; | ||
54 | I915_WRITE(FBC_CONTROL, fbc_ctl); | ||
55 | |||
56 | /* Wait for compressing bit to clear */ | ||
57 | if (wait_for((I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) == 0, 10)) { | ||
58 | DRM_DEBUG_KMS("FBC idle timed out\n"); | ||
59 | return; | ||
60 | } | ||
61 | |||
62 | DRM_DEBUG_KMS("disabled FBC\n"); | ||
63 | } | ||
64 | |||
65 | static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | ||
66 | { | ||
67 | struct drm_device *dev = crtc->dev; | ||
68 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
69 | struct drm_framebuffer *fb = crtc->fb; | ||
70 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); | ||
71 | struct drm_i915_gem_object *obj = intel_fb->obj; | ||
72 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
73 | int cfb_pitch; | ||
74 | int plane, i; | ||
75 | u32 fbc_ctl, fbc_ctl2; | ||
76 | |||
77 | cfb_pitch = dev_priv->cfb_size / FBC_LL_SIZE; | ||
78 | if (fb->pitches[0] < cfb_pitch) | ||
79 | cfb_pitch = fb->pitches[0]; | ||
80 | |||
81 | /* FBC_CTL wants 64B units */ | ||
82 | cfb_pitch = (cfb_pitch / 64) - 1; | ||
83 | plane = intel_crtc->plane == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB; | ||
84 | |||
85 | /* Clear old tags */ | ||
86 | for (i = 0; i < (FBC_LL_SIZE / 32) + 1; i++) | ||
87 | I915_WRITE(FBC_TAG + (i * 4), 0); | ||
88 | |||
89 | /* Set it up... */ | ||
90 | fbc_ctl2 = FBC_CTL_FENCE_DBL | FBC_CTL_IDLE_IMM | FBC_CTL_CPU_FENCE; | ||
91 | fbc_ctl2 |= plane; | ||
92 | I915_WRITE(FBC_CONTROL2, fbc_ctl2); | ||
93 | I915_WRITE(FBC_FENCE_OFF, crtc->y); | ||
94 | |||
95 | /* enable it... */ | ||
96 | fbc_ctl = FBC_CTL_EN | FBC_CTL_PERIODIC; | ||
97 | if (IS_I945GM(dev)) | ||
98 | fbc_ctl |= FBC_CTL_C3_IDLE; /* 945 needs special SR handling */ | ||
99 | fbc_ctl |= (cfb_pitch & 0xff) << FBC_CTL_STRIDE_SHIFT; | ||
100 | fbc_ctl |= (interval & 0x2fff) << FBC_CTL_INTERVAL_SHIFT; | ||
101 | fbc_ctl |= obj->fence_reg; | ||
102 | I915_WRITE(FBC_CONTROL, fbc_ctl); | ||
103 | |||
104 | DRM_DEBUG_KMS("enabled FBC, pitch %d, yoff %d, plane %d, ", | ||
105 | cfb_pitch, crtc->y, intel_crtc->plane); | ||
106 | } | ||
107 | |||
108 | static bool i8xx_fbc_enabled(struct drm_device *dev) | ||
109 | { | ||
110 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
111 | |||
112 | return I915_READ(FBC_CONTROL) & FBC_CTL_EN; | ||
113 | } | ||
114 | |||
115 | static void g4x_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | ||
116 | { | ||
117 | struct drm_device *dev = crtc->dev; | ||
118 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
119 | struct drm_framebuffer *fb = crtc->fb; | ||
120 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); | ||
121 | struct drm_i915_gem_object *obj = intel_fb->obj; | ||
122 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
123 | int plane = intel_crtc->plane == 0 ? DPFC_CTL_PLANEA : DPFC_CTL_PLANEB; | ||
124 | unsigned long stall_watermark = 200; | ||
125 | u32 dpfc_ctl; | ||
126 | |||
127 | dpfc_ctl = plane | DPFC_SR_EN | DPFC_CTL_LIMIT_1X; | ||
128 | dpfc_ctl |= DPFC_CTL_FENCE_EN | obj->fence_reg; | ||
129 | I915_WRITE(DPFC_CHICKEN, DPFC_HT_MODIFY); | ||
130 | |||
131 | I915_WRITE(DPFC_RECOMP_CTL, DPFC_RECOMP_STALL_EN | | ||
132 | (stall_watermark << DPFC_RECOMP_STALL_WM_SHIFT) | | ||
133 | (interval << DPFC_RECOMP_TIMER_COUNT_SHIFT)); | ||
134 | I915_WRITE(DPFC_FENCE_YOFF, crtc->y); | ||
135 | |||
136 | /* enable it... */ | ||
137 | I915_WRITE(DPFC_CONTROL, I915_READ(DPFC_CONTROL) | DPFC_CTL_EN); | ||
138 | |||
139 | DRM_DEBUG_KMS("enabled fbc on plane %d\n", intel_crtc->plane); | ||
140 | } | ||
141 | |||
142 | static void g4x_disable_fbc(struct drm_device *dev) | ||
143 | { | ||
144 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
145 | u32 dpfc_ctl; | ||
146 | |||
147 | /* Disable compression */ | ||
148 | dpfc_ctl = I915_READ(DPFC_CONTROL); | ||
149 | if (dpfc_ctl & DPFC_CTL_EN) { | ||
150 | dpfc_ctl &= ~DPFC_CTL_EN; | ||
151 | I915_WRITE(DPFC_CONTROL, dpfc_ctl); | ||
152 | |||
153 | DRM_DEBUG_KMS("disabled FBC\n"); | ||
154 | } | ||
155 | } | ||
156 | |||
157 | static bool g4x_fbc_enabled(struct drm_device *dev) | ||
158 | { | ||
159 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
160 | |||
161 | return I915_READ(DPFC_CONTROL) & DPFC_CTL_EN; | ||
162 | } | ||
163 | |||
164 | static void sandybridge_blit_fbc_update(struct drm_device *dev) | ||
165 | { | ||
166 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
167 | u32 blt_ecoskpd; | ||
168 | |||
169 | /* Make sure blitter notifies FBC of writes */ | ||
170 | gen6_gt_force_wake_get(dev_priv); | ||
171 | blt_ecoskpd = I915_READ(GEN6_BLITTER_ECOSKPD); | ||
172 | blt_ecoskpd |= GEN6_BLITTER_FBC_NOTIFY << | ||
173 | GEN6_BLITTER_LOCK_SHIFT; | ||
174 | I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd); | ||
175 | blt_ecoskpd |= GEN6_BLITTER_FBC_NOTIFY; | ||
176 | I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd); | ||
177 | blt_ecoskpd &= ~(GEN6_BLITTER_FBC_NOTIFY << | ||
178 | GEN6_BLITTER_LOCK_SHIFT); | ||
179 | I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd); | ||
180 | POSTING_READ(GEN6_BLITTER_ECOSKPD); | ||
181 | gen6_gt_force_wake_put(dev_priv); | ||
182 | } | ||
183 | |||
184 | static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | ||
185 | { | ||
186 | struct drm_device *dev = crtc->dev; | ||
187 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
188 | struct drm_framebuffer *fb = crtc->fb; | ||
189 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); | ||
190 | struct drm_i915_gem_object *obj = intel_fb->obj; | ||
191 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
192 | int plane = intel_crtc->plane == 0 ? DPFC_CTL_PLANEA : DPFC_CTL_PLANEB; | ||
193 | unsigned long stall_watermark = 200; | ||
194 | u32 dpfc_ctl; | ||
195 | |||
196 | dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); | ||
197 | dpfc_ctl &= DPFC_RESERVED; | ||
198 | dpfc_ctl |= (plane | DPFC_CTL_LIMIT_1X); | ||
199 | /* Set persistent mode for front-buffer rendering, ala X. */ | ||
200 | dpfc_ctl |= DPFC_CTL_PERSISTENT_MODE; | ||
201 | dpfc_ctl |= (DPFC_CTL_FENCE_EN | obj->fence_reg); | ||
202 | I915_WRITE(ILK_DPFC_CHICKEN, DPFC_HT_MODIFY); | ||
203 | |||
204 | I915_WRITE(ILK_DPFC_RECOMP_CTL, DPFC_RECOMP_STALL_EN | | ||
205 | (stall_watermark << DPFC_RECOMP_STALL_WM_SHIFT) | | ||
206 | (interval << DPFC_RECOMP_TIMER_COUNT_SHIFT)); | ||
207 | I915_WRITE(ILK_DPFC_FENCE_YOFF, crtc->y); | ||
208 | I915_WRITE(ILK_FBC_RT_BASE, obj->gtt_offset | ILK_FBC_RT_VALID); | ||
209 | /* enable it... */ | ||
210 | I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN); | ||
211 | |||
212 | if (IS_GEN6(dev)) { | ||
213 | I915_WRITE(SNB_DPFC_CTL_SA, | ||
214 | SNB_CPU_FENCE_ENABLE | obj->fence_reg); | ||
215 | I915_WRITE(DPFC_CPU_FENCE_OFFSET, crtc->y); | ||
216 | sandybridge_blit_fbc_update(dev); | ||
217 | } | ||
218 | |||
219 | DRM_DEBUG_KMS("enabled fbc on plane %d\n", intel_crtc->plane); | ||
220 | } | ||
221 | |||
222 | static void ironlake_disable_fbc(struct drm_device *dev) | ||
223 | { | ||
224 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
225 | u32 dpfc_ctl; | ||
226 | |||
227 | /* Disable compression */ | ||
228 | dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); | ||
229 | if (dpfc_ctl & DPFC_CTL_EN) { | ||
230 | dpfc_ctl &= ~DPFC_CTL_EN; | ||
231 | I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl); | ||
232 | |||
233 | DRM_DEBUG_KMS("disabled FBC\n"); | ||
234 | } | ||
235 | } | ||
236 | |||
237 | static bool ironlake_fbc_enabled(struct drm_device *dev) | ||
238 | { | ||
239 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
240 | |||
241 | return I915_READ(ILK_DPFC_CONTROL) & DPFC_CTL_EN; | ||
242 | } | ||
243 | |||
244 | bool intel_fbc_enabled(struct drm_device *dev) | ||
245 | { | ||
246 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
247 | |||
248 | if (!dev_priv->display.fbc_enabled) | ||
249 | return false; | ||
250 | |||
251 | return dev_priv->display.fbc_enabled(dev); | ||
252 | } | ||
253 | |||
254 | static void intel_fbc_work_fn(struct work_struct *__work) | ||
255 | { | ||
256 | struct intel_fbc_work *work = | ||
257 | container_of(to_delayed_work(__work), | ||
258 | struct intel_fbc_work, work); | ||
259 | struct drm_device *dev = work->crtc->dev; | ||
260 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
261 | |||
262 | mutex_lock(&dev->struct_mutex); | ||
263 | if (work == dev_priv->fbc_work) { | ||
264 | /* Double check that we haven't switched fb without cancelling | ||
265 | * the prior work. | ||
266 | */ | ||
267 | if (work->crtc->fb == work->fb) { | ||
268 | dev_priv->display.enable_fbc(work->crtc, | ||
269 | work->interval); | ||
270 | |||
271 | dev_priv->cfb_plane = to_intel_crtc(work->crtc)->plane; | ||
272 | dev_priv->cfb_fb = work->crtc->fb->base.id; | ||
273 | dev_priv->cfb_y = work->crtc->y; | ||
274 | } | ||
275 | |||
276 | dev_priv->fbc_work = NULL; | ||
277 | } | ||
278 | mutex_unlock(&dev->struct_mutex); | ||
279 | |||
280 | kfree(work); | ||
281 | } | ||
282 | |||
283 | static void intel_cancel_fbc_work(struct drm_i915_private *dev_priv) | ||
284 | { | ||
285 | if (dev_priv->fbc_work == NULL) | ||
286 | return; | ||
287 | |||
288 | DRM_DEBUG_KMS("cancelling pending FBC enable\n"); | ||
289 | |||
290 | /* Synchronisation is provided by struct_mutex and checking of | ||
291 | * dev_priv->fbc_work, so we can perform the cancellation | ||
292 | * entirely asynchronously. | ||
293 | */ | ||
294 | if (cancel_delayed_work(&dev_priv->fbc_work->work)) | ||
295 | /* tasklet was killed before being run, clean up */ | ||
296 | kfree(dev_priv->fbc_work); | ||
297 | |||
298 | /* Mark the work as no longer wanted so that if it does | ||
299 | * wake-up (because the work was already running and waiting | ||
300 | * for our mutex), it will discover that is no longer | ||
301 | * necessary to run. | ||
302 | */ | ||
303 | dev_priv->fbc_work = NULL; | ||
304 | } | ||
305 | |||
306 | void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | ||
307 | { | ||
308 | struct intel_fbc_work *work; | ||
309 | struct drm_device *dev = crtc->dev; | ||
310 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
311 | |||
312 | if (!dev_priv->display.enable_fbc) | ||
313 | return; | ||
314 | |||
315 | intel_cancel_fbc_work(dev_priv); | ||
316 | |||
317 | work = kzalloc(sizeof *work, GFP_KERNEL); | ||
318 | if (work == NULL) { | ||
319 | dev_priv->display.enable_fbc(crtc, interval); | ||
320 | return; | ||
321 | } | ||
322 | |||
323 | work->crtc = crtc; | ||
324 | work->fb = crtc->fb; | ||
325 | work->interval = interval; | ||
326 | INIT_DELAYED_WORK(&work->work, intel_fbc_work_fn); | ||
327 | |||
328 | dev_priv->fbc_work = work; | ||
329 | |||
330 | DRM_DEBUG_KMS("scheduling delayed FBC enable\n"); | ||
331 | |||
332 | /* Delay the actual enabling to let pageflipping cease and the | ||
333 | * display to settle before starting the compression. Note that | ||
334 | * this delay also serves a second purpose: it allows for a | ||
335 | * vblank to pass after disabling the FBC before we attempt | ||
336 | * to modify the control registers. | ||
337 | * | ||
338 | * A more complicated solution would involve tracking vblanks | ||
339 | * following the termination of the page-flipping sequence | ||
340 | * and indeed performing the enable as a co-routine and not | ||
341 | * waiting synchronously upon the vblank. | ||
342 | */ | ||
343 | schedule_delayed_work(&work->work, msecs_to_jiffies(50)); | ||
344 | } | ||
345 | |||
346 | void intel_disable_fbc(struct drm_device *dev) | ||
347 | { | ||
348 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
349 | |||
350 | intel_cancel_fbc_work(dev_priv); | ||
351 | |||
352 | if (!dev_priv->display.disable_fbc) | ||
353 | return; | ||
354 | |||
355 | dev_priv->display.disable_fbc(dev); | ||
356 | dev_priv->cfb_plane = -1; | ||
357 | } | ||
358 | |||
359 | /** | ||
360 | * intel_update_fbc - enable/disable FBC as needed | ||
361 | * @dev: the drm_device | ||
362 | * | ||
363 | * Set up the framebuffer compression hardware at mode set time. We | ||
364 | * enable it if possible: | ||
365 | * - plane A only (on pre-965) | ||
366 | * - no pixel mulitply/line duplication | ||
367 | * - no alpha buffer discard | ||
368 | * - no dual wide | ||
369 | * - framebuffer <= 2048 in width, 1536 in height | ||
370 | * | ||
371 | * We can't assume that any compression will take place (worst case), | ||
372 | * so the compressed buffer has to be the same size as the uncompressed | ||
373 | * one. It also must reside (along with the line length buffer) in | ||
374 | * stolen memory. | ||
375 | * | ||
376 | * We need to enable/disable FBC on a global basis. | ||
377 | */ | ||
378 | void intel_update_fbc(struct drm_device *dev) | ||
379 | { | ||
380 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
381 | struct drm_crtc *crtc = NULL, *tmp_crtc; | ||
382 | struct intel_crtc *intel_crtc; | ||
383 | struct drm_framebuffer *fb; | ||
384 | struct intel_framebuffer *intel_fb; | ||
385 | struct drm_i915_gem_object *obj; | ||
386 | int enable_fbc; | ||
387 | |||
388 | DRM_DEBUG_KMS("\n"); | ||
389 | |||
390 | if (!i915_powersave) | ||
391 | return; | ||
392 | |||
393 | if (!I915_HAS_FBC(dev)) | ||
394 | return; | ||
395 | |||
396 | /* | ||
397 | * If FBC is already on, we just have to verify that we can | ||
398 | * keep it that way... | ||
399 | * Need to disable if: | ||
400 | * - more than one pipe is active | ||
401 | * - changing FBC params (stride, fence, mode) | ||
402 | * - new fb is too large to fit in compressed buffer | ||
403 | * - going to an unsupported config (interlace, pixel multiply, etc.) | ||
404 | */ | ||
405 | list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head) { | ||
406 | if (tmp_crtc->enabled && tmp_crtc->fb) { | ||
407 | if (crtc) { | ||
408 | DRM_DEBUG_KMS("more than one pipe active, disabling compression\n"); | ||
409 | dev_priv->no_fbc_reason = FBC_MULTIPLE_PIPES; | ||
410 | goto out_disable; | ||
411 | } | ||
412 | crtc = tmp_crtc; | ||
413 | } | ||
414 | } | ||
415 | |||
416 | if (!crtc || crtc->fb == NULL) { | ||
417 | DRM_DEBUG_KMS("no output, disabling\n"); | ||
418 | dev_priv->no_fbc_reason = FBC_NO_OUTPUT; | ||
419 | goto out_disable; | ||
420 | } | ||
421 | |||
422 | intel_crtc = to_intel_crtc(crtc); | ||
423 | fb = crtc->fb; | ||
424 | intel_fb = to_intel_framebuffer(fb); | ||
425 | obj = intel_fb->obj; | ||
426 | |||
427 | enable_fbc = i915_enable_fbc; | ||
428 | if (enable_fbc < 0) { | ||
429 | DRM_DEBUG_KMS("fbc set to per-chip default\n"); | ||
430 | enable_fbc = 1; | ||
431 | if (INTEL_INFO(dev)->gen <= 6) | ||
432 | enable_fbc = 0; | ||
433 | } | ||
434 | if (!enable_fbc) { | ||
435 | DRM_DEBUG_KMS("fbc disabled per module param\n"); | ||
436 | dev_priv->no_fbc_reason = FBC_MODULE_PARAM; | ||
437 | goto out_disable; | ||
438 | } | ||
439 | if (intel_fb->obj->base.size > dev_priv->cfb_size) { | ||
440 | DRM_DEBUG_KMS("framebuffer too large, disabling " | ||
441 | "compression\n"); | ||
442 | dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL; | ||
443 | goto out_disable; | ||
444 | } | ||
445 | if ((crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) || | ||
446 | (crtc->mode.flags & DRM_MODE_FLAG_DBLSCAN)) { | ||
447 | DRM_DEBUG_KMS("mode incompatible with compression, " | ||
448 | "disabling\n"); | ||
449 | dev_priv->no_fbc_reason = FBC_UNSUPPORTED_MODE; | ||
450 | goto out_disable; | ||
451 | } | ||
452 | if ((crtc->mode.hdisplay > 2048) || | ||
453 | (crtc->mode.vdisplay > 1536)) { | ||
454 | DRM_DEBUG_KMS("mode too large for compression, disabling\n"); | ||
455 | dev_priv->no_fbc_reason = FBC_MODE_TOO_LARGE; | ||
456 | goto out_disable; | ||
457 | } | ||
458 | if ((IS_I915GM(dev) || IS_I945GM(dev)) && intel_crtc->plane != 0) { | ||
459 | DRM_DEBUG_KMS("plane not 0, disabling compression\n"); | ||
460 | dev_priv->no_fbc_reason = FBC_BAD_PLANE; | ||
461 | goto out_disable; | ||
462 | } | ||
463 | |||
464 | /* The use of a CPU fence is mandatory in order to detect writes | ||
465 | * by the CPU to the scanout and trigger updates to the FBC. | ||
466 | */ | ||
467 | if (obj->tiling_mode != I915_TILING_X || | ||
468 | obj->fence_reg == I915_FENCE_REG_NONE) { | ||
469 | DRM_DEBUG_KMS("framebuffer not tiled or fenced, disabling compression\n"); | ||
470 | dev_priv->no_fbc_reason = FBC_NOT_TILED; | ||
471 | goto out_disable; | ||
472 | } | ||
473 | |||
474 | /* If the kernel debugger is active, always disable compression */ | ||
475 | if (in_dbg_master()) | ||
476 | goto out_disable; | ||
477 | |||
478 | /* If the scanout has not changed, don't modify the FBC settings. | ||
479 | * Note that we make the fundamental assumption that the fb->obj | ||
480 | * cannot be unpinned (and have its GTT offset and fence revoked) | ||
481 | * without first being decoupled from the scanout and FBC disabled. | ||
482 | */ | ||
483 | if (dev_priv->cfb_plane == intel_crtc->plane && | ||
484 | dev_priv->cfb_fb == fb->base.id && | ||
485 | dev_priv->cfb_y == crtc->y) | ||
486 | return; | ||
487 | |||
488 | if (intel_fbc_enabled(dev)) { | ||
489 | /* We update FBC along two paths, after changing fb/crtc | ||
490 | * configuration (modeswitching) and after page-flipping | ||
491 | * finishes. For the latter, we know that not only did | ||
492 | * we disable the FBC at the start of the page-flip | ||
493 | * sequence, but also more than one vblank has passed. | ||
494 | * | ||
495 | * For the former case of modeswitching, it is possible | ||
496 | * to switch between two FBC valid configurations | ||
497 | * instantaneously so we do need to disable the FBC | ||
498 | * before we can modify its control registers. We also | ||
499 | * have to wait for the next vblank for that to take | ||
500 | * effect. However, since we delay enabling FBC we can | ||
501 | * assume that a vblank has passed since disabling and | ||
502 | * that we can safely alter the registers in the deferred | ||
503 | * callback. | ||
504 | * | ||
505 | * In the scenario that we go from a valid to invalid | ||
506 | * and then back to valid FBC configuration we have | ||
507 | * no strict enforcement that a vblank occurred since | ||
508 | * disabling the FBC. However, along all current pipe | ||
509 | * disabling paths we do need to wait for a vblank at | ||
510 | * some point. And we wait before enabling FBC anyway. | ||
511 | */ | ||
512 | DRM_DEBUG_KMS("disabling active FBC for update\n"); | ||
513 | intel_disable_fbc(dev); | ||
514 | } | ||
515 | |||
516 | intel_enable_fbc(crtc, 500); | ||
517 | return; | ||
518 | |||
519 | out_disable: | ||
520 | /* Multiple disables should be harmless */ | ||
521 | if (intel_fbc_enabled(dev)) { | ||
522 | DRM_DEBUG_KMS("unsupported config, disabling FBC\n"); | ||
523 | intel_disable_fbc(dev); | ||
524 | } | ||
525 | } | ||
526 | |||
527 | static const struct cxsr_latency cxsr_latency_table[] = { | ||
528 | {1, 0, 800, 400, 3382, 33382, 3983, 33983}, /* DDR2-400 SC */ | ||
529 | {1, 0, 800, 667, 3354, 33354, 3807, 33807}, /* DDR2-667 SC */ | ||
530 | {1, 0, 800, 800, 3347, 33347, 3763, 33763}, /* DDR2-800 SC */ | ||
531 | {1, 1, 800, 667, 6420, 36420, 6873, 36873}, /* DDR3-667 SC */ | ||
532 | {1, 1, 800, 800, 5902, 35902, 6318, 36318}, /* DDR3-800 SC */ | ||
533 | |||
534 | {1, 0, 667, 400, 3400, 33400, 4021, 34021}, /* DDR2-400 SC */ | ||
535 | {1, 0, 667, 667, 3372, 33372, 3845, 33845}, /* DDR2-667 SC */ | ||
536 | {1, 0, 667, 800, 3386, 33386, 3822, 33822}, /* DDR2-800 SC */ | ||
537 | {1, 1, 667, 667, 6438, 36438, 6911, 36911}, /* DDR3-667 SC */ | ||
538 | {1, 1, 667, 800, 5941, 35941, 6377, 36377}, /* DDR3-800 SC */ | ||
539 | |||
540 | {1, 0, 400, 400, 3472, 33472, 4173, 34173}, /* DDR2-400 SC */ | ||
541 | {1, 0, 400, 667, 3443, 33443, 3996, 33996}, /* DDR2-667 SC */ | ||
542 | {1, 0, 400, 800, 3430, 33430, 3946, 33946}, /* DDR2-800 SC */ | ||
543 | {1, 1, 400, 667, 6509, 36509, 7062, 37062}, /* DDR3-667 SC */ | ||
544 | {1, 1, 400, 800, 5985, 35985, 6501, 36501}, /* DDR3-800 SC */ | ||
545 | |||
546 | {0, 0, 800, 400, 3438, 33438, 4065, 34065}, /* DDR2-400 SC */ | ||
547 | {0, 0, 800, 667, 3410, 33410, 3889, 33889}, /* DDR2-667 SC */ | ||
548 | {0, 0, 800, 800, 3403, 33403, 3845, 33845}, /* DDR2-800 SC */ | ||
549 | {0, 1, 800, 667, 6476, 36476, 6955, 36955}, /* DDR3-667 SC */ | ||
550 | {0, 1, 800, 800, 5958, 35958, 6400, 36400}, /* DDR3-800 SC */ | ||
551 | |||
552 | {0, 0, 667, 400, 3456, 33456, 4103, 34106}, /* DDR2-400 SC */ | ||
553 | {0, 0, 667, 667, 3428, 33428, 3927, 33927}, /* DDR2-667 SC */ | ||
554 | {0, 0, 667, 800, 3443, 33443, 3905, 33905}, /* DDR2-800 SC */ | ||
555 | {0, 1, 667, 667, 6494, 36494, 6993, 36993}, /* DDR3-667 SC */ | ||
556 | {0, 1, 667, 800, 5998, 35998, 6460, 36460}, /* DDR3-800 SC */ | ||
557 | |||
558 | {0, 0, 400, 400, 3528, 33528, 4255, 34255}, /* DDR2-400 SC */ | ||
559 | {0, 0, 400, 667, 3500, 33500, 4079, 34079}, /* DDR2-667 SC */ | ||
560 | {0, 0, 400, 800, 3487, 33487, 4029, 34029}, /* DDR2-800 SC */ | ||
561 | {0, 1, 400, 667, 6566, 36566, 7145, 37145}, /* DDR3-667 SC */ | ||
562 | {0, 1, 400, 800, 6042, 36042, 6584, 36584}, /* DDR3-800 SC */ | ||
563 | }; | ||
564 | |||
565 | const struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, | ||
566 | int is_ddr3, | ||
567 | int fsb, | ||
568 | int mem) | ||
569 | { | ||
570 | const struct cxsr_latency *latency; | ||
571 | int i; | ||
572 | |||
573 | if (fsb == 0 || mem == 0) | ||
574 | return NULL; | ||
575 | |||
576 | for (i = 0; i < ARRAY_SIZE(cxsr_latency_table); i++) { | ||
577 | latency = &cxsr_latency_table[i]; | ||
578 | if (is_desktop == latency->is_desktop && | ||
579 | is_ddr3 == latency->is_ddr3 && | ||
580 | fsb == latency->fsb_freq && mem == latency->mem_freq) | ||
581 | return latency; | ||
582 | } | ||
583 | |||
584 | DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n"); | ||
585 | |||
586 | return NULL; | ||
587 | } | ||
588 | |||
589 | static void pineview_disable_cxsr(struct drm_device *dev) | ||
590 | { | ||
591 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
592 | |||
593 | /* deactivate cxsr */ | ||
594 | I915_WRITE(DSPFW3, I915_READ(DSPFW3) & ~PINEVIEW_SELF_REFRESH_EN); | ||
595 | } | ||
596 | |||
597 | /* | ||
598 | * Latency for FIFO fetches is dependent on several factors: | ||
599 | * - memory configuration (speed, channels) | ||
600 | * - chipset | ||
601 | * - current MCH state | ||
602 | * It can be fairly high in some situations, so here we assume a fairly | ||
603 | * pessimal value. It's a tradeoff between extra memory fetches (if we | ||
604 | * set this value too high, the FIFO will fetch frequently to stay full) | ||
605 | * and power consumption (set it too low to save power and we might see | ||
606 | * FIFO underruns and display "flicker"). | ||
607 | * | ||
608 | * A value of 5us seems to be a good balance; safe for very low end | ||
609 | * platforms but not overly aggressive on lower latency configs. | ||
610 | */ | ||
611 | static const int latency_ns = 5000; | ||
612 | |||
613 | static int i9xx_get_fifo_size(struct drm_device *dev, int plane) | ||
614 | { | ||
615 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
616 | uint32_t dsparb = I915_READ(DSPARB); | ||
617 | int size; | ||
618 | |||
619 | size = dsparb & 0x7f; | ||
620 | if (plane) | ||
621 | size = ((dsparb >> DSPARB_CSTART_SHIFT) & 0x7f) - size; | ||
622 | |||
623 | DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb, | ||
624 | plane ? "B" : "A", size); | ||
625 | |||
626 | return size; | ||
627 | } | ||
628 | |||
629 | static int i85x_get_fifo_size(struct drm_device *dev, int plane) | ||
630 | { | ||
631 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
632 | uint32_t dsparb = I915_READ(DSPARB); | ||
633 | int size; | ||
634 | |||
635 | size = dsparb & 0x1ff; | ||
636 | if (plane) | ||
637 | size = ((dsparb >> DSPARB_BEND_SHIFT) & 0x1ff) - size; | ||
638 | size >>= 1; /* Convert to cachelines */ | ||
639 | |||
640 | DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb, | ||
641 | plane ? "B" : "A", size); | ||
642 | |||
643 | return size; | ||
644 | } | ||
645 | |||
646 | static int i845_get_fifo_size(struct drm_device *dev, int plane) | ||
647 | { | ||
648 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
649 | uint32_t dsparb = I915_READ(DSPARB); | ||
650 | int size; | ||
651 | |||
652 | size = dsparb & 0x7f; | ||
653 | size >>= 2; /* Convert to cachelines */ | ||
654 | |||
655 | DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb, | ||
656 | plane ? "B" : "A", | ||
657 | size); | ||
658 | |||
659 | return size; | ||
660 | } | ||
661 | |||
662 | static int i830_get_fifo_size(struct drm_device *dev, int plane) | ||
663 | { | ||
664 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
665 | uint32_t dsparb = I915_READ(DSPARB); | ||
666 | int size; | ||
667 | |||
668 | size = dsparb & 0x7f; | ||
669 | size >>= 1; /* Convert to cachelines */ | ||
670 | |||
671 | DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb, | ||
672 | plane ? "B" : "A", size); | ||
673 | |||
674 | return size; | ||
675 | } | ||
676 | |||
677 | /* Pineview has different values for various configs */ | ||
678 | static const struct intel_watermark_params pineview_display_wm = { | ||
679 | PINEVIEW_DISPLAY_FIFO, | ||
680 | PINEVIEW_MAX_WM, | ||
681 | PINEVIEW_DFT_WM, | ||
682 | PINEVIEW_GUARD_WM, | ||
683 | PINEVIEW_FIFO_LINE_SIZE | ||
684 | }; | ||
685 | static const struct intel_watermark_params pineview_display_hplloff_wm = { | ||
686 | PINEVIEW_DISPLAY_FIFO, | ||
687 | PINEVIEW_MAX_WM, | ||
688 | PINEVIEW_DFT_HPLLOFF_WM, | ||
689 | PINEVIEW_GUARD_WM, | ||
690 | PINEVIEW_FIFO_LINE_SIZE | ||
691 | }; | ||
692 | static const struct intel_watermark_params pineview_cursor_wm = { | ||
693 | PINEVIEW_CURSOR_FIFO, | ||
694 | PINEVIEW_CURSOR_MAX_WM, | ||
695 | PINEVIEW_CURSOR_DFT_WM, | ||
696 | PINEVIEW_CURSOR_GUARD_WM, | ||
697 | PINEVIEW_FIFO_LINE_SIZE, | ||
698 | }; | ||
699 | static const struct intel_watermark_params pineview_cursor_hplloff_wm = { | ||
700 | PINEVIEW_CURSOR_FIFO, | ||
701 | PINEVIEW_CURSOR_MAX_WM, | ||
702 | PINEVIEW_CURSOR_DFT_WM, | ||
703 | PINEVIEW_CURSOR_GUARD_WM, | ||
704 | PINEVIEW_FIFO_LINE_SIZE | ||
705 | }; | ||
706 | static const struct intel_watermark_params g4x_wm_info = { | ||
707 | G4X_FIFO_SIZE, | ||
708 | G4X_MAX_WM, | ||
709 | G4X_MAX_WM, | ||
710 | 2, | ||
711 | G4X_FIFO_LINE_SIZE, | ||
712 | }; | ||
713 | static const struct intel_watermark_params g4x_cursor_wm_info = { | ||
714 | I965_CURSOR_FIFO, | ||
715 | I965_CURSOR_MAX_WM, | ||
716 | I965_CURSOR_DFT_WM, | ||
717 | 2, | ||
718 | G4X_FIFO_LINE_SIZE, | ||
719 | }; | ||
720 | static const struct intel_watermark_params valleyview_wm_info = { | ||
721 | VALLEYVIEW_FIFO_SIZE, | ||
722 | VALLEYVIEW_MAX_WM, | ||
723 | VALLEYVIEW_MAX_WM, | ||
724 | 2, | ||
725 | G4X_FIFO_LINE_SIZE, | ||
726 | }; | ||
727 | static const struct intel_watermark_params valleyview_cursor_wm_info = { | ||
728 | I965_CURSOR_FIFO, | ||
729 | VALLEYVIEW_CURSOR_MAX_WM, | ||
730 | I965_CURSOR_DFT_WM, | ||
731 | 2, | ||
732 | G4X_FIFO_LINE_SIZE, | ||
733 | }; | ||
734 | static const struct intel_watermark_params i965_cursor_wm_info = { | ||
735 | I965_CURSOR_FIFO, | ||
736 | I965_CURSOR_MAX_WM, | ||
737 | I965_CURSOR_DFT_WM, | ||
738 | 2, | ||
739 | I915_FIFO_LINE_SIZE, | ||
740 | }; | ||
741 | static const struct intel_watermark_params i945_wm_info = { | ||
742 | I945_FIFO_SIZE, | ||
743 | I915_MAX_WM, | ||
744 | 1, | ||
745 | 2, | ||
746 | I915_FIFO_LINE_SIZE | ||
747 | }; | ||
748 | static const struct intel_watermark_params i915_wm_info = { | ||
749 | I915_FIFO_SIZE, | ||
750 | I915_MAX_WM, | ||
751 | 1, | ||
752 | 2, | ||
753 | I915_FIFO_LINE_SIZE | ||
754 | }; | ||
755 | static const struct intel_watermark_params i855_wm_info = { | ||
756 | I855GM_FIFO_SIZE, | ||
757 | I915_MAX_WM, | ||
758 | 1, | ||
759 | 2, | ||
760 | I830_FIFO_LINE_SIZE | ||
761 | }; | ||
762 | static const struct intel_watermark_params i830_wm_info = { | ||
763 | I830_FIFO_SIZE, | ||
764 | I915_MAX_WM, | ||
765 | 1, | ||
766 | 2, | ||
767 | I830_FIFO_LINE_SIZE | ||
768 | }; | ||
769 | |||
770 | static const struct intel_watermark_params ironlake_display_wm_info = { | ||
771 | ILK_DISPLAY_FIFO, | ||
772 | ILK_DISPLAY_MAXWM, | ||
773 | ILK_DISPLAY_DFTWM, | ||
774 | 2, | ||
775 | ILK_FIFO_LINE_SIZE | ||
776 | }; | ||
777 | static const struct intel_watermark_params ironlake_cursor_wm_info = { | ||
778 | ILK_CURSOR_FIFO, | ||
779 | ILK_CURSOR_MAXWM, | ||
780 | ILK_CURSOR_DFTWM, | ||
781 | 2, | ||
782 | ILK_FIFO_LINE_SIZE | ||
783 | }; | ||
784 | static const struct intel_watermark_params ironlake_display_srwm_info = { | ||
785 | ILK_DISPLAY_SR_FIFO, | ||
786 | ILK_DISPLAY_MAX_SRWM, | ||
787 | ILK_DISPLAY_DFT_SRWM, | ||
788 | 2, | ||
789 | ILK_FIFO_LINE_SIZE | ||
790 | }; | ||
791 | static const struct intel_watermark_params ironlake_cursor_srwm_info = { | ||
792 | ILK_CURSOR_SR_FIFO, | ||
793 | ILK_CURSOR_MAX_SRWM, | ||
794 | ILK_CURSOR_DFT_SRWM, | ||
795 | 2, | ||
796 | ILK_FIFO_LINE_SIZE | ||
797 | }; | ||
798 | |||
799 | static const struct intel_watermark_params sandybridge_display_wm_info = { | ||
800 | SNB_DISPLAY_FIFO, | ||
801 | SNB_DISPLAY_MAXWM, | ||
802 | SNB_DISPLAY_DFTWM, | ||
803 | 2, | ||
804 | SNB_FIFO_LINE_SIZE | ||
805 | }; | ||
806 | static const struct intel_watermark_params sandybridge_cursor_wm_info = { | ||
807 | SNB_CURSOR_FIFO, | ||
808 | SNB_CURSOR_MAXWM, | ||
809 | SNB_CURSOR_DFTWM, | ||
810 | 2, | ||
811 | SNB_FIFO_LINE_SIZE | ||
812 | }; | ||
813 | static const struct intel_watermark_params sandybridge_display_srwm_info = { | ||
814 | SNB_DISPLAY_SR_FIFO, | ||
815 | SNB_DISPLAY_MAX_SRWM, | ||
816 | SNB_DISPLAY_DFT_SRWM, | ||
817 | 2, | ||
818 | SNB_FIFO_LINE_SIZE | ||
819 | }; | ||
820 | static const struct intel_watermark_params sandybridge_cursor_srwm_info = { | ||
821 | SNB_CURSOR_SR_FIFO, | ||
822 | SNB_CURSOR_MAX_SRWM, | ||
823 | SNB_CURSOR_DFT_SRWM, | ||
824 | 2, | ||
825 | SNB_FIFO_LINE_SIZE | ||
826 | }; | ||
827 | |||
828 | |||
829 | /** | ||
830 | * intel_calculate_wm - calculate watermark level | ||
831 | * @clock_in_khz: pixel clock | ||
832 | * @wm: chip FIFO params | ||
833 | * @pixel_size: display pixel size | ||
834 | * @latency_ns: memory latency for the platform | ||
835 | * | ||
836 | * Calculate the watermark level (the level at which the display plane will | ||
837 | * start fetching from memory again). Each chip has a different display | ||
838 | * FIFO size and allocation, so the caller needs to figure that out and pass | ||
839 | * in the correct intel_watermark_params structure. | ||
840 | * | ||
841 | * As the pixel clock runs, the FIFO will be drained at a rate that depends | ||
842 | * on the pixel size. When it reaches the watermark level, it'll start | ||
843 | * fetching FIFO line sized based chunks from memory until the FIFO fills | ||
844 | * past the watermark point. If the FIFO drains completely, a FIFO underrun | ||
845 | * will occur, and a display engine hang could result. | ||
846 | */ | ||
847 | static unsigned long intel_calculate_wm(unsigned long clock_in_khz, | ||
848 | const struct intel_watermark_params *wm, | ||
849 | int fifo_size, | ||
850 | int pixel_size, | ||
851 | unsigned long latency_ns) | ||
852 | { | ||
853 | long entries_required, wm_size; | ||
854 | |||
855 | /* | ||
856 | * Note: we need to make sure we don't overflow for various clock & | ||
857 | * latency values. | ||
858 | * clocks go from a few thousand to several hundred thousand. | ||
859 | * latency is usually a few thousand | ||
860 | */ | ||
861 | entries_required = ((clock_in_khz / 1000) * pixel_size * latency_ns) / | ||
862 | 1000; | ||
863 | entries_required = DIV_ROUND_UP(entries_required, wm->cacheline_size); | ||
864 | |||
865 | DRM_DEBUG_KMS("FIFO entries required for mode: %ld\n", entries_required); | ||
866 | |||
867 | wm_size = fifo_size - (entries_required + wm->guard_size); | ||
868 | |||
869 | DRM_DEBUG_KMS("FIFO watermark level: %ld\n", wm_size); | ||
870 | |||
871 | /* Don't promote wm_size to unsigned... */ | ||
872 | if (wm_size > (long)wm->max_wm) | ||
873 | wm_size = wm->max_wm; | ||
874 | if (wm_size <= 0) | ||
875 | wm_size = wm->default_wm; | ||
876 | return wm_size; | ||
877 | } | ||
878 | |||
879 | static struct drm_crtc *single_enabled_crtc(struct drm_device *dev) | ||
880 | { | ||
881 | struct drm_crtc *crtc, *enabled = NULL; | ||
882 | |||
883 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | ||
884 | if (crtc->enabled && crtc->fb) { | ||
885 | if (enabled) | ||
886 | return NULL; | ||
887 | enabled = crtc; | ||
888 | } | ||
889 | } | ||
890 | |||
891 | return enabled; | ||
892 | } | ||
893 | |||
894 | static void pineview_update_wm(struct drm_device *dev) | ||
895 | { | ||
896 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
897 | struct drm_crtc *crtc; | ||
898 | const struct cxsr_latency *latency; | ||
899 | u32 reg; | ||
900 | unsigned long wm; | ||
901 | |||
902 | latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->is_ddr3, | ||
903 | dev_priv->fsb_freq, dev_priv->mem_freq); | ||
904 | if (!latency) { | ||
905 | DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n"); | ||
906 | pineview_disable_cxsr(dev); | ||
907 | return; | ||
908 | } | ||
909 | |||
910 | crtc = single_enabled_crtc(dev); | ||
911 | if (crtc) { | ||
912 | int clock = crtc->mode.clock; | ||
913 | int pixel_size = crtc->fb->bits_per_pixel / 8; | ||
914 | |||
915 | /* Display SR */ | ||
916 | wm = intel_calculate_wm(clock, &pineview_display_wm, | ||
917 | pineview_display_wm.fifo_size, | ||
918 | pixel_size, latency->display_sr); | ||
919 | reg = I915_READ(DSPFW1); | ||
920 | reg &= ~DSPFW_SR_MASK; | ||
921 | reg |= wm << DSPFW_SR_SHIFT; | ||
922 | I915_WRITE(DSPFW1, reg); | ||
923 | DRM_DEBUG_KMS("DSPFW1 register is %x\n", reg); | ||
924 | |||
925 | /* cursor SR */ | ||
926 | wm = intel_calculate_wm(clock, &pineview_cursor_wm, | ||
927 | pineview_display_wm.fifo_size, | ||
928 | pixel_size, latency->cursor_sr); | ||
929 | reg = I915_READ(DSPFW3); | ||
930 | reg &= ~DSPFW_CURSOR_SR_MASK; | ||
931 | reg |= (wm & 0x3f) << DSPFW_CURSOR_SR_SHIFT; | ||
932 | I915_WRITE(DSPFW3, reg); | ||
933 | |||
934 | /* Display HPLL off SR */ | ||
935 | wm = intel_calculate_wm(clock, &pineview_display_hplloff_wm, | ||
936 | pineview_display_hplloff_wm.fifo_size, | ||
937 | pixel_size, latency->display_hpll_disable); | ||
938 | reg = I915_READ(DSPFW3); | ||
939 | reg &= ~DSPFW_HPLL_SR_MASK; | ||
940 | reg |= wm & DSPFW_HPLL_SR_MASK; | ||
941 | I915_WRITE(DSPFW3, reg); | ||
942 | |||
943 | /* cursor HPLL off SR */ | ||
944 | wm = intel_calculate_wm(clock, &pineview_cursor_hplloff_wm, | ||
945 | pineview_display_hplloff_wm.fifo_size, | ||
946 | pixel_size, latency->cursor_hpll_disable); | ||
947 | reg = I915_READ(DSPFW3); | ||
948 | reg &= ~DSPFW_HPLL_CURSOR_MASK; | ||
949 | reg |= (wm & 0x3f) << DSPFW_HPLL_CURSOR_SHIFT; | ||
950 | I915_WRITE(DSPFW3, reg); | ||
951 | DRM_DEBUG_KMS("DSPFW3 register is %x\n", reg); | ||
952 | |||
953 | /* activate cxsr */ | ||
954 | I915_WRITE(DSPFW3, | ||
955 | I915_READ(DSPFW3) | PINEVIEW_SELF_REFRESH_EN); | ||
956 | DRM_DEBUG_KMS("Self-refresh is enabled\n"); | ||
957 | } else { | ||
958 | pineview_disable_cxsr(dev); | ||
959 | DRM_DEBUG_KMS("Self-refresh is disabled\n"); | ||
960 | } | ||
961 | } | ||
962 | |||
963 | static bool g4x_compute_wm0(struct drm_device *dev, | ||
964 | int plane, | ||
965 | const struct intel_watermark_params *display, | ||
966 | int display_latency_ns, | ||
967 | const struct intel_watermark_params *cursor, | ||
968 | int cursor_latency_ns, | ||
969 | int *plane_wm, | ||
970 | int *cursor_wm) | ||
971 | { | ||
972 | struct drm_crtc *crtc; | ||
973 | int htotal, hdisplay, clock, pixel_size; | ||
974 | int line_time_us, line_count; | ||
975 | int entries, tlb_miss; | ||
976 | |||
977 | crtc = intel_get_crtc_for_plane(dev, plane); | ||
978 | if (crtc->fb == NULL || !crtc->enabled) { | ||
979 | *cursor_wm = cursor->guard_size; | ||
980 | *plane_wm = display->guard_size; | ||
981 | return false; | ||
982 | } | ||
983 | |||
984 | htotal = crtc->mode.htotal; | ||
985 | hdisplay = crtc->mode.hdisplay; | ||
986 | clock = crtc->mode.clock; | ||
987 | pixel_size = crtc->fb->bits_per_pixel / 8; | ||
988 | |||
989 | /* Use the small buffer method to calculate plane watermark */ | ||
990 | entries = ((clock * pixel_size / 1000) * display_latency_ns) / 1000; | ||
991 | tlb_miss = display->fifo_size*display->cacheline_size - hdisplay * 8; | ||
992 | if (tlb_miss > 0) | ||
993 | entries += tlb_miss; | ||
994 | entries = DIV_ROUND_UP(entries, display->cacheline_size); | ||
995 | *plane_wm = entries + display->guard_size; | ||
996 | if (*plane_wm > (int)display->max_wm) | ||
997 | *plane_wm = display->max_wm; | ||
998 | |||
999 | /* Use the large buffer method to calculate cursor watermark */ | ||
1000 | line_time_us = ((htotal * 1000) / clock); | ||
1001 | line_count = (cursor_latency_ns / line_time_us + 1000) / 1000; | ||
1002 | entries = line_count * 64 * pixel_size; | ||
1003 | tlb_miss = cursor->fifo_size*cursor->cacheline_size - hdisplay * 8; | ||
1004 | if (tlb_miss > 0) | ||
1005 | entries += tlb_miss; | ||
1006 | entries = DIV_ROUND_UP(entries, cursor->cacheline_size); | ||
1007 | *cursor_wm = entries + cursor->guard_size; | ||
1008 | if (*cursor_wm > (int)cursor->max_wm) | ||
1009 | *cursor_wm = (int)cursor->max_wm; | ||
1010 | |||
1011 | return true; | ||
1012 | } | ||
1013 | |||
1014 | /* | ||
1015 | * Check the wm result. | ||
1016 | * | ||
1017 | * If any calculated watermark values is larger than the maximum value that | ||
1018 | * can be programmed into the associated watermark register, that watermark | ||
1019 | * must be disabled. | ||
1020 | */ | ||
1021 | static bool g4x_check_srwm(struct drm_device *dev, | ||
1022 | int display_wm, int cursor_wm, | ||
1023 | const struct intel_watermark_params *display, | ||
1024 | const struct intel_watermark_params *cursor) | ||
1025 | { | ||
1026 | DRM_DEBUG_KMS("SR watermark: display plane %d, cursor %d\n", | ||
1027 | display_wm, cursor_wm); | ||
1028 | |||
1029 | if (display_wm > display->max_wm) { | ||
1030 | DRM_DEBUG_KMS("display watermark is too large(%d/%ld), disabling\n", | ||
1031 | display_wm, display->max_wm); | ||
1032 | return false; | ||
1033 | } | ||
1034 | |||
1035 | if (cursor_wm > cursor->max_wm) { | ||
1036 | DRM_DEBUG_KMS("cursor watermark is too large(%d/%ld), disabling\n", | ||
1037 | cursor_wm, cursor->max_wm); | ||
1038 | return false; | ||
1039 | } | ||
1040 | |||
1041 | if (!(display_wm || cursor_wm)) { | ||
1042 | DRM_DEBUG_KMS("SR latency is 0, disabling\n"); | ||
1043 | return false; | ||
1044 | } | ||
1045 | |||
1046 | return true; | ||
1047 | } | ||
1048 | |||
1049 | static bool g4x_compute_srwm(struct drm_device *dev, | ||
1050 | int plane, | ||
1051 | int latency_ns, | ||
1052 | const struct intel_watermark_params *display, | ||
1053 | const struct intel_watermark_params *cursor, | ||
1054 | int *display_wm, int *cursor_wm) | ||
1055 | { | ||
1056 | struct drm_crtc *crtc; | ||
1057 | int hdisplay, htotal, pixel_size, clock; | ||
1058 | unsigned long line_time_us; | ||
1059 | int line_count, line_size; | ||
1060 | int small, large; | ||
1061 | int entries; | ||
1062 | |||
1063 | if (!latency_ns) { | ||
1064 | *display_wm = *cursor_wm = 0; | ||
1065 | return false; | ||
1066 | } | ||
1067 | |||
1068 | crtc = intel_get_crtc_for_plane(dev, plane); | ||
1069 | hdisplay = crtc->mode.hdisplay; | ||
1070 | htotal = crtc->mode.htotal; | ||
1071 | clock = crtc->mode.clock; | ||
1072 | pixel_size = crtc->fb->bits_per_pixel / 8; | ||
1073 | |||
1074 | line_time_us = (htotal * 1000) / clock; | ||
1075 | line_count = (latency_ns / line_time_us + 1000) / 1000; | ||
1076 | line_size = hdisplay * pixel_size; | ||
1077 | |||
1078 | /* Use the minimum of the small and large buffer method for primary */ | ||
1079 | small = ((clock * pixel_size / 1000) * latency_ns) / 1000; | ||
1080 | large = line_count * line_size; | ||
1081 | |||
1082 | entries = DIV_ROUND_UP(min(small, large), display->cacheline_size); | ||
1083 | *display_wm = entries + display->guard_size; | ||
1084 | |||
1085 | /* calculate the self-refresh watermark for display cursor */ | ||
1086 | entries = line_count * pixel_size * 64; | ||
1087 | entries = DIV_ROUND_UP(entries, cursor->cacheline_size); | ||
1088 | *cursor_wm = entries + cursor->guard_size; | ||
1089 | |||
1090 | return g4x_check_srwm(dev, | ||
1091 | *display_wm, *cursor_wm, | ||
1092 | display, cursor); | ||
1093 | } | ||
1094 | |||
1095 | static bool vlv_compute_drain_latency(struct drm_device *dev, | ||
1096 | int plane, | ||
1097 | int *plane_prec_mult, | ||
1098 | int *plane_dl, | ||
1099 | int *cursor_prec_mult, | ||
1100 | int *cursor_dl) | ||
1101 | { | ||
1102 | struct drm_crtc *crtc; | ||
1103 | int clock, pixel_size; | ||
1104 | int entries; | ||
1105 | |||
1106 | crtc = intel_get_crtc_for_plane(dev, plane); | ||
1107 | if (crtc->fb == NULL || !crtc->enabled) | ||
1108 | return false; | ||
1109 | |||
1110 | clock = crtc->mode.clock; /* VESA DOT Clock */ | ||
1111 | pixel_size = crtc->fb->bits_per_pixel / 8; /* BPP */ | ||
1112 | |||
1113 | entries = (clock / 1000) * pixel_size; | ||
1114 | *plane_prec_mult = (entries > 256) ? | ||
1115 | DRAIN_LATENCY_PRECISION_32 : DRAIN_LATENCY_PRECISION_16; | ||
1116 | *plane_dl = (64 * (*plane_prec_mult) * 4) / ((clock / 1000) * | ||
1117 | pixel_size); | ||
1118 | |||
1119 | entries = (clock / 1000) * 4; /* BPP is always 4 for cursor */ | ||
1120 | *cursor_prec_mult = (entries > 256) ? | ||
1121 | DRAIN_LATENCY_PRECISION_32 : DRAIN_LATENCY_PRECISION_16; | ||
1122 | *cursor_dl = (64 * (*cursor_prec_mult) * 4) / ((clock / 1000) * 4); | ||
1123 | |||
1124 | return true; | ||
1125 | } | ||
1126 | |||
1127 | /* | ||
1128 | * Update drain latency registers of memory arbiter | ||
1129 | * | ||
1130 | * Valleyview SoC has a new memory arbiter and needs drain latency registers | ||
1131 | * to be programmed. Each plane has a drain latency multiplier and a drain | ||
1132 | * latency value. | ||
1133 | */ | ||
1134 | |||
1135 | static void vlv_update_drain_latency(struct drm_device *dev) | ||
1136 | { | ||
1137 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1138 | int planea_prec, planea_dl, planeb_prec, planeb_dl; | ||
1139 | int cursora_prec, cursora_dl, cursorb_prec, cursorb_dl; | ||
1140 | int plane_prec_mult, cursor_prec_mult; /* Precision multiplier is | ||
1141 | either 16 or 32 */ | ||
1142 | |||
1143 | /* For plane A, Cursor A */ | ||
1144 | if (vlv_compute_drain_latency(dev, 0, &plane_prec_mult, &planea_dl, | ||
1145 | &cursor_prec_mult, &cursora_dl)) { | ||
1146 | cursora_prec = (cursor_prec_mult == DRAIN_LATENCY_PRECISION_32) ? | ||
1147 | DDL_CURSORA_PRECISION_32 : DDL_CURSORA_PRECISION_16; | ||
1148 | planea_prec = (plane_prec_mult == DRAIN_LATENCY_PRECISION_32) ? | ||
1149 | DDL_PLANEA_PRECISION_32 : DDL_PLANEA_PRECISION_16; | ||
1150 | |||
1151 | I915_WRITE(VLV_DDL1, cursora_prec | | ||
1152 | (cursora_dl << DDL_CURSORA_SHIFT) | | ||
1153 | planea_prec | planea_dl); | ||
1154 | } | ||
1155 | |||
1156 | /* For plane B, Cursor B */ | ||
1157 | if (vlv_compute_drain_latency(dev, 1, &plane_prec_mult, &planeb_dl, | ||
1158 | &cursor_prec_mult, &cursorb_dl)) { | ||
1159 | cursorb_prec = (cursor_prec_mult == DRAIN_LATENCY_PRECISION_32) ? | ||
1160 | DDL_CURSORB_PRECISION_32 : DDL_CURSORB_PRECISION_16; | ||
1161 | planeb_prec = (plane_prec_mult == DRAIN_LATENCY_PRECISION_32) ? | ||
1162 | DDL_PLANEB_PRECISION_32 : DDL_PLANEB_PRECISION_16; | ||
1163 | |||
1164 | I915_WRITE(VLV_DDL2, cursorb_prec | | ||
1165 | (cursorb_dl << DDL_CURSORB_SHIFT) | | ||
1166 | planeb_prec | planeb_dl); | ||
1167 | } | ||
1168 | } | ||
1169 | |||
1170 | #define single_plane_enabled(mask) is_power_of_2(mask) | ||
1171 | |||
1172 | static void valleyview_update_wm(struct drm_device *dev) | ||
1173 | { | ||
1174 | static const int sr_latency_ns = 12000; | ||
1175 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1176 | int planea_wm, planeb_wm, cursora_wm, cursorb_wm; | ||
1177 | int plane_sr, cursor_sr; | ||
1178 | unsigned int enabled = 0; | ||
1179 | |||
1180 | vlv_update_drain_latency(dev); | ||
1181 | |||
1182 | if (g4x_compute_wm0(dev, 0, | ||
1183 | &valleyview_wm_info, latency_ns, | ||
1184 | &valleyview_cursor_wm_info, latency_ns, | ||
1185 | &planea_wm, &cursora_wm)) | ||
1186 | enabled |= 1; | ||
1187 | |||
1188 | if (g4x_compute_wm0(dev, 1, | ||
1189 | &valleyview_wm_info, latency_ns, | ||
1190 | &valleyview_cursor_wm_info, latency_ns, | ||
1191 | &planeb_wm, &cursorb_wm)) | ||
1192 | enabled |= 2; | ||
1193 | |||
1194 | plane_sr = cursor_sr = 0; | ||
1195 | if (single_plane_enabled(enabled) && | ||
1196 | g4x_compute_srwm(dev, ffs(enabled) - 1, | ||
1197 | sr_latency_ns, | ||
1198 | &valleyview_wm_info, | ||
1199 | &valleyview_cursor_wm_info, | ||
1200 | &plane_sr, &cursor_sr)) | ||
1201 | I915_WRITE(FW_BLC_SELF_VLV, FW_CSPWRDWNEN); | ||
1202 | else | ||
1203 | I915_WRITE(FW_BLC_SELF_VLV, | ||
1204 | I915_READ(FW_BLC_SELF_VLV) & ~FW_CSPWRDWNEN); | ||
1205 | |||
1206 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: plane=%d, cursor=%d, B: plane=%d, cursor=%d, SR: plane=%d, cursor=%d\n", | ||
1207 | planea_wm, cursora_wm, | ||
1208 | planeb_wm, cursorb_wm, | ||
1209 | plane_sr, cursor_sr); | ||
1210 | |||
1211 | I915_WRITE(DSPFW1, | ||
1212 | (plane_sr << DSPFW_SR_SHIFT) | | ||
1213 | (cursorb_wm << DSPFW_CURSORB_SHIFT) | | ||
1214 | (planeb_wm << DSPFW_PLANEB_SHIFT) | | ||
1215 | planea_wm); | ||
1216 | I915_WRITE(DSPFW2, | ||
1217 | (I915_READ(DSPFW2) & DSPFW_CURSORA_MASK) | | ||
1218 | (cursora_wm << DSPFW_CURSORA_SHIFT)); | ||
1219 | I915_WRITE(DSPFW3, | ||
1220 | (I915_READ(DSPFW3) | (cursor_sr << DSPFW_CURSOR_SR_SHIFT))); | ||
1221 | } | ||
1222 | |||
1223 | static void g4x_update_wm(struct drm_device *dev) | ||
1224 | { | ||
1225 | static const int sr_latency_ns = 12000; | ||
1226 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1227 | int planea_wm, planeb_wm, cursora_wm, cursorb_wm; | ||
1228 | int plane_sr, cursor_sr; | ||
1229 | unsigned int enabled = 0; | ||
1230 | |||
1231 | if (g4x_compute_wm0(dev, 0, | ||
1232 | &g4x_wm_info, latency_ns, | ||
1233 | &g4x_cursor_wm_info, latency_ns, | ||
1234 | &planea_wm, &cursora_wm)) | ||
1235 | enabled |= 1; | ||
1236 | |||
1237 | if (g4x_compute_wm0(dev, 1, | ||
1238 | &g4x_wm_info, latency_ns, | ||
1239 | &g4x_cursor_wm_info, latency_ns, | ||
1240 | &planeb_wm, &cursorb_wm)) | ||
1241 | enabled |= 2; | ||
1242 | |||
1243 | plane_sr = cursor_sr = 0; | ||
1244 | if (single_plane_enabled(enabled) && | ||
1245 | g4x_compute_srwm(dev, ffs(enabled) - 1, | ||
1246 | sr_latency_ns, | ||
1247 | &g4x_wm_info, | ||
1248 | &g4x_cursor_wm_info, | ||
1249 | &plane_sr, &cursor_sr)) | ||
1250 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); | ||
1251 | else | ||
1252 | I915_WRITE(FW_BLC_SELF, | ||
1253 | I915_READ(FW_BLC_SELF) & ~FW_BLC_SELF_EN); | ||
1254 | |||
1255 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: plane=%d, cursor=%d, B: plane=%d, cursor=%d, SR: plane=%d, cursor=%d\n", | ||
1256 | planea_wm, cursora_wm, | ||
1257 | planeb_wm, cursorb_wm, | ||
1258 | plane_sr, cursor_sr); | ||
1259 | |||
1260 | I915_WRITE(DSPFW1, | ||
1261 | (plane_sr << DSPFW_SR_SHIFT) | | ||
1262 | (cursorb_wm << DSPFW_CURSORB_SHIFT) | | ||
1263 | (planeb_wm << DSPFW_PLANEB_SHIFT) | | ||
1264 | planea_wm); | ||
1265 | I915_WRITE(DSPFW2, | ||
1266 | (I915_READ(DSPFW2) & DSPFW_CURSORA_MASK) | | ||
1267 | (cursora_wm << DSPFW_CURSORA_SHIFT)); | ||
1268 | /* HPLL off in SR has some issues on G4x... disable it */ | ||
1269 | I915_WRITE(DSPFW3, | ||
1270 | (I915_READ(DSPFW3) & ~DSPFW_HPLL_SR_EN) | | ||
1271 | (cursor_sr << DSPFW_CURSOR_SR_SHIFT)); | ||
1272 | } | ||
1273 | |||
1274 | static void i965_update_wm(struct drm_device *dev) | ||
1275 | { | ||
1276 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1277 | struct drm_crtc *crtc; | ||
1278 | int srwm = 1; | ||
1279 | int cursor_sr = 16; | ||
1280 | |||
1281 | /* Calc sr entries for one plane configs */ | ||
1282 | crtc = single_enabled_crtc(dev); | ||
1283 | if (crtc) { | ||
1284 | /* self-refresh has much higher latency */ | ||
1285 | static const int sr_latency_ns = 12000; | ||
1286 | int clock = crtc->mode.clock; | ||
1287 | int htotal = crtc->mode.htotal; | ||
1288 | int hdisplay = crtc->mode.hdisplay; | ||
1289 | int pixel_size = crtc->fb->bits_per_pixel / 8; | ||
1290 | unsigned long line_time_us; | ||
1291 | int entries; | ||
1292 | |||
1293 | line_time_us = ((htotal * 1000) / clock); | ||
1294 | |||
1295 | /* Use ns/us then divide to preserve precision */ | ||
1296 | entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * | ||
1297 | pixel_size * hdisplay; | ||
1298 | entries = DIV_ROUND_UP(entries, I915_FIFO_LINE_SIZE); | ||
1299 | srwm = I965_FIFO_SIZE - entries; | ||
1300 | if (srwm < 0) | ||
1301 | srwm = 1; | ||
1302 | srwm &= 0x1ff; | ||
1303 | DRM_DEBUG_KMS("self-refresh entries: %d, wm: %d\n", | ||
1304 | entries, srwm); | ||
1305 | |||
1306 | entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * | ||
1307 | pixel_size * 64; | ||
1308 | entries = DIV_ROUND_UP(entries, | ||
1309 | i965_cursor_wm_info.cacheline_size); | ||
1310 | cursor_sr = i965_cursor_wm_info.fifo_size - | ||
1311 | (entries + i965_cursor_wm_info.guard_size); | ||
1312 | |||
1313 | if (cursor_sr > i965_cursor_wm_info.max_wm) | ||
1314 | cursor_sr = i965_cursor_wm_info.max_wm; | ||
1315 | |||
1316 | DRM_DEBUG_KMS("self-refresh watermark: display plane %d " | ||
1317 | "cursor %d\n", srwm, cursor_sr); | ||
1318 | |||
1319 | if (IS_CRESTLINE(dev)) | ||
1320 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); | ||
1321 | } else { | ||
1322 | /* Turn off self refresh if both pipes are enabled */ | ||
1323 | if (IS_CRESTLINE(dev)) | ||
1324 | I915_WRITE(FW_BLC_SELF, I915_READ(FW_BLC_SELF) | ||
1325 | & ~FW_BLC_SELF_EN); | ||
1326 | } | ||
1327 | |||
1328 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: 8, B: 8, C: 8, SR %d\n", | ||
1329 | srwm); | ||
1330 | |||
1331 | /* 965 has limitations... */ | ||
1332 | I915_WRITE(DSPFW1, (srwm << DSPFW_SR_SHIFT) | | ||
1333 | (8 << 16) | (8 << 8) | (8 << 0)); | ||
1334 | I915_WRITE(DSPFW2, (8 << 8) | (8 << 0)); | ||
1335 | /* update cursor SR watermark */ | ||
1336 | I915_WRITE(DSPFW3, (cursor_sr << DSPFW_CURSOR_SR_SHIFT)); | ||
1337 | } | ||
1338 | |||
1339 | static void i9xx_update_wm(struct drm_device *dev) | ||
1340 | { | ||
1341 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1342 | const struct intel_watermark_params *wm_info; | ||
1343 | uint32_t fwater_lo; | ||
1344 | uint32_t fwater_hi; | ||
1345 | int cwm, srwm = 1; | ||
1346 | int fifo_size; | ||
1347 | int planea_wm, planeb_wm; | ||
1348 | struct drm_crtc *crtc, *enabled = NULL; | ||
1349 | |||
1350 | if (IS_I945GM(dev)) | ||
1351 | wm_info = &i945_wm_info; | ||
1352 | else if (!IS_GEN2(dev)) | ||
1353 | wm_info = &i915_wm_info; | ||
1354 | else | ||
1355 | wm_info = &i855_wm_info; | ||
1356 | |||
1357 | fifo_size = dev_priv->display.get_fifo_size(dev, 0); | ||
1358 | crtc = intel_get_crtc_for_plane(dev, 0); | ||
1359 | if (crtc->enabled && crtc->fb) { | ||
1360 | planea_wm = intel_calculate_wm(crtc->mode.clock, | ||
1361 | wm_info, fifo_size, | ||
1362 | crtc->fb->bits_per_pixel / 8, | ||
1363 | latency_ns); | ||
1364 | enabled = crtc; | ||
1365 | } else | ||
1366 | planea_wm = fifo_size - wm_info->guard_size; | ||
1367 | |||
1368 | fifo_size = dev_priv->display.get_fifo_size(dev, 1); | ||
1369 | crtc = intel_get_crtc_for_plane(dev, 1); | ||
1370 | if (crtc->enabled && crtc->fb) { | ||
1371 | planeb_wm = intel_calculate_wm(crtc->mode.clock, | ||
1372 | wm_info, fifo_size, | ||
1373 | crtc->fb->bits_per_pixel / 8, | ||
1374 | latency_ns); | ||
1375 | if (enabled == NULL) | ||
1376 | enabled = crtc; | ||
1377 | else | ||
1378 | enabled = NULL; | ||
1379 | } else | ||
1380 | planeb_wm = fifo_size - wm_info->guard_size; | ||
1381 | |||
1382 | DRM_DEBUG_KMS("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm); | ||
1383 | |||
1384 | /* | ||
1385 | * Overlay gets an aggressive default since video jitter is bad. | ||
1386 | */ | ||
1387 | cwm = 2; | ||
1388 | |||
1389 | /* Play safe and disable self-refresh before adjusting watermarks. */ | ||
1390 | if (IS_I945G(dev) || IS_I945GM(dev)) | ||
1391 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN_MASK | 0); | ||
1392 | else if (IS_I915GM(dev)) | ||
1393 | I915_WRITE(INSTPM, I915_READ(INSTPM) & ~INSTPM_SELF_EN); | ||
1394 | |||
1395 | /* Calc sr entries for one plane configs */ | ||
1396 | if (HAS_FW_BLC(dev) && enabled) { | ||
1397 | /* self-refresh has much higher latency */ | ||
1398 | static const int sr_latency_ns = 6000; | ||
1399 | int clock = enabled->mode.clock; | ||
1400 | int htotal = enabled->mode.htotal; | ||
1401 | int hdisplay = enabled->mode.hdisplay; | ||
1402 | int pixel_size = enabled->fb->bits_per_pixel / 8; | ||
1403 | unsigned long line_time_us; | ||
1404 | int entries; | ||
1405 | |||
1406 | line_time_us = (htotal * 1000) / clock; | ||
1407 | |||
1408 | /* Use ns/us then divide to preserve precision */ | ||
1409 | entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * | ||
1410 | pixel_size * hdisplay; | ||
1411 | entries = DIV_ROUND_UP(entries, wm_info->cacheline_size); | ||
1412 | DRM_DEBUG_KMS("self-refresh entries: %d\n", entries); | ||
1413 | srwm = wm_info->fifo_size - entries; | ||
1414 | if (srwm < 0) | ||
1415 | srwm = 1; | ||
1416 | |||
1417 | if (IS_I945G(dev) || IS_I945GM(dev)) | ||
1418 | I915_WRITE(FW_BLC_SELF, | ||
1419 | FW_BLC_SELF_FIFO_MASK | (srwm & 0xff)); | ||
1420 | else if (IS_I915GM(dev)) | ||
1421 | I915_WRITE(FW_BLC_SELF, srwm & 0x3f); | ||
1422 | } | ||
1423 | |||
1424 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n", | ||
1425 | planea_wm, planeb_wm, cwm, srwm); | ||
1426 | |||
1427 | fwater_lo = ((planeb_wm & 0x3f) << 16) | (planea_wm & 0x3f); | ||
1428 | fwater_hi = (cwm & 0x1f); | ||
1429 | |||
1430 | /* Set request length to 8 cachelines per fetch */ | ||
1431 | fwater_lo = fwater_lo | (1 << 24) | (1 << 8); | ||
1432 | fwater_hi = fwater_hi | (1 << 8); | ||
1433 | |||
1434 | I915_WRITE(FW_BLC, fwater_lo); | ||
1435 | I915_WRITE(FW_BLC2, fwater_hi); | ||
1436 | |||
1437 | if (HAS_FW_BLC(dev)) { | ||
1438 | if (enabled) { | ||
1439 | if (IS_I945G(dev) || IS_I945GM(dev)) | ||
1440 | I915_WRITE(FW_BLC_SELF, | ||
1441 | FW_BLC_SELF_EN_MASK | FW_BLC_SELF_EN); | ||
1442 | else if (IS_I915GM(dev)) | ||
1443 | I915_WRITE(INSTPM, I915_READ(INSTPM) | INSTPM_SELF_EN); | ||
1444 | DRM_DEBUG_KMS("memory self refresh enabled\n"); | ||
1445 | } else | ||
1446 | DRM_DEBUG_KMS("memory self refresh disabled\n"); | ||
1447 | } | ||
1448 | } | ||
1449 | |||
1450 | static void i830_update_wm(struct drm_device *dev) | ||
1451 | { | ||
1452 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1453 | struct drm_crtc *crtc; | ||
1454 | uint32_t fwater_lo; | ||
1455 | int planea_wm; | ||
1456 | |||
1457 | crtc = single_enabled_crtc(dev); | ||
1458 | if (crtc == NULL) | ||
1459 | return; | ||
1460 | |||
1461 | planea_wm = intel_calculate_wm(crtc->mode.clock, &i830_wm_info, | ||
1462 | dev_priv->display.get_fifo_size(dev, 0), | ||
1463 | crtc->fb->bits_per_pixel / 8, | ||
1464 | latency_ns); | ||
1465 | fwater_lo = I915_READ(FW_BLC) & ~0xfff; | ||
1466 | fwater_lo |= (3<<8) | planea_wm; | ||
1467 | |||
1468 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: %d\n", planea_wm); | ||
1469 | |||
1470 | I915_WRITE(FW_BLC, fwater_lo); | ||
1471 | } | ||
1472 | |||
1473 | #define ILK_LP0_PLANE_LATENCY 700 | ||
1474 | #define ILK_LP0_CURSOR_LATENCY 1300 | ||
1475 | |||
1476 | /* | ||
1477 | * Check the wm result. | ||
1478 | * | ||
1479 | * If any calculated watermark values is larger than the maximum value that | ||
1480 | * can be programmed into the associated watermark register, that watermark | ||
1481 | * must be disabled. | ||
1482 | */ | ||
1483 | static bool ironlake_check_srwm(struct drm_device *dev, int level, | ||
1484 | int fbc_wm, int display_wm, int cursor_wm, | ||
1485 | const struct intel_watermark_params *display, | ||
1486 | const struct intel_watermark_params *cursor) | ||
1487 | { | ||
1488 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1489 | |||
1490 | DRM_DEBUG_KMS("watermark %d: display plane %d, fbc lines %d," | ||
1491 | " cursor %d\n", level, display_wm, fbc_wm, cursor_wm); | ||
1492 | |||
1493 | if (fbc_wm > SNB_FBC_MAX_SRWM) { | ||
1494 | DRM_DEBUG_KMS("fbc watermark(%d) is too large(%d), disabling wm%d+\n", | ||
1495 | fbc_wm, SNB_FBC_MAX_SRWM, level); | ||
1496 | |||
1497 | /* fbc has it's own way to disable FBC WM */ | ||
1498 | I915_WRITE(DISP_ARB_CTL, | ||
1499 | I915_READ(DISP_ARB_CTL) | DISP_FBC_WM_DIS); | ||
1500 | return false; | ||
1501 | } | ||
1502 | |||
1503 | if (display_wm > display->max_wm) { | ||
1504 | DRM_DEBUG_KMS("display watermark(%d) is too large(%d), disabling wm%d+\n", | ||
1505 | display_wm, SNB_DISPLAY_MAX_SRWM, level); | ||
1506 | return false; | ||
1507 | } | ||
1508 | |||
1509 | if (cursor_wm > cursor->max_wm) { | ||
1510 | DRM_DEBUG_KMS("cursor watermark(%d) is too large(%d), disabling wm%d+\n", | ||
1511 | cursor_wm, SNB_CURSOR_MAX_SRWM, level); | ||
1512 | return false; | ||
1513 | } | ||
1514 | |||
1515 | if (!(fbc_wm || display_wm || cursor_wm)) { | ||
1516 | DRM_DEBUG_KMS("latency %d is 0, disabling wm%d+\n", level, level); | ||
1517 | return false; | ||
1518 | } | ||
1519 | |||
1520 | return true; | ||
1521 | } | ||
1522 | |||
1523 | /* | ||
1524 | * Compute watermark values of WM[1-3], | ||
1525 | */ | ||
1526 | static bool ironlake_compute_srwm(struct drm_device *dev, int level, int plane, | ||
1527 | int latency_ns, | ||
1528 | const struct intel_watermark_params *display, | ||
1529 | const struct intel_watermark_params *cursor, | ||
1530 | int *fbc_wm, int *display_wm, int *cursor_wm) | ||
1531 | { | ||
1532 | struct drm_crtc *crtc; | ||
1533 | unsigned long line_time_us; | ||
1534 | int hdisplay, htotal, pixel_size, clock; | ||
1535 | int line_count, line_size; | ||
1536 | int small, large; | ||
1537 | int entries; | ||
1538 | |||
1539 | if (!latency_ns) { | ||
1540 | *fbc_wm = *display_wm = *cursor_wm = 0; | ||
1541 | return false; | ||
1542 | } | ||
1543 | |||
1544 | crtc = intel_get_crtc_for_plane(dev, plane); | ||
1545 | hdisplay = crtc->mode.hdisplay; | ||
1546 | htotal = crtc->mode.htotal; | ||
1547 | clock = crtc->mode.clock; | ||
1548 | pixel_size = crtc->fb->bits_per_pixel / 8; | ||
1549 | |||
1550 | line_time_us = (htotal * 1000) / clock; | ||
1551 | line_count = (latency_ns / line_time_us + 1000) / 1000; | ||
1552 | line_size = hdisplay * pixel_size; | ||
1553 | |||
1554 | /* Use the minimum of the small and large buffer method for primary */ | ||
1555 | small = ((clock * pixel_size / 1000) * latency_ns) / 1000; | ||
1556 | large = line_count * line_size; | ||
1557 | |||
1558 | entries = DIV_ROUND_UP(min(small, large), display->cacheline_size); | ||
1559 | *display_wm = entries + display->guard_size; | ||
1560 | |||
1561 | /* | ||
1562 | * Spec says: | ||
1563 | * FBC WM = ((Final Primary WM * 64) / number of bytes per line) + 2 | ||
1564 | */ | ||
1565 | *fbc_wm = DIV_ROUND_UP(*display_wm * 64, line_size) + 2; | ||
1566 | |||
1567 | /* calculate the self-refresh watermark for display cursor */ | ||
1568 | entries = line_count * pixel_size * 64; | ||
1569 | entries = DIV_ROUND_UP(entries, cursor->cacheline_size); | ||
1570 | *cursor_wm = entries + cursor->guard_size; | ||
1571 | |||
1572 | return ironlake_check_srwm(dev, level, | ||
1573 | *fbc_wm, *display_wm, *cursor_wm, | ||
1574 | display, cursor); | ||
1575 | } | ||
1576 | |||
1577 | static void ironlake_update_wm(struct drm_device *dev) | ||
1578 | { | ||
1579 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1580 | int fbc_wm, plane_wm, cursor_wm; | ||
1581 | unsigned int enabled; | ||
1582 | |||
1583 | enabled = 0; | ||
1584 | if (g4x_compute_wm0(dev, 0, | ||
1585 | &ironlake_display_wm_info, | ||
1586 | ILK_LP0_PLANE_LATENCY, | ||
1587 | &ironlake_cursor_wm_info, | ||
1588 | ILK_LP0_CURSOR_LATENCY, | ||
1589 | &plane_wm, &cursor_wm)) { | ||
1590 | I915_WRITE(WM0_PIPEA_ILK, | ||
1591 | (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); | ||
1592 | DRM_DEBUG_KMS("FIFO watermarks For pipe A -" | ||
1593 | " plane %d, " "cursor: %d\n", | ||
1594 | plane_wm, cursor_wm); | ||
1595 | enabled |= 1; | ||
1596 | } | ||
1597 | |||
1598 | if (g4x_compute_wm0(dev, 1, | ||
1599 | &ironlake_display_wm_info, | ||
1600 | ILK_LP0_PLANE_LATENCY, | ||
1601 | &ironlake_cursor_wm_info, | ||
1602 | ILK_LP0_CURSOR_LATENCY, | ||
1603 | &plane_wm, &cursor_wm)) { | ||
1604 | I915_WRITE(WM0_PIPEB_ILK, | ||
1605 | (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); | ||
1606 | DRM_DEBUG_KMS("FIFO watermarks For pipe B -" | ||
1607 | " plane %d, cursor: %d\n", | ||
1608 | plane_wm, cursor_wm); | ||
1609 | enabled |= 2; | ||
1610 | } | ||
1611 | |||
1612 | /* | ||
1613 | * Calculate and update the self-refresh watermark only when one | ||
1614 | * display plane is used. | ||
1615 | */ | ||
1616 | I915_WRITE(WM3_LP_ILK, 0); | ||
1617 | I915_WRITE(WM2_LP_ILK, 0); | ||
1618 | I915_WRITE(WM1_LP_ILK, 0); | ||
1619 | |||
1620 | if (!single_plane_enabled(enabled)) | ||
1621 | return; | ||
1622 | enabled = ffs(enabled) - 1; | ||
1623 | |||
1624 | /* WM1 */ | ||
1625 | if (!ironlake_compute_srwm(dev, 1, enabled, | ||
1626 | ILK_READ_WM1_LATENCY() * 500, | ||
1627 | &ironlake_display_srwm_info, | ||
1628 | &ironlake_cursor_srwm_info, | ||
1629 | &fbc_wm, &plane_wm, &cursor_wm)) | ||
1630 | return; | ||
1631 | |||
1632 | I915_WRITE(WM1_LP_ILK, | ||
1633 | WM1_LP_SR_EN | | ||
1634 | (ILK_READ_WM1_LATENCY() << WM1_LP_LATENCY_SHIFT) | | ||
1635 | (fbc_wm << WM1_LP_FBC_SHIFT) | | ||
1636 | (plane_wm << WM1_LP_SR_SHIFT) | | ||
1637 | cursor_wm); | ||
1638 | |||
1639 | /* WM2 */ | ||
1640 | if (!ironlake_compute_srwm(dev, 2, enabled, | ||
1641 | ILK_READ_WM2_LATENCY() * 500, | ||
1642 | &ironlake_display_srwm_info, | ||
1643 | &ironlake_cursor_srwm_info, | ||
1644 | &fbc_wm, &plane_wm, &cursor_wm)) | ||
1645 | return; | ||
1646 | |||
1647 | I915_WRITE(WM2_LP_ILK, | ||
1648 | WM2_LP_EN | | ||
1649 | (ILK_READ_WM2_LATENCY() << WM1_LP_LATENCY_SHIFT) | | ||
1650 | (fbc_wm << WM1_LP_FBC_SHIFT) | | ||
1651 | (plane_wm << WM1_LP_SR_SHIFT) | | ||
1652 | cursor_wm); | ||
1653 | |||
1654 | /* | ||
1655 | * WM3 is unsupported on ILK, probably because we don't have latency | ||
1656 | * data for that power state | ||
1657 | */ | ||
1658 | } | ||
1659 | |||
1660 | static void sandybridge_update_wm(struct drm_device *dev) | ||
1661 | { | ||
1662 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1663 | int latency = SNB_READ_WM0_LATENCY() * 100; /* In unit 0.1us */ | ||
1664 | u32 val; | ||
1665 | int fbc_wm, plane_wm, cursor_wm; | ||
1666 | unsigned int enabled; | ||
1667 | |||
1668 | enabled = 0; | ||
1669 | if (g4x_compute_wm0(dev, 0, | ||
1670 | &sandybridge_display_wm_info, latency, | ||
1671 | &sandybridge_cursor_wm_info, latency, | ||
1672 | &plane_wm, &cursor_wm)) { | ||
1673 | val = I915_READ(WM0_PIPEA_ILK); | ||
1674 | val &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK); | ||
1675 | I915_WRITE(WM0_PIPEA_ILK, val | | ||
1676 | ((plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm)); | ||
1677 | DRM_DEBUG_KMS("FIFO watermarks For pipe A -" | ||
1678 | " plane %d, " "cursor: %d\n", | ||
1679 | plane_wm, cursor_wm); | ||
1680 | enabled |= 1; | ||
1681 | } | ||
1682 | |||
1683 | if (g4x_compute_wm0(dev, 1, | ||
1684 | &sandybridge_display_wm_info, latency, | ||
1685 | &sandybridge_cursor_wm_info, latency, | ||
1686 | &plane_wm, &cursor_wm)) { | ||
1687 | val = I915_READ(WM0_PIPEB_ILK); | ||
1688 | val &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK); | ||
1689 | I915_WRITE(WM0_PIPEB_ILK, val | | ||
1690 | ((plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm)); | ||
1691 | DRM_DEBUG_KMS("FIFO watermarks For pipe B -" | ||
1692 | " plane %d, cursor: %d\n", | ||
1693 | plane_wm, cursor_wm); | ||
1694 | enabled |= 2; | ||
1695 | } | ||
1696 | |||
1697 | /* IVB has 3 pipes */ | ||
1698 | if (IS_IVYBRIDGE(dev) && | ||
1699 | g4x_compute_wm0(dev, 2, | ||
1700 | &sandybridge_display_wm_info, latency, | ||
1701 | &sandybridge_cursor_wm_info, latency, | ||
1702 | &plane_wm, &cursor_wm)) { | ||
1703 | val = I915_READ(WM0_PIPEC_IVB); | ||
1704 | val &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK); | ||
1705 | I915_WRITE(WM0_PIPEC_IVB, val | | ||
1706 | ((plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm)); | ||
1707 | DRM_DEBUG_KMS("FIFO watermarks For pipe C -" | ||
1708 | " plane %d, cursor: %d\n", | ||
1709 | plane_wm, cursor_wm); | ||
1710 | enabled |= 3; | ||
1711 | } | ||
1712 | |||
1713 | /* | ||
1714 | * Calculate and update the self-refresh watermark only when one | ||
1715 | * display plane is used. | ||
1716 | * | ||
1717 | * SNB support 3 levels of watermark. | ||
1718 | * | ||
1719 | * WM1/WM2/WM2 watermarks have to be enabled in the ascending order, | ||
1720 | * and disabled in the descending order | ||
1721 | * | ||
1722 | */ | ||
1723 | I915_WRITE(WM3_LP_ILK, 0); | ||
1724 | I915_WRITE(WM2_LP_ILK, 0); | ||
1725 | I915_WRITE(WM1_LP_ILK, 0); | ||
1726 | |||
1727 | if (!single_plane_enabled(enabled) || | ||
1728 | dev_priv->sprite_scaling_enabled) | ||
1729 | return; | ||
1730 | enabled = ffs(enabled) - 1; | ||
1731 | |||
1732 | /* WM1 */ | ||
1733 | if (!ironlake_compute_srwm(dev, 1, enabled, | ||
1734 | SNB_READ_WM1_LATENCY() * 500, | ||
1735 | &sandybridge_display_srwm_info, | ||
1736 | &sandybridge_cursor_srwm_info, | ||
1737 | &fbc_wm, &plane_wm, &cursor_wm)) | ||
1738 | return; | ||
1739 | |||
1740 | I915_WRITE(WM1_LP_ILK, | ||
1741 | WM1_LP_SR_EN | | ||
1742 | (SNB_READ_WM1_LATENCY() << WM1_LP_LATENCY_SHIFT) | | ||
1743 | (fbc_wm << WM1_LP_FBC_SHIFT) | | ||
1744 | (plane_wm << WM1_LP_SR_SHIFT) | | ||
1745 | cursor_wm); | ||
1746 | |||
1747 | /* WM2 */ | ||
1748 | if (!ironlake_compute_srwm(dev, 2, enabled, | ||
1749 | SNB_READ_WM2_LATENCY() * 500, | ||
1750 | &sandybridge_display_srwm_info, | ||
1751 | &sandybridge_cursor_srwm_info, | ||
1752 | &fbc_wm, &plane_wm, &cursor_wm)) | ||
1753 | return; | ||
1754 | |||
1755 | I915_WRITE(WM2_LP_ILK, | ||
1756 | WM2_LP_EN | | ||
1757 | (SNB_READ_WM2_LATENCY() << WM1_LP_LATENCY_SHIFT) | | ||
1758 | (fbc_wm << WM1_LP_FBC_SHIFT) | | ||
1759 | (plane_wm << WM1_LP_SR_SHIFT) | | ||
1760 | cursor_wm); | ||
1761 | |||
1762 | /* WM3 */ | ||
1763 | if (!ironlake_compute_srwm(dev, 3, enabled, | ||
1764 | SNB_READ_WM3_LATENCY() * 500, | ||
1765 | &sandybridge_display_srwm_info, | ||
1766 | &sandybridge_cursor_srwm_info, | ||
1767 | &fbc_wm, &plane_wm, &cursor_wm)) | ||
1768 | return; | ||
1769 | |||
1770 | I915_WRITE(WM3_LP_ILK, | ||
1771 | WM3_LP_EN | | ||
1772 | (SNB_READ_WM3_LATENCY() << WM1_LP_LATENCY_SHIFT) | | ||
1773 | (fbc_wm << WM1_LP_FBC_SHIFT) | | ||
1774 | (plane_wm << WM1_LP_SR_SHIFT) | | ||
1775 | cursor_wm); | ||
1776 | } | ||
1777 | |||
1778 | static bool | ||
1779 | sandybridge_compute_sprite_wm(struct drm_device *dev, int plane, | ||
1780 | uint32_t sprite_width, int pixel_size, | ||
1781 | const struct intel_watermark_params *display, | ||
1782 | int display_latency_ns, int *sprite_wm) | ||
1783 | { | ||
1784 | struct drm_crtc *crtc; | ||
1785 | int clock; | ||
1786 | int entries, tlb_miss; | ||
1787 | |||
1788 | crtc = intel_get_crtc_for_plane(dev, plane); | ||
1789 | if (crtc->fb == NULL || !crtc->enabled) { | ||
1790 | *sprite_wm = display->guard_size; | ||
1791 | return false; | ||
1792 | } | ||
1793 | |||
1794 | clock = crtc->mode.clock; | ||
1795 | |||
1796 | /* Use the small buffer method to calculate the sprite watermark */ | ||
1797 | entries = ((clock * pixel_size / 1000) * display_latency_ns) / 1000; | ||
1798 | tlb_miss = display->fifo_size*display->cacheline_size - | ||
1799 | sprite_width * 8; | ||
1800 | if (tlb_miss > 0) | ||
1801 | entries += tlb_miss; | ||
1802 | entries = DIV_ROUND_UP(entries, display->cacheline_size); | ||
1803 | *sprite_wm = entries + display->guard_size; | ||
1804 | if (*sprite_wm > (int)display->max_wm) | ||
1805 | *sprite_wm = display->max_wm; | ||
1806 | |||
1807 | return true; | ||
1808 | } | ||
1809 | |||
1810 | static bool | ||
1811 | sandybridge_compute_sprite_srwm(struct drm_device *dev, int plane, | ||
1812 | uint32_t sprite_width, int pixel_size, | ||
1813 | const struct intel_watermark_params *display, | ||
1814 | int latency_ns, int *sprite_wm) | ||
1815 | { | ||
1816 | struct drm_crtc *crtc; | ||
1817 | unsigned long line_time_us; | ||
1818 | int clock; | ||
1819 | int line_count, line_size; | ||
1820 | int small, large; | ||
1821 | int entries; | ||
1822 | |||
1823 | if (!latency_ns) { | ||
1824 | *sprite_wm = 0; | ||
1825 | return false; | ||
1826 | } | ||
1827 | |||
1828 | crtc = intel_get_crtc_for_plane(dev, plane); | ||
1829 | clock = crtc->mode.clock; | ||
1830 | if (!clock) { | ||
1831 | *sprite_wm = 0; | ||
1832 | return false; | ||
1833 | } | ||
1834 | |||
1835 | line_time_us = (sprite_width * 1000) / clock; | ||
1836 | if (!line_time_us) { | ||
1837 | *sprite_wm = 0; | ||
1838 | return false; | ||
1839 | } | ||
1840 | |||
1841 | line_count = (latency_ns / line_time_us + 1000) / 1000; | ||
1842 | line_size = sprite_width * pixel_size; | ||
1843 | |||
1844 | /* Use the minimum of the small and large buffer method for primary */ | ||
1845 | small = ((clock * pixel_size / 1000) * latency_ns) / 1000; | ||
1846 | large = line_count * line_size; | ||
1847 | |||
1848 | entries = DIV_ROUND_UP(min(small, large), display->cacheline_size); | ||
1849 | *sprite_wm = entries + display->guard_size; | ||
1850 | |||
1851 | return *sprite_wm > 0x3ff ? false : true; | ||
1852 | } | ||
1853 | |||
1854 | static void sandybridge_update_sprite_wm(struct drm_device *dev, int pipe, | ||
1855 | uint32_t sprite_width, int pixel_size) | ||
1856 | { | ||
1857 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1858 | int latency = SNB_READ_WM0_LATENCY() * 100; /* In unit 0.1us */ | ||
1859 | u32 val; | ||
1860 | int sprite_wm, reg; | ||
1861 | int ret; | ||
1862 | |||
1863 | switch (pipe) { | ||
1864 | case 0: | ||
1865 | reg = WM0_PIPEA_ILK; | ||
1866 | break; | ||
1867 | case 1: | ||
1868 | reg = WM0_PIPEB_ILK; | ||
1869 | break; | ||
1870 | case 2: | ||
1871 | reg = WM0_PIPEC_IVB; | ||
1872 | break; | ||
1873 | default: | ||
1874 | return; /* bad pipe */ | ||
1875 | } | ||
1876 | |||
1877 | ret = sandybridge_compute_sprite_wm(dev, pipe, sprite_width, pixel_size, | ||
1878 | &sandybridge_display_wm_info, | ||
1879 | latency, &sprite_wm); | ||
1880 | if (!ret) { | ||
1881 | DRM_DEBUG_KMS("failed to compute sprite wm for pipe %d\n", | ||
1882 | pipe); | ||
1883 | return; | ||
1884 | } | ||
1885 | |||
1886 | val = I915_READ(reg); | ||
1887 | val &= ~WM0_PIPE_SPRITE_MASK; | ||
1888 | I915_WRITE(reg, val | (sprite_wm << WM0_PIPE_SPRITE_SHIFT)); | ||
1889 | DRM_DEBUG_KMS("sprite watermarks For pipe %d - %d\n", pipe, sprite_wm); | ||
1890 | |||
1891 | |||
1892 | ret = sandybridge_compute_sprite_srwm(dev, pipe, sprite_width, | ||
1893 | pixel_size, | ||
1894 | &sandybridge_display_srwm_info, | ||
1895 | SNB_READ_WM1_LATENCY() * 500, | ||
1896 | &sprite_wm); | ||
1897 | if (!ret) { | ||
1898 | DRM_DEBUG_KMS("failed to compute sprite lp1 wm on pipe %d\n", | ||
1899 | pipe); | ||
1900 | return; | ||
1901 | } | ||
1902 | I915_WRITE(WM1S_LP_ILK, sprite_wm); | ||
1903 | |||
1904 | /* Only IVB has two more LP watermarks for sprite */ | ||
1905 | if (!IS_IVYBRIDGE(dev)) | ||
1906 | return; | ||
1907 | |||
1908 | ret = sandybridge_compute_sprite_srwm(dev, pipe, sprite_width, | ||
1909 | pixel_size, | ||
1910 | &sandybridge_display_srwm_info, | ||
1911 | SNB_READ_WM2_LATENCY() * 500, | ||
1912 | &sprite_wm); | ||
1913 | if (!ret) { | ||
1914 | DRM_DEBUG_KMS("failed to compute sprite lp2 wm on pipe %d\n", | ||
1915 | pipe); | ||
1916 | return; | ||
1917 | } | ||
1918 | I915_WRITE(WM2S_LP_IVB, sprite_wm); | ||
1919 | |||
1920 | ret = sandybridge_compute_sprite_srwm(dev, pipe, sprite_width, | ||
1921 | pixel_size, | ||
1922 | &sandybridge_display_srwm_info, | ||
1923 | SNB_READ_WM3_LATENCY() * 500, | ||
1924 | &sprite_wm); | ||
1925 | if (!ret) { | ||
1926 | DRM_DEBUG_KMS("failed to compute sprite lp3 wm on pipe %d\n", | ||
1927 | pipe); | ||
1928 | return; | ||
1929 | } | ||
1930 | I915_WRITE(WM3S_LP_IVB, sprite_wm); | ||
1931 | } | ||
1932 | |||
1933 | /** | ||
1934 | * intel_update_watermarks - update FIFO watermark values based on current modes | ||
1935 | * | ||
1936 | * Calculate watermark values for the various WM regs based on current mode | ||
1937 | * and plane configuration. | ||
1938 | * | ||
1939 | * There are several cases to deal with here: | ||
1940 | * - normal (i.e. non-self-refresh) | ||
1941 | * - self-refresh (SR) mode | ||
1942 | * - lines are large relative to FIFO size (buffer can hold up to 2) | ||
1943 | * - lines are small relative to FIFO size (buffer can hold more than 2 | ||
1944 | * lines), so need to account for TLB latency | ||
1945 | * | ||
1946 | * The normal calculation is: | ||
1947 | * watermark = dotclock * bytes per pixel * latency | ||
1948 | * where latency is platform & configuration dependent (we assume pessimal | ||
1949 | * values here). | ||
1950 | * | ||
1951 | * The SR calculation is: | ||
1952 | * watermark = (trunc(latency/line time)+1) * surface width * | ||
1953 | * bytes per pixel | ||
1954 | * where | ||
1955 | * line time = htotal / dotclock | ||
1956 | * surface width = hdisplay for normal plane and 64 for cursor | ||
1957 | * and latency is assumed to be high, as above. | ||
1958 | * | ||
1959 | * The final value programmed to the register should always be rounded up, | ||
1960 | * and include an extra 2 entries to account for clock crossings. | ||
1961 | * | ||
1962 | * We don't use the sprite, so we can ignore that. And on Crestline we have | ||
1963 | * to set the non-SR watermarks to 8. | ||
1964 | */ | ||
1965 | void intel_update_watermarks(struct drm_device *dev) | ||
1966 | { | ||
1967 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1968 | |||
1969 | if (dev_priv->display.update_wm) | ||
1970 | dev_priv->display.update_wm(dev); | ||
1971 | } | ||
1972 | |||
1973 | void intel_update_sprite_watermarks(struct drm_device *dev, int pipe, | ||
1974 | uint32_t sprite_width, int pixel_size) | ||
1975 | { | ||
1976 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1977 | |||
1978 | if (dev_priv->display.update_sprite_wm) | ||
1979 | dev_priv->display.update_sprite_wm(dev, pipe, sprite_width, | ||
1980 | pixel_size); | ||
1981 | } | ||
1982 | |||
1983 | static struct drm_i915_gem_object * | ||
1984 | intel_alloc_context_page(struct drm_device *dev) | ||
1985 | { | ||
1986 | struct drm_i915_gem_object *ctx; | ||
1987 | int ret; | ||
1988 | |||
1989 | WARN_ON(!mutex_is_locked(&dev->struct_mutex)); | ||
1990 | |||
1991 | ctx = i915_gem_alloc_object(dev, 4096); | ||
1992 | if (!ctx) { | ||
1993 | DRM_DEBUG("failed to alloc power context, RC6 disabled\n"); | ||
1994 | return NULL; | ||
1995 | } | ||
1996 | |||
1997 | ret = i915_gem_object_pin(ctx, 4096, true); | ||
1998 | if (ret) { | ||
1999 | DRM_ERROR("failed to pin power context: %d\n", ret); | ||
2000 | goto err_unref; | ||
2001 | } | ||
2002 | |||
2003 | ret = i915_gem_object_set_to_gtt_domain(ctx, 1); | ||
2004 | if (ret) { | ||
2005 | DRM_ERROR("failed to set-domain on power context: %d\n", ret); | ||
2006 | goto err_unpin; | ||
2007 | } | ||
2008 | |||
2009 | return ctx; | ||
2010 | |||
2011 | err_unpin: | ||
2012 | i915_gem_object_unpin(ctx); | ||
2013 | err_unref: | ||
2014 | drm_gem_object_unreference(&ctx->base); | ||
2015 | mutex_unlock(&dev->struct_mutex); | ||
2016 | return NULL; | ||
2017 | } | ||
2018 | |||
2019 | bool ironlake_set_drps(struct drm_device *dev, u8 val) | ||
2020 | { | ||
2021 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2022 | u16 rgvswctl; | ||
2023 | |||
2024 | rgvswctl = I915_READ16(MEMSWCTL); | ||
2025 | if (rgvswctl & MEMCTL_CMD_STS) { | ||
2026 | DRM_DEBUG("gpu busy, RCS change rejected\n"); | ||
2027 | return false; /* still busy with another command */ | ||
2028 | } | ||
2029 | |||
2030 | rgvswctl = (MEMCTL_CMD_CHFREQ << MEMCTL_CMD_SHIFT) | | ||
2031 | (val << MEMCTL_FREQ_SHIFT) | MEMCTL_SFCAVM; | ||
2032 | I915_WRITE16(MEMSWCTL, rgvswctl); | ||
2033 | POSTING_READ16(MEMSWCTL); | ||
2034 | |||
2035 | rgvswctl |= MEMCTL_CMD_STS; | ||
2036 | I915_WRITE16(MEMSWCTL, rgvswctl); | ||
2037 | |||
2038 | return true; | ||
2039 | } | ||
2040 | |||
2041 | void ironlake_enable_drps(struct drm_device *dev) | ||
2042 | { | ||
2043 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2044 | u32 rgvmodectl = I915_READ(MEMMODECTL); | ||
2045 | u8 fmax, fmin, fstart, vstart; | ||
2046 | |||
2047 | /* Enable temp reporting */ | ||
2048 | I915_WRITE16(PMMISC, I915_READ(PMMISC) | MCPPCE_EN); | ||
2049 | I915_WRITE16(TSC1, I915_READ(TSC1) | TSE); | ||
2050 | |||
2051 | /* 100ms RC evaluation intervals */ | ||
2052 | I915_WRITE(RCUPEI, 100000); | ||
2053 | I915_WRITE(RCDNEI, 100000); | ||
2054 | |||
2055 | /* Set max/min thresholds to 90ms and 80ms respectively */ | ||
2056 | I915_WRITE(RCBMAXAVG, 90000); | ||
2057 | I915_WRITE(RCBMINAVG, 80000); | ||
2058 | |||
2059 | I915_WRITE(MEMIHYST, 1); | ||
2060 | |||
2061 | /* Set up min, max, and cur for interrupt handling */ | ||
2062 | fmax = (rgvmodectl & MEMMODE_FMAX_MASK) >> MEMMODE_FMAX_SHIFT; | ||
2063 | fmin = (rgvmodectl & MEMMODE_FMIN_MASK); | ||
2064 | fstart = (rgvmodectl & MEMMODE_FSTART_MASK) >> | ||
2065 | MEMMODE_FSTART_SHIFT; | ||
2066 | |||
2067 | vstart = (I915_READ(PXVFREQ_BASE + (fstart * 4)) & PXVFREQ_PX_MASK) >> | ||
2068 | PXVFREQ_PX_SHIFT; | ||
2069 | |||
2070 | dev_priv->fmax = fmax; /* IPS callback will increase this */ | ||
2071 | dev_priv->fstart = fstart; | ||
2072 | |||
2073 | dev_priv->max_delay = fstart; | ||
2074 | dev_priv->min_delay = fmin; | ||
2075 | dev_priv->cur_delay = fstart; | ||
2076 | |||
2077 | DRM_DEBUG_DRIVER("fmax: %d, fmin: %d, fstart: %d\n", | ||
2078 | fmax, fmin, fstart); | ||
2079 | |||
2080 | I915_WRITE(MEMINTREN, MEMINT_CX_SUPR_EN | MEMINT_EVAL_CHG_EN); | ||
2081 | |||
2082 | /* | ||
2083 | * Interrupts will be enabled in ironlake_irq_postinstall | ||
2084 | */ | ||
2085 | |||
2086 | I915_WRITE(VIDSTART, vstart); | ||
2087 | POSTING_READ(VIDSTART); | ||
2088 | |||
2089 | rgvmodectl |= MEMMODE_SWMODE_EN; | ||
2090 | I915_WRITE(MEMMODECTL, rgvmodectl); | ||
2091 | |||
2092 | if (wait_for((I915_READ(MEMSWCTL) & MEMCTL_CMD_STS) == 0, 10)) | ||
2093 | DRM_ERROR("stuck trying to change perf mode\n"); | ||
2094 | msleep(1); | ||
2095 | |||
2096 | ironlake_set_drps(dev, fstart); | ||
2097 | |||
2098 | dev_priv->last_count1 = I915_READ(0x112e4) + I915_READ(0x112e8) + | ||
2099 | I915_READ(0x112e0); | ||
2100 | dev_priv->last_time1 = jiffies_to_msecs(jiffies); | ||
2101 | dev_priv->last_count2 = I915_READ(0x112f4); | ||
2102 | getrawmonotonic(&dev_priv->last_time2); | ||
2103 | } | ||
2104 | |||
2105 | void ironlake_disable_drps(struct drm_device *dev) | ||
2106 | { | ||
2107 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2108 | u16 rgvswctl = I915_READ16(MEMSWCTL); | ||
2109 | |||
2110 | /* Ack interrupts, disable EFC interrupt */ | ||
2111 | I915_WRITE(MEMINTREN, I915_READ(MEMINTREN) & ~MEMINT_EVAL_CHG_EN); | ||
2112 | I915_WRITE(MEMINTRSTS, MEMINT_EVAL_CHG); | ||
2113 | I915_WRITE(DEIER, I915_READ(DEIER) & ~DE_PCU_EVENT); | ||
2114 | I915_WRITE(DEIIR, DE_PCU_EVENT); | ||
2115 | I915_WRITE(DEIMR, I915_READ(DEIMR) | DE_PCU_EVENT); | ||
2116 | |||
2117 | /* Go back to the starting frequency */ | ||
2118 | ironlake_set_drps(dev, dev_priv->fstart); | ||
2119 | msleep(1); | ||
2120 | rgvswctl |= MEMCTL_CMD_STS; | ||
2121 | I915_WRITE(MEMSWCTL, rgvswctl); | ||
2122 | msleep(1); | ||
2123 | |||
2124 | } | ||
2125 | |||
2126 | void gen6_set_rps(struct drm_device *dev, u8 val) | ||
2127 | { | ||
2128 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2129 | u32 swreq; | ||
2130 | |||
2131 | swreq = (val & 0x3ff) << 25; | ||
2132 | I915_WRITE(GEN6_RPNSWREQ, swreq); | ||
2133 | } | ||
2134 | |||
2135 | void gen6_disable_rps(struct drm_device *dev) | ||
2136 | { | ||
2137 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2138 | |||
2139 | I915_WRITE(GEN6_RPNSWREQ, 1 << 31); | ||
2140 | I915_WRITE(GEN6_PMINTRMSK, 0xffffffff); | ||
2141 | I915_WRITE(GEN6_PMIER, 0); | ||
2142 | /* Complete PM interrupt masking here doesn't race with the rps work | ||
2143 | * item again unmasking PM interrupts because that is using a different | ||
2144 | * register (PMIMR) to mask PM interrupts. The only risk is in leaving | ||
2145 | * stale bits in PMIIR and PMIMR which gen6_enable_rps will clean up. */ | ||
2146 | |||
2147 | spin_lock_irq(&dev_priv->rps_lock); | ||
2148 | dev_priv->pm_iir = 0; | ||
2149 | spin_unlock_irq(&dev_priv->rps_lock); | ||
2150 | |||
2151 | I915_WRITE(GEN6_PMIIR, I915_READ(GEN6_PMIIR)); | ||
2152 | } | ||
2153 | |||
2154 | int intel_enable_rc6(const struct drm_device *dev) | ||
2155 | { | ||
2156 | /* | ||
2157 | * Respect the kernel parameter if it is set | ||
2158 | */ | ||
2159 | if (i915_enable_rc6 >= 0) | ||
2160 | return i915_enable_rc6; | ||
2161 | |||
2162 | /* | ||
2163 | * Disable RC6 on Ironlake | ||
2164 | */ | ||
2165 | if (INTEL_INFO(dev)->gen == 5) | ||
2166 | return 0; | ||
2167 | |||
2168 | /* Sorry Haswell, no RC6 for you for now. */ | ||
2169 | if (IS_HASWELL(dev)) | ||
2170 | return 0; | ||
2171 | |||
2172 | /* | ||
2173 | * Disable rc6 on Sandybridge | ||
2174 | */ | ||
2175 | if (INTEL_INFO(dev)->gen == 6) { | ||
2176 | DRM_DEBUG_DRIVER("Sandybridge: deep RC6 disabled\n"); | ||
2177 | return INTEL_RC6_ENABLE; | ||
2178 | } | ||
2179 | DRM_DEBUG_DRIVER("RC6 and deep RC6 enabled\n"); | ||
2180 | return (INTEL_RC6_ENABLE | INTEL_RC6p_ENABLE); | ||
2181 | } | ||
2182 | |||
2183 | void gen6_enable_rps(struct drm_i915_private *dev_priv) | ||
2184 | { | ||
2185 | u32 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); | ||
2186 | u32 gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS); | ||
2187 | u32 pcu_mbox, rc6_mask = 0; | ||
2188 | u32 gtfifodbg; | ||
2189 | int cur_freq, min_freq, max_freq; | ||
2190 | int rc6_mode; | ||
2191 | int i; | ||
2192 | |||
2193 | /* Here begins a magic sequence of register writes to enable | ||
2194 | * auto-downclocking. | ||
2195 | * | ||
2196 | * Perhaps there might be some value in exposing these to | ||
2197 | * userspace... | ||
2198 | */ | ||
2199 | I915_WRITE(GEN6_RC_STATE, 0); | ||
2200 | mutex_lock(&dev_priv->dev->struct_mutex); | ||
2201 | |||
2202 | /* Clear the DBG now so we don't confuse earlier errors */ | ||
2203 | if ((gtfifodbg = I915_READ(GTFIFODBG))) { | ||
2204 | DRM_ERROR("GT fifo had a previous error %x\n", gtfifodbg); | ||
2205 | I915_WRITE(GTFIFODBG, gtfifodbg); | ||
2206 | } | ||
2207 | |||
2208 | gen6_gt_force_wake_get(dev_priv); | ||
2209 | |||
2210 | /* disable the counters and set deterministic thresholds */ | ||
2211 | I915_WRITE(GEN6_RC_CONTROL, 0); | ||
2212 | |||
2213 | I915_WRITE(GEN6_RC1_WAKE_RATE_LIMIT, 1000 << 16); | ||
2214 | I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16 | 30); | ||
2215 | I915_WRITE(GEN6_RC6pp_WAKE_RATE_LIMIT, 30); | ||
2216 | I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); | ||
2217 | I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); | ||
2218 | |||
2219 | for (i = 0; i < I915_NUM_RINGS; i++) | ||
2220 | I915_WRITE(RING_MAX_IDLE(dev_priv->ring[i].mmio_base), 10); | ||
2221 | |||
2222 | I915_WRITE(GEN6_RC_SLEEP, 0); | ||
2223 | I915_WRITE(GEN6_RC1e_THRESHOLD, 1000); | ||
2224 | I915_WRITE(GEN6_RC6_THRESHOLD, 50000); | ||
2225 | I915_WRITE(GEN6_RC6p_THRESHOLD, 100000); | ||
2226 | I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */ | ||
2227 | |||
2228 | rc6_mode = intel_enable_rc6(dev_priv->dev); | ||
2229 | if (rc6_mode & INTEL_RC6_ENABLE) | ||
2230 | rc6_mask |= GEN6_RC_CTL_RC6_ENABLE; | ||
2231 | |||
2232 | if (rc6_mode & INTEL_RC6p_ENABLE) | ||
2233 | rc6_mask |= GEN6_RC_CTL_RC6p_ENABLE; | ||
2234 | |||
2235 | if (rc6_mode & INTEL_RC6pp_ENABLE) | ||
2236 | rc6_mask |= GEN6_RC_CTL_RC6pp_ENABLE; | ||
2237 | |||
2238 | DRM_INFO("Enabling RC6 states: RC6 %s, RC6p %s, RC6pp %s\n", | ||
2239 | (rc6_mode & INTEL_RC6_ENABLE) ? "on" : "off", | ||
2240 | (rc6_mode & INTEL_RC6p_ENABLE) ? "on" : "off", | ||
2241 | (rc6_mode & INTEL_RC6pp_ENABLE) ? "on" : "off"); | ||
2242 | |||
2243 | I915_WRITE(GEN6_RC_CONTROL, | ||
2244 | rc6_mask | | ||
2245 | GEN6_RC_CTL_EI_MODE(1) | | ||
2246 | GEN6_RC_CTL_HW_ENABLE); | ||
2247 | |||
2248 | I915_WRITE(GEN6_RPNSWREQ, | ||
2249 | GEN6_FREQUENCY(10) | | ||
2250 | GEN6_OFFSET(0) | | ||
2251 | GEN6_AGGRESSIVE_TURBO); | ||
2252 | I915_WRITE(GEN6_RC_VIDEO_FREQ, | ||
2253 | GEN6_FREQUENCY(12)); | ||
2254 | |||
2255 | I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 1000000); | ||
2256 | I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, | ||
2257 | 18 << 24 | | ||
2258 | 6 << 16); | ||
2259 | I915_WRITE(GEN6_RP_UP_THRESHOLD, 10000); | ||
2260 | I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 1000000); | ||
2261 | I915_WRITE(GEN6_RP_UP_EI, 100000); | ||
2262 | I915_WRITE(GEN6_RP_DOWN_EI, 5000000); | ||
2263 | I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); | ||
2264 | I915_WRITE(GEN6_RP_CONTROL, | ||
2265 | GEN6_RP_MEDIA_TURBO | | ||
2266 | GEN6_RP_MEDIA_HW_MODE | | ||
2267 | GEN6_RP_MEDIA_IS_GFX | | ||
2268 | GEN6_RP_ENABLE | | ||
2269 | GEN6_RP_UP_BUSY_AVG | | ||
2270 | GEN6_RP_DOWN_IDLE_CONT); | ||
2271 | |||
2272 | if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0, | ||
2273 | 500)) | ||
2274 | DRM_ERROR("timeout waiting for pcode mailbox to become idle\n"); | ||
2275 | |||
2276 | I915_WRITE(GEN6_PCODE_DATA, 0); | ||
2277 | I915_WRITE(GEN6_PCODE_MAILBOX, | ||
2278 | GEN6_PCODE_READY | | ||
2279 | GEN6_PCODE_WRITE_MIN_FREQ_TABLE); | ||
2280 | if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0, | ||
2281 | 500)) | ||
2282 | DRM_ERROR("timeout waiting for pcode mailbox to finish\n"); | ||
2283 | |||
2284 | min_freq = (rp_state_cap & 0xff0000) >> 16; | ||
2285 | max_freq = rp_state_cap & 0xff; | ||
2286 | cur_freq = (gt_perf_status & 0xff00) >> 8; | ||
2287 | |||
2288 | /* Check for overclock support */ | ||
2289 | if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0, | ||
2290 | 500)) | ||
2291 | DRM_ERROR("timeout waiting for pcode mailbox to become idle\n"); | ||
2292 | I915_WRITE(GEN6_PCODE_MAILBOX, GEN6_READ_OC_PARAMS); | ||
2293 | pcu_mbox = I915_READ(GEN6_PCODE_DATA); | ||
2294 | if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0, | ||
2295 | 500)) | ||
2296 | DRM_ERROR("timeout waiting for pcode mailbox to finish\n"); | ||
2297 | if (pcu_mbox & (1<<31)) { /* OC supported */ | ||
2298 | max_freq = pcu_mbox & 0xff; | ||
2299 | DRM_DEBUG_DRIVER("overclocking supported, adjusting frequency max to %dMHz\n", pcu_mbox * 50); | ||
2300 | } | ||
2301 | |||
2302 | /* In units of 100MHz */ | ||
2303 | dev_priv->max_delay = max_freq; | ||
2304 | dev_priv->min_delay = min_freq; | ||
2305 | dev_priv->cur_delay = cur_freq; | ||
2306 | |||
2307 | /* requires MSI enabled */ | ||
2308 | I915_WRITE(GEN6_PMIER, | ||
2309 | GEN6_PM_MBOX_EVENT | | ||
2310 | GEN6_PM_THERMAL_EVENT | | ||
2311 | GEN6_PM_RP_DOWN_TIMEOUT | | ||
2312 | GEN6_PM_RP_UP_THRESHOLD | | ||
2313 | GEN6_PM_RP_DOWN_THRESHOLD | | ||
2314 | GEN6_PM_RP_UP_EI_EXPIRED | | ||
2315 | GEN6_PM_RP_DOWN_EI_EXPIRED); | ||
2316 | spin_lock_irq(&dev_priv->rps_lock); | ||
2317 | WARN_ON(dev_priv->pm_iir != 0); | ||
2318 | I915_WRITE(GEN6_PMIMR, 0); | ||
2319 | spin_unlock_irq(&dev_priv->rps_lock); | ||
2320 | /* enable all PM interrupts */ | ||
2321 | I915_WRITE(GEN6_PMINTRMSK, 0); | ||
2322 | |||
2323 | gen6_gt_force_wake_put(dev_priv); | ||
2324 | mutex_unlock(&dev_priv->dev->struct_mutex); | ||
2325 | } | ||
2326 | |||
2327 | void gen6_update_ring_freq(struct drm_i915_private *dev_priv) | ||
2328 | { | ||
2329 | int min_freq = 15; | ||
2330 | int gpu_freq, ia_freq, max_ia_freq; | ||
2331 | int scaling_factor = 180; | ||
2332 | |||
2333 | max_ia_freq = cpufreq_quick_get_max(0); | ||
2334 | /* | ||
2335 | * Default to measured freq if none found, PCU will ensure we don't go | ||
2336 | * over | ||
2337 | */ | ||
2338 | if (!max_ia_freq) | ||
2339 | max_ia_freq = tsc_khz; | ||
2340 | |||
2341 | /* Convert from kHz to MHz */ | ||
2342 | max_ia_freq /= 1000; | ||
2343 | |||
2344 | mutex_lock(&dev_priv->dev->struct_mutex); | ||
2345 | |||
2346 | /* | ||
2347 | * For each potential GPU frequency, load a ring frequency we'd like | ||
2348 | * to use for memory access. We do this by specifying the IA frequency | ||
2349 | * the PCU should use as a reference to determine the ring frequency. | ||
2350 | */ | ||
2351 | for (gpu_freq = dev_priv->max_delay; gpu_freq >= dev_priv->min_delay; | ||
2352 | gpu_freq--) { | ||
2353 | int diff = dev_priv->max_delay - gpu_freq; | ||
2354 | |||
2355 | /* | ||
2356 | * For GPU frequencies less than 750MHz, just use the lowest | ||
2357 | * ring freq. | ||
2358 | */ | ||
2359 | if (gpu_freq < min_freq) | ||
2360 | ia_freq = 800; | ||
2361 | else | ||
2362 | ia_freq = max_ia_freq - ((diff * scaling_factor) / 2); | ||
2363 | ia_freq = DIV_ROUND_CLOSEST(ia_freq, 100); | ||
2364 | |||
2365 | I915_WRITE(GEN6_PCODE_DATA, | ||
2366 | (ia_freq << GEN6_PCODE_FREQ_IA_RATIO_SHIFT) | | ||
2367 | gpu_freq); | ||
2368 | I915_WRITE(GEN6_PCODE_MAILBOX, GEN6_PCODE_READY | | ||
2369 | GEN6_PCODE_WRITE_MIN_FREQ_TABLE); | ||
2370 | if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & | ||
2371 | GEN6_PCODE_READY) == 0, 10)) { | ||
2372 | DRM_ERROR("pcode write of freq table timed out\n"); | ||
2373 | continue; | ||
2374 | } | ||
2375 | } | ||
2376 | |||
2377 | mutex_unlock(&dev_priv->dev->struct_mutex); | ||
2378 | } | ||
2379 | |||
2380 | static void ironlake_teardown_rc6(struct drm_device *dev) | ||
2381 | { | ||
2382 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2383 | |||
2384 | if (dev_priv->renderctx) { | ||
2385 | i915_gem_object_unpin(dev_priv->renderctx); | ||
2386 | drm_gem_object_unreference(&dev_priv->renderctx->base); | ||
2387 | dev_priv->renderctx = NULL; | ||
2388 | } | ||
2389 | |||
2390 | if (dev_priv->pwrctx) { | ||
2391 | i915_gem_object_unpin(dev_priv->pwrctx); | ||
2392 | drm_gem_object_unreference(&dev_priv->pwrctx->base); | ||
2393 | dev_priv->pwrctx = NULL; | ||
2394 | } | ||
2395 | } | ||
2396 | |||
2397 | void ironlake_disable_rc6(struct drm_device *dev) | ||
2398 | { | ||
2399 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2400 | |||
2401 | if (I915_READ(PWRCTXA)) { | ||
2402 | /* Wake the GPU, prevent RC6, then restore RSTDBYCTL */ | ||
2403 | I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) | RCX_SW_EXIT); | ||
2404 | wait_for(((I915_READ(RSTDBYCTL) & RSX_STATUS_MASK) == RSX_STATUS_ON), | ||
2405 | 50); | ||
2406 | |||
2407 | I915_WRITE(PWRCTXA, 0); | ||
2408 | POSTING_READ(PWRCTXA); | ||
2409 | |||
2410 | I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) & ~RCX_SW_EXIT); | ||
2411 | POSTING_READ(RSTDBYCTL); | ||
2412 | } | ||
2413 | |||
2414 | ironlake_teardown_rc6(dev); | ||
2415 | } | ||
2416 | |||
2417 | static int ironlake_setup_rc6(struct drm_device *dev) | ||
2418 | { | ||
2419 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2420 | |||
2421 | if (dev_priv->renderctx == NULL) | ||
2422 | dev_priv->renderctx = intel_alloc_context_page(dev); | ||
2423 | if (!dev_priv->renderctx) | ||
2424 | return -ENOMEM; | ||
2425 | |||
2426 | if (dev_priv->pwrctx == NULL) | ||
2427 | dev_priv->pwrctx = intel_alloc_context_page(dev); | ||
2428 | if (!dev_priv->pwrctx) { | ||
2429 | ironlake_teardown_rc6(dev); | ||
2430 | return -ENOMEM; | ||
2431 | } | ||
2432 | |||
2433 | return 0; | ||
2434 | } | ||
2435 | |||
2436 | void ironlake_enable_rc6(struct drm_device *dev) | ||
2437 | { | ||
2438 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2439 | int ret; | ||
2440 | |||
2441 | /* rc6 disabled by default due to repeated reports of hanging during | ||
2442 | * boot and resume. | ||
2443 | */ | ||
2444 | if (!intel_enable_rc6(dev)) | ||
2445 | return; | ||
2446 | |||
2447 | mutex_lock(&dev->struct_mutex); | ||
2448 | ret = ironlake_setup_rc6(dev); | ||
2449 | if (ret) { | ||
2450 | mutex_unlock(&dev->struct_mutex); | ||
2451 | return; | ||
2452 | } | ||
2453 | |||
2454 | /* | ||
2455 | * GPU can automatically power down the render unit if given a page | ||
2456 | * to save state. | ||
2457 | */ | ||
2458 | ret = BEGIN_LP_RING(6); | ||
2459 | if (ret) { | ||
2460 | ironlake_teardown_rc6(dev); | ||
2461 | mutex_unlock(&dev->struct_mutex); | ||
2462 | return; | ||
2463 | } | ||
2464 | |||
2465 | OUT_RING(MI_SUSPEND_FLUSH | MI_SUSPEND_FLUSH_EN); | ||
2466 | OUT_RING(MI_SET_CONTEXT); | ||
2467 | OUT_RING(dev_priv->renderctx->gtt_offset | | ||
2468 | MI_MM_SPACE_GTT | | ||
2469 | MI_SAVE_EXT_STATE_EN | | ||
2470 | MI_RESTORE_EXT_STATE_EN | | ||
2471 | MI_RESTORE_INHIBIT); | ||
2472 | OUT_RING(MI_SUSPEND_FLUSH); | ||
2473 | OUT_RING(MI_NOOP); | ||
2474 | OUT_RING(MI_FLUSH); | ||
2475 | ADVANCE_LP_RING(); | ||
2476 | |||
2477 | /* | ||
2478 | * Wait for the command parser to advance past MI_SET_CONTEXT. The HW | ||
2479 | * does an implicit flush, combined with MI_FLUSH above, it should be | ||
2480 | * safe to assume that renderctx is valid | ||
2481 | */ | ||
2482 | ret = intel_wait_ring_idle(LP_RING(dev_priv)); | ||
2483 | if (ret) { | ||
2484 | DRM_ERROR("failed to enable ironlake power power savings\n"); | ||
2485 | ironlake_teardown_rc6(dev); | ||
2486 | mutex_unlock(&dev->struct_mutex); | ||
2487 | return; | ||
2488 | } | ||
2489 | |||
2490 | I915_WRITE(PWRCTXA, dev_priv->pwrctx->gtt_offset | PWRCTX_EN); | ||
2491 | I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) & ~RCX_SW_EXIT); | ||
2492 | mutex_unlock(&dev->struct_mutex); | ||
2493 | } | ||
2494 | |||
2495 | static unsigned long intel_pxfreq(u32 vidfreq) | ||
2496 | { | ||
2497 | unsigned long freq; | ||
2498 | int div = (vidfreq & 0x3f0000) >> 16; | ||
2499 | int post = (vidfreq & 0x3000) >> 12; | ||
2500 | int pre = (vidfreq & 0x7); | ||
2501 | |||
2502 | if (!pre) | ||
2503 | return 0; | ||
2504 | |||
2505 | freq = ((div * 133333) / ((1<<post) * pre)); | ||
2506 | |||
2507 | return freq; | ||
2508 | } | ||
2509 | |||
2510 | void intel_init_emon(struct drm_device *dev) | ||
2511 | { | ||
2512 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2513 | u32 lcfuse; | ||
2514 | u8 pxw[16]; | ||
2515 | int i; | ||
2516 | |||
2517 | /* Disable to program */ | ||
2518 | I915_WRITE(ECR, 0); | ||
2519 | POSTING_READ(ECR); | ||
2520 | |||
2521 | /* Program energy weights for various events */ | ||
2522 | I915_WRITE(SDEW, 0x15040d00); | ||
2523 | I915_WRITE(CSIEW0, 0x007f0000); | ||
2524 | I915_WRITE(CSIEW1, 0x1e220004); | ||
2525 | I915_WRITE(CSIEW2, 0x04000004); | ||
2526 | |||
2527 | for (i = 0; i < 5; i++) | ||
2528 | I915_WRITE(PEW + (i * 4), 0); | ||
2529 | for (i = 0; i < 3; i++) | ||
2530 | I915_WRITE(DEW + (i * 4), 0); | ||
2531 | |||
2532 | /* Program P-state weights to account for frequency power adjustment */ | ||
2533 | for (i = 0; i < 16; i++) { | ||
2534 | u32 pxvidfreq = I915_READ(PXVFREQ_BASE + (i * 4)); | ||
2535 | unsigned long freq = intel_pxfreq(pxvidfreq); | ||
2536 | unsigned long vid = (pxvidfreq & PXVFREQ_PX_MASK) >> | ||
2537 | PXVFREQ_PX_SHIFT; | ||
2538 | unsigned long val; | ||
2539 | |||
2540 | val = vid * vid; | ||
2541 | val *= (freq / 1000); | ||
2542 | val *= 255; | ||
2543 | val /= (127*127*900); | ||
2544 | if (val > 0xff) | ||
2545 | DRM_ERROR("bad pxval: %ld\n", val); | ||
2546 | pxw[i] = val; | ||
2547 | } | ||
2548 | /* Render standby states get 0 weight */ | ||
2549 | pxw[14] = 0; | ||
2550 | pxw[15] = 0; | ||
2551 | |||
2552 | for (i = 0; i < 4; i++) { | ||
2553 | u32 val = (pxw[i*4] << 24) | (pxw[(i*4)+1] << 16) | | ||
2554 | (pxw[(i*4)+2] << 8) | (pxw[(i*4)+3]); | ||
2555 | I915_WRITE(PXW + (i * 4), val); | ||
2556 | } | ||
2557 | |||
2558 | /* Adjust magic regs to magic values (more experimental results) */ | ||
2559 | I915_WRITE(OGW0, 0); | ||
2560 | I915_WRITE(OGW1, 0); | ||
2561 | I915_WRITE(EG0, 0x00007f00); | ||
2562 | I915_WRITE(EG1, 0x0000000e); | ||
2563 | I915_WRITE(EG2, 0x000e0000); | ||
2564 | I915_WRITE(EG3, 0x68000300); | ||
2565 | I915_WRITE(EG4, 0x42000000); | ||
2566 | I915_WRITE(EG5, 0x00140031); | ||
2567 | I915_WRITE(EG6, 0); | ||
2568 | I915_WRITE(EG7, 0); | ||
2569 | |||
2570 | for (i = 0; i < 8; i++) | ||
2571 | I915_WRITE(PXWL + (i * 4), 0); | ||
2572 | |||
2573 | /* Enable PMON + select events */ | ||
2574 | I915_WRITE(ECR, 0x80000019); | ||
2575 | |||
2576 | lcfuse = I915_READ(LCFUSE02); | ||
2577 | |||
2578 | dev_priv->corr = (lcfuse & LCFUSE_HIV_MASK); | ||
2579 | } | ||
2580 | |||
2581 | static void ironlake_init_clock_gating(struct drm_device *dev) | ||
2582 | { | ||
2583 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2584 | uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE; | ||
2585 | |||
2586 | /* Required for FBC */ | ||
2587 | dspclk_gate |= DPFCUNIT_CLOCK_GATE_DISABLE | | ||
2588 | DPFCRUNIT_CLOCK_GATE_DISABLE | | ||
2589 | DPFDUNIT_CLOCK_GATE_DISABLE; | ||
2590 | /* Required for CxSR */ | ||
2591 | dspclk_gate |= DPARBUNIT_CLOCK_GATE_DISABLE; | ||
2592 | |||
2593 | I915_WRITE(PCH_3DCGDIS0, | ||
2594 | MARIUNIT_CLOCK_GATE_DISABLE | | ||
2595 | SVSMUNIT_CLOCK_GATE_DISABLE); | ||
2596 | I915_WRITE(PCH_3DCGDIS1, | ||
2597 | VFMUNIT_CLOCK_GATE_DISABLE); | ||
2598 | |||
2599 | I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate); | ||
2600 | |||
2601 | /* | ||
2602 | * According to the spec the following bits should be set in | ||
2603 | * order to enable memory self-refresh | ||
2604 | * The bit 22/21 of 0x42004 | ||
2605 | * The bit 5 of 0x42020 | ||
2606 | * The bit 15 of 0x45000 | ||
2607 | */ | ||
2608 | I915_WRITE(ILK_DISPLAY_CHICKEN2, | ||
2609 | (I915_READ(ILK_DISPLAY_CHICKEN2) | | ||
2610 | ILK_DPARB_GATE | ILK_VSDPFD_FULL)); | ||
2611 | I915_WRITE(ILK_DSPCLK_GATE, | ||
2612 | (I915_READ(ILK_DSPCLK_GATE) | | ||
2613 | ILK_DPARB_CLK_GATE)); | ||
2614 | I915_WRITE(DISP_ARB_CTL, | ||
2615 | (I915_READ(DISP_ARB_CTL) | | ||
2616 | DISP_FBC_WM_DIS)); | ||
2617 | I915_WRITE(WM3_LP_ILK, 0); | ||
2618 | I915_WRITE(WM2_LP_ILK, 0); | ||
2619 | I915_WRITE(WM1_LP_ILK, 0); | ||
2620 | |||
2621 | /* | ||
2622 | * Based on the document from hardware guys the following bits | ||
2623 | * should be set unconditionally in order to enable FBC. | ||
2624 | * The bit 22 of 0x42000 | ||
2625 | * The bit 22 of 0x42004 | ||
2626 | * The bit 7,8,9 of 0x42020. | ||
2627 | */ | ||
2628 | if (IS_IRONLAKE_M(dev)) { | ||
2629 | I915_WRITE(ILK_DISPLAY_CHICKEN1, | ||
2630 | I915_READ(ILK_DISPLAY_CHICKEN1) | | ||
2631 | ILK_FBCQ_DIS); | ||
2632 | I915_WRITE(ILK_DISPLAY_CHICKEN2, | ||
2633 | I915_READ(ILK_DISPLAY_CHICKEN2) | | ||
2634 | ILK_DPARB_GATE); | ||
2635 | I915_WRITE(ILK_DSPCLK_GATE, | ||
2636 | I915_READ(ILK_DSPCLK_GATE) | | ||
2637 | ILK_DPFC_DIS1 | | ||
2638 | ILK_DPFC_DIS2 | | ||
2639 | ILK_CLK_FBC); | ||
2640 | } | ||
2641 | |||
2642 | I915_WRITE(ILK_DISPLAY_CHICKEN2, | ||
2643 | I915_READ(ILK_DISPLAY_CHICKEN2) | | ||
2644 | ILK_ELPIN_409_SELECT); | ||
2645 | I915_WRITE(_3D_CHICKEN2, | ||
2646 | _3D_CHICKEN2_WM_READ_PIPELINED << 16 | | ||
2647 | _3D_CHICKEN2_WM_READ_PIPELINED); | ||
2648 | } | ||
2649 | |||
2650 | static void gen6_init_clock_gating(struct drm_device *dev) | ||
2651 | { | ||
2652 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2653 | int pipe; | ||
2654 | uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE; | ||
2655 | |||
2656 | I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate); | ||
2657 | |||
2658 | I915_WRITE(ILK_DISPLAY_CHICKEN2, | ||
2659 | I915_READ(ILK_DISPLAY_CHICKEN2) | | ||
2660 | ILK_ELPIN_409_SELECT); | ||
2661 | |||
2662 | I915_WRITE(WM3_LP_ILK, 0); | ||
2663 | I915_WRITE(WM2_LP_ILK, 0); | ||
2664 | I915_WRITE(WM1_LP_ILK, 0); | ||
2665 | |||
2666 | /* clear masked bit */ | ||
2667 | I915_WRITE(CACHE_MODE_0, | ||
2668 | CM0_STC_EVICT_DISABLE_LRA_SNB << CM0_MASK_SHIFT); | ||
2669 | |||
2670 | I915_WRITE(GEN6_UCGCTL1, | ||
2671 | I915_READ(GEN6_UCGCTL1) | | ||
2672 | GEN6_BLBUNIT_CLOCK_GATE_DISABLE | | ||
2673 | GEN6_CSUNIT_CLOCK_GATE_DISABLE); | ||
2674 | |||
2675 | /* According to the BSpec vol1g, bit 12 (RCPBUNIT) clock | ||
2676 | * gating disable must be set. Failure to set it results in | ||
2677 | * flickering pixels due to Z write ordering failures after | ||
2678 | * some amount of runtime in the Mesa "fire" demo, and Unigine | ||
2679 | * Sanctuary and Tropics, and apparently anything else with | ||
2680 | * alpha test or pixel discard. | ||
2681 | * | ||
2682 | * According to the spec, bit 11 (RCCUNIT) must also be set, | ||
2683 | * but we didn't debug actual testcases to find it out. | ||
2684 | */ | ||
2685 | I915_WRITE(GEN6_UCGCTL2, | ||
2686 | GEN6_RCPBUNIT_CLOCK_GATE_DISABLE | | ||
2687 | GEN6_RCCUNIT_CLOCK_GATE_DISABLE); | ||
2688 | |||
2689 | /* Bspec says we need to always set all mask bits. */ | ||
2690 | I915_WRITE(_3D_CHICKEN, (0xFFFF << 16) | | ||
2691 | _3D_CHICKEN_SF_DISABLE_FASTCLIP_CULL); | ||
2692 | |||
2693 | /* | ||
2694 | * According to the spec the following bits should be | ||
2695 | * set in order to enable memory self-refresh and fbc: | ||
2696 | * The bit21 and bit22 of 0x42000 | ||
2697 | * The bit21 and bit22 of 0x42004 | ||
2698 | * The bit5 and bit7 of 0x42020 | ||
2699 | * The bit14 of 0x70180 | ||
2700 | * The bit14 of 0x71180 | ||
2701 | */ | ||
2702 | I915_WRITE(ILK_DISPLAY_CHICKEN1, | ||
2703 | I915_READ(ILK_DISPLAY_CHICKEN1) | | ||
2704 | ILK_FBCQ_DIS | ILK_PABSTRETCH_DIS); | ||
2705 | I915_WRITE(ILK_DISPLAY_CHICKEN2, | ||
2706 | I915_READ(ILK_DISPLAY_CHICKEN2) | | ||
2707 | ILK_DPARB_GATE | ILK_VSDPFD_FULL); | ||
2708 | I915_WRITE(ILK_DSPCLK_GATE, | ||
2709 | I915_READ(ILK_DSPCLK_GATE) | | ||
2710 | ILK_DPARB_CLK_GATE | | ||
2711 | ILK_DPFD_CLK_GATE); | ||
2712 | |||
2713 | for_each_pipe(pipe) { | ||
2714 | I915_WRITE(DSPCNTR(pipe), | ||
2715 | I915_READ(DSPCNTR(pipe)) | | ||
2716 | DISPPLANE_TRICKLE_FEED_DISABLE); | ||
2717 | intel_flush_display_plane(dev_priv, pipe); | ||
2718 | } | ||
2719 | } | ||
2720 | |||
2721 | static void gen7_setup_fixed_func_scheduler(struct drm_i915_private *dev_priv) | ||
2722 | { | ||
2723 | uint32_t reg = I915_READ(GEN7_FF_THREAD_MODE); | ||
2724 | |||
2725 | reg &= ~GEN7_FF_SCHED_MASK; | ||
2726 | reg |= GEN7_FF_TS_SCHED_HW; | ||
2727 | reg |= GEN7_FF_VS_SCHED_HW; | ||
2728 | reg |= GEN7_FF_DS_SCHED_HW; | ||
2729 | |||
2730 | I915_WRITE(GEN7_FF_THREAD_MODE, reg); | ||
2731 | } | ||
2732 | |||
2733 | static void ivybridge_init_clock_gating(struct drm_device *dev) | ||
2734 | { | ||
2735 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2736 | int pipe; | ||
2737 | uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE; | ||
2738 | |||
2739 | I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate); | ||
2740 | |||
2741 | I915_WRITE(WM3_LP_ILK, 0); | ||
2742 | I915_WRITE(WM2_LP_ILK, 0); | ||
2743 | I915_WRITE(WM1_LP_ILK, 0); | ||
2744 | |||
2745 | /* According to the spec, bit 13 (RCZUNIT) must be set on IVB. | ||
2746 | * This implements the WaDisableRCZUnitClockGating workaround. | ||
2747 | */ | ||
2748 | I915_WRITE(GEN6_UCGCTL2, GEN6_RCZUNIT_CLOCK_GATE_DISABLE); | ||
2749 | |||
2750 | I915_WRITE(ILK_DSPCLK_GATE, IVB_VRHUNIT_CLK_GATE); | ||
2751 | |||
2752 | I915_WRITE(IVB_CHICKEN3, | ||
2753 | CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE | | ||
2754 | CHICKEN3_DGMG_DONE_FIX_DISABLE); | ||
2755 | |||
2756 | /* Apply the WaDisableRHWOOptimizationForRenderHang workaround. */ | ||
2757 | I915_WRITE(GEN7_COMMON_SLICE_CHICKEN1, | ||
2758 | GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC); | ||
2759 | |||
2760 | /* WaApplyL3ControlAndL3ChickenMode requires those two on Ivy Bridge */ | ||
2761 | I915_WRITE(GEN7_L3CNTLREG1, | ||
2762 | GEN7_WA_FOR_GEN7_L3_CONTROL); | ||
2763 | I915_WRITE(GEN7_L3_CHICKEN_MODE_REGISTER, | ||
2764 | GEN7_WA_L3_CHICKEN_MODE); | ||
2765 | |||
2766 | /* This is required by WaCatErrorRejectionIssue */ | ||
2767 | I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, | ||
2768 | I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | | ||
2769 | GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); | ||
2770 | |||
2771 | for_each_pipe(pipe) { | ||
2772 | I915_WRITE(DSPCNTR(pipe), | ||
2773 | I915_READ(DSPCNTR(pipe)) | | ||
2774 | DISPPLANE_TRICKLE_FEED_DISABLE); | ||
2775 | intel_flush_display_plane(dev_priv, pipe); | ||
2776 | } | ||
2777 | |||
2778 | gen7_setup_fixed_func_scheduler(dev_priv); | ||
2779 | } | ||
2780 | |||
2781 | static void valleyview_init_clock_gating(struct drm_device *dev) | ||
2782 | { | ||
2783 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2784 | int pipe; | ||
2785 | uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE; | ||
2786 | |||
2787 | I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate); | ||
2788 | |||
2789 | I915_WRITE(WM3_LP_ILK, 0); | ||
2790 | I915_WRITE(WM2_LP_ILK, 0); | ||
2791 | I915_WRITE(WM1_LP_ILK, 0); | ||
2792 | |||
2793 | /* According to the spec, bit 13 (RCZUNIT) must be set on IVB. | ||
2794 | * This implements the WaDisableRCZUnitClockGating workaround. | ||
2795 | */ | ||
2796 | I915_WRITE(GEN6_UCGCTL2, GEN6_RCZUNIT_CLOCK_GATE_DISABLE); | ||
2797 | |||
2798 | I915_WRITE(ILK_DSPCLK_GATE, IVB_VRHUNIT_CLK_GATE); | ||
2799 | |||
2800 | I915_WRITE(IVB_CHICKEN3, | ||
2801 | CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE | | ||
2802 | CHICKEN3_DGMG_DONE_FIX_DISABLE); | ||
2803 | |||
2804 | /* Apply the WaDisableRHWOOptimizationForRenderHang workaround. */ | ||
2805 | I915_WRITE(GEN7_COMMON_SLICE_CHICKEN1, | ||
2806 | GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC); | ||
2807 | |||
2808 | /* WaApplyL3ControlAndL3ChickenMode requires those two on Ivy Bridge */ | ||
2809 | I915_WRITE(GEN7_L3CNTLREG1, GEN7_WA_FOR_GEN7_L3_CONTROL); | ||
2810 | I915_WRITE(GEN7_L3_CHICKEN_MODE_REGISTER, GEN7_WA_L3_CHICKEN_MODE); | ||
2811 | |||
2812 | /* This is required by WaCatErrorRejectionIssue */ | ||
2813 | I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, | ||
2814 | I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | | ||
2815 | GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); | ||
2816 | |||
2817 | for_each_pipe(pipe) { | ||
2818 | I915_WRITE(DSPCNTR(pipe), | ||
2819 | I915_READ(DSPCNTR(pipe)) | | ||
2820 | DISPPLANE_TRICKLE_FEED_DISABLE); | ||
2821 | intel_flush_display_plane(dev_priv, pipe); | ||
2822 | } | ||
2823 | |||
2824 | I915_WRITE(CACHE_MODE_1, I915_READ(CACHE_MODE_1) | | ||
2825 | (PIXEL_SUBSPAN_COLLECT_OPT_DISABLE << 16) | | ||
2826 | PIXEL_SUBSPAN_COLLECT_OPT_DISABLE); | ||
2827 | } | ||
2828 | |||
2829 | static void g4x_init_clock_gating(struct drm_device *dev) | ||
2830 | { | ||
2831 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2832 | uint32_t dspclk_gate; | ||
2833 | |||
2834 | I915_WRITE(RENCLK_GATE_D1, 0); | ||
2835 | I915_WRITE(RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE | | ||
2836 | GS_UNIT_CLOCK_GATE_DISABLE | | ||
2837 | CL_UNIT_CLOCK_GATE_DISABLE); | ||
2838 | I915_WRITE(RAMCLK_GATE_D, 0); | ||
2839 | dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE | | ||
2840 | OVRUNIT_CLOCK_GATE_DISABLE | | ||
2841 | OVCUNIT_CLOCK_GATE_DISABLE; | ||
2842 | if (IS_GM45(dev)) | ||
2843 | dspclk_gate |= DSSUNIT_CLOCK_GATE_DISABLE; | ||
2844 | I915_WRITE(DSPCLK_GATE_D, dspclk_gate); | ||
2845 | } | ||
2846 | |||
2847 | static void crestline_init_clock_gating(struct drm_device *dev) | ||
2848 | { | ||
2849 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2850 | |||
2851 | I915_WRITE(RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE); | ||
2852 | I915_WRITE(RENCLK_GATE_D2, 0); | ||
2853 | I915_WRITE(DSPCLK_GATE_D, 0); | ||
2854 | I915_WRITE(RAMCLK_GATE_D, 0); | ||
2855 | I915_WRITE16(DEUC, 0); | ||
2856 | } | ||
2857 | |||
2858 | static void broadwater_init_clock_gating(struct drm_device *dev) | ||
2859 | { | ||
2860 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2861 | |||
2862 | I915_WRITE(RENCLK_GATE_D1, I965_RCZ_CLOCK_GATE_DISABLE | | ||
2863 | I965_RCC_CLOCK_GATE_DISABLE | | ||
2864 | I965_RCPB_CLOCK_GATE_DISABLE | | ||
2865 | I965_ISC_CLOCK_GATE_DISABLE | | ||
2866 | I965_FBC_CLOCK_GATE_DISABLE); | ||
2867 | I915_WRITE(RENCLK_GATE_D2, 0); | ||
2868 | } | ||
2869 | |||
2870 | static void gen3_init_clock_gating(struct drm_device *dev) | ||
2871 | { | ||
2872 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2873 | u32 dstate = I915_READ(D_STATE); | ||
2874 | |||
2875 | dstate |= DSTATE_PLL_D3_OFF | DSTATE_GFX_CLOCK_GATING | | ||
2876 | DSTATE_DOT_CLOCK_GATING; | ||
2877 | I915_WRITE(D_STATE, dstate); | ||
2878 | } | ||
2879 | |||
2880 | static void i85x_init_clock_gating(struct drm_device *dev) | ||
2881 | { | ||
2882 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2883 | |||
2884 | I915_WRITE(RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE); | ||
2885 | } | ||
2886 | |||
2887 | static void i830_init_clock_gating(struct drm_device *dev) | ||
2888 | { | ||
2889 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2890 | |||
2891 | I915_WRITE(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE); | ||
2892 | } | ||
2893 | |||
2894 | static void ibx_init_clock_gating(struct drm_device *dev) | ||
2895 | { | ||
2896 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2897 | |||
2898 | /* | ||
2899 | * On Ibex Peak and Cougar Point, we need to disable clock | ||
2900 | * gating for the panel power sequencer or it will fail to | ||
2901 | * start up when no ports are active. | ||
2902 | */ | ||
2903 | I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE); | ||
2904 | } | ||
2905 | |||
2906 | static void cpt_init_clock_gating(struct drm_device *dev) | ||
2907 | { | ||
2908 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2909 | int pipe; | ||
2910 | |||
2911 | /* | ||
2912 | * On Ibex Peak and Cougar Point, we need to disable clock | ||
2913 | * gating for the panel power sequencer or it will fail to | ||
2914 | * start up when no ports are active. | ||
2915 | */ | ||
2916 | I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE); | ||
2917 | I915_WRITE(SOUTH_CHICKEN2, I915_READ(SOUTH_CHICKEN2) | | ||
2918 | DPLS_EDP_PPS_FIX_DIS); | ||
2919 | /* Without this, mode sets may fail silently on FDI */ | ||
2920 | for_each_pipe(pipe) | ||
2921 | I915_WRITE(TRANS_CHICKEN2(pipe), TRANS_AUTOTRAIN_GEN_STALL_DIS); | ||
2922 | } | ||
2923 | |||
2924 | void intel_init_clock_gating(struct drm_device *dev) | ||
2925 | { | ||
2926 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2927 | |||
2928 | dev_priv->display.init_clock_gating(dev); | ||
2929 | |||
2930 | if (dev_priv->display.init_pch_clock_gating) | ||
2931 | dev_priv->display.init_pch_clock_gating(dev); | ||
2932 | } | ||
2933 | |||
2934 | /* Set up chip specific power management-related functions */ | ||
2935 | void intel_init_pm(struct drm_device *dev) | ||
2936 | { | ||
2937 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2938 | |||
2939 | if (I915_HAS_FBC(dev)) { | ||
2940 | if (HAS_PCH_SPLIT(dev)) { | ||
2941 | dev_priv->display.fbc_enabled = ironlake_fbc_enabled; | ||
2942 | dev_priv->display.enable_fbc = ironlake_enable_fbc; | ||
2943 | dev_priv->display.disable_fbc = ironlake_disable_fbc; | ||
2944 | } else if (IS_GM45(dev)) { | ||
2945 | dev_priv->display.fbc_enabled = g4x_fbc_enabled; | ||
2946 | dev_priv->display.enable_fbc = g4x_enable_fbc; | ||
2947 | dev_priv->display.disable_fbc = g4x_disable_fbc; | ||
2948 | } else if (IS_CRESTLINE(dev)) { | ||
2949 | dev_priv->display.fbc_enabled = i8xx_fbc_enabled; | ||
2950 | dev_priv->display.enable_fbc = i8xx_enable_fbc; | ||
2951 | dev_priv->display.disable_fbc = i8xx_disable_fbc; | ||
2952 | } | ||
2953 | /* 855GM needs testing */ | ||
2954 | } | ||
2955 | |||
2956 | /* For FIFO watermark updates */ | ||
2957 | if (HAS_PCH_SPLIT(dev)) { | ||
2958 | dev_priv->display.force_wake_get = __gen6_gt_force_wake_get; | ||
2959 | dev_priv->display.force_wake_put = __gen6_gt_force_wake_put; | ||
2960 | |||
2961 | /* IVB configs may use multi-threaded forcewake */ | ||
2962 | if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) { | ||
2963 | u32 ecobus; | ||
2964 | |||
2965 | /* A small trick here - if the bios hasn't configured MT forcewake, | ||
2966 | * and if the device is in RC6, then force_wake_mt_get will not wake | ||
2967 | * the device and the ECOBUS read will return zero. Which will be | ||
2968 | * (correctly) interpreted by the test below as MT forcewake being | ||
2969 | * disabled. | ||
2970 | */ | ||
2971 | mutex_lock(&dev->struct_mutex); | ||
2972 | __gen6_gt_force_wake_mt_get(dev_priv); | ||
2973 | ecobus = I915_READ_NOTRACE(ECOBUS); | ||
2974 | __gen6_gt_force_wake_mt_put(dev_priv); | ||
2975 | mutex_unlock(&dev->struct_mutex); | ||
2976 | |||
2977 | if (ecobus & FORCEWAKE_MT_ENABLE) { | ||
2978 | DRM_DEBUG_KMS("Using MT version of forcewake\n"); | ||
2979 | dev_priv->display.force_wake_get = | ||
2980 | __gen6_gt_force_wake_mt_get; | ||
2981 | dev_priv->display.force_wake_put = | ||
2982 | __gen6_gt_force_wake_mt_put; | ||
2983 | } | ||
2984 | } | ||
2985 | |||
2986 | if (HAS_PCH_IBX(dev)) | ||
2987 | dev_priv->display.init_pch_clock_gating = ibx_init_clock_gating; | ||
2988 | else if (HAS_PCH_CPT(dev)) | ||
2989 | dev_priv->display.init_pch_clock_gating = cpt_init_clock_gating; | ||
2990 | |||
2991 | if (IS_GEN5(dev)) { | ||
2992 | if (I915_READ(MLTR_ILK) & ILK_SRLT_MASK) | ||
2993 | dev_priv->display.update_wm = ironlake_update_wm; | ||
2994 | else { | ||
2995 | DRM_DEBUG_KMS("Failed to get proper latency. " | ||
2996 | "Disable CxSR\n"); | ||
2997 | dev_priv->display.update_wm = NULL; | ||
2998 | } | ||
2999 | dev_priv->display.init_clock_gating = ironlake_init_clock_gating; | ||
3000 | } else if (IS_GEN6(dev)) { | ||
3001 | if (SNB_READ_WM0_LATENCY()) { | ||
3002 | dev_priv->display.update_wm = sandybridge_update_wm; | ||
3003 | dev_priv->display.update_sprite_wm = sandybridge_update_sprite_wm; | ||
3004 | } else { | ||
3005 | DRM_DEBUG_KMS("Failed to read display plane latency. " | ||
3006 | "Disable CxSR\n"); | ||
3007 | dev_priv->display.update_wm = NULL; | ||
3008 | } | ||
3009 | dev_priv->display.init_clock_gating = gen6_init_clock_gating; | ||
3010 | } else if (IS_IVYBRIDGE(dev)) { | ||
3011 | /* FIXME: detect B0+ stepping and use auto training */ | ||
3012 | if (SNB_READ_WM0_LATENCY()) { | ||
3013 | dev_priv->display.update_wm = sandybridge_update_wm; | ||
3014 | dev_priv->display.update_sprite_wm = sandybridge_update_sprite_wm; | ||
3015 | } else { | ||
3016 | DRM_DEBUG_KMS("Failed to read display plane latency. " | ||
3017 | "Disable CxSR\n"); | ||
3018 | dev_priv->display.update_wm = NULL; | ||
3019 | } | ||
3020 | dev_priv->display.init_clock_gating = ivybridge_init_clock_gating; | ||
3021 | } else | ||
3022 | dev_priv->display.update_wm = NULL; | ||
3023 | } else if (IS_VALLEYVIEW(dev)) { | ||
3024 | dev_priv->display.update_wm = valleyview_update_wm; | ||
3025 | dev_priv->display.init_clock_gating = | ||
3026 | valleyview_init_clock_gating; | ||
3027 | dev_priv->display.force_wake_get = vlv_force_wake_get; | ||
3028 | dev_priv->display.force_wake_put = vlv_force_wake_put; | ||
3029 | } else if (IS_PINEVIEW(dev)) { | ||
3030 | if (!intel_get_cxsr_latency(IS_PINEVIEW_G(dev), | ||
3031 | dev_priv->is_ddr3, | ||
3032 | dev_priv->fsb_freq, | ||
3033 | dev_priv->mem_freq)) { | ||
3034 | DRM_INFO("failed to find known CxSR latency " | ||
3035 | "(found ddr%s fsb freq %d, mem freq %d), " | ||
3036 | "disabling CxSR\n", | ||
3037 | (dev_priv->is_ddr3 == 1) ? "3" : "2", | ||
3038 | dev_priv->fsb_freq, dev_priv->mem_freq); | ||
3039 | /* Disable CxSR and never update its watermark again */ | ||
3040 | pineview_disable_cxsr(dev); | ||
3041 | dev_priv->display.update_wm = NULL; | ||
3042 | } else | ||
3043 | dev_priv->display.update_wm = pineview_update_wm; | ||
3044 | dev_priv->display.init_clock_gating = gen3_init_clock_gating; | ||
3045 | } else if (IS_G4X(dev)) { | ||
3046 | dev_priv->display.update_wm = g4x_update_wm; | ||
3047 | dev_priv->display.init_clock_gating = g4x_init_clock_gating; | ||
3048 | } else if (IS_GEN4(dev)) { | ||
3049 | dev_priv->display.update_wm = i965_update_wm; | ||
3050 | if (IS_CRESTLINE(dev)) | ||
3051 | dev_priv->display.init_clock_gating = crestline_init_clock_gating; | ||
3052 | else if (IS_BROADWATER(dev)) | ||
3053 | dev_priv->display.init_clock_gating = broadwater_init_clock_gating; | ||
3054 | } else if (IS_GEN3(dev)) { | ||
3055 | dev_priv->display.update_wm = i9xx_update_wm; | ||
3056 | dev_priv->display.get_fifo_size = i9xx_get_fifo_size; | ||
3057 | dev_priv->display.init_clock_gating = gen3_init_clock_gating; | ||
3058 | } else if (IS_I865G(dev)) { | ||
3059 | dev_priv->display.update_wm = i830_update_wm; | ||
3060 | dev_priv->display.init_clock_gating = i85x_init_clock_gating; | ||
3061 | dev_priv->display.get_fifo_size = i830_get_fifo_size; | ||
3062 | } else if (IS_I85X(dev)) { | ||
3063 | dev_priv->display.update_wm = i9xx_update_wm; | ||
3064 | dev_priv->display.get_fifo_size = i85x_get_fifo_size; | ||
3065 | dev_priv->display.init_clock_gating = i85x_init_clock_gating; | ||
3066 | } else { | ||
3067 | dev_priv->display.update_wm = i830_update_wm; | ||
3068 | dev_priv->display.init_clock_gating = i830_init_clock_gating; | ||
3069 | if (IS_845G(dev)) | ||
3070 | dev_priv->display.get_fifo_size = i845_get_fifo_size; | ||
3071 | else | ||
3072 | dev_priv->display.get_fifo_size = i830_get_fifo_size; | ||
3073 | } | ||
3074 | } | ||
3075 | |||
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index dfdb613752c5..12d9bc789dfb 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -53,9 +53,35 @@ static inline int ring_space(struct intel_ring_buffer *ring) | |||
53 | } | 53 | } |
54 | 54 | ||
55 | static int | 55 | static int |
56 | render_ring_flush(struct intel_ring_buffer *ring, | 56 | gen2_render_ring_flush(struct intel_ring_buffer *ring, |
57 | u32 invalidate_domains, | 57 | u32 invalidate_domains, |
58 | u32 flush_domains) | 58 | u32 flush_domains) |
59 | { | ||
60 | u32 cmd; | ||
61 | int ret; | ||
62 | |||
63 | cmd = MI_FLUSH; | ||
64 | if (((invalidate_domains|flush_domains) & I915_GEM_DOMAIN_RENDER) == 0) | ||
65 | cmd |= MI_NO_WRITE_FLUSH; | ||
66 | |||
67 | if (invalidate_domains & I915_GEM_DOMAIN_SAMPLER) | ||
68 | cmd |= MI_READ_FLUSH; | ||
69 | |||
70 | ret = intel_ring_begin(ring, 2); | ||
71 | if (ret) | ||
72 | return ret; | ||
73 | |||
74 | intel_ring_emit(ring, cmd); | ||
75 | intel_ring_emit(ring, MI_NOOP); | ||
76 | intel_ring_advance(ring); | ||
77 | |||
78 | return 0; | ||
79 | } | ||
80 | |||
81 | static int | ||
82 | gen4_render_ring_flush(struct intel_ring_buffer *ring, | ||
83 | u32 invalidate_domains, | ||
84 | u32 flush_domains) | ||
59 | { | 85 | { |
60 | struct drm_device *dev = ring->dev; | 86 | struct drm_device *dev = ring->dev; |
61 | u32 cmd; | 87 | u32 cmd; |
@@ -90,17 +116,8 @@ render_ring_flush(struct intel_ring_buffer *ring, | |||
90 | */ | 116 | */ |
91 | 117 | ||
92 | cmd = MI_FLUSH | MI_NO_WRITE_FLUSH; | 118 | cmd = MI_FLUSH | MI_NO_WRITE_FLUSH; |
93 | if ((invalidate_domains|flush_domains) & | 119 | if ((invalidate_domains|flush_domains) & I915_GEM_DOMAIN_RENDER) |
94 | I915_GEM_DOMAIN_RENDER) | ||
95 | cmd &= ~MI_NO_WRITE_FLUSH; | 120 | cmd &= ~MI_NO_WRITE_FLUSH; |
96 | if (INTEL_INFO(dev)->gen < 4) { | ||
97 | /* | ||
98 | * On the 965, the sampler cache always gets flushed | ||
99 | * and this bit is reserved. | ||
100 | */ | ||
101 | if (invalidate_domains & I915_GEM_DOMAIN_SAMPLER) | ||
102 | cmd |= MI_READ_FLUSH; | ||
103 | } | ||
104 | if (invalidate_domains & I915_GEM_DOMAIN_INSTRUCTION) | 121 | if (invalidate_domains & I915_GEM_DOMAIN_INSTRUCTION) |
105 | cmd |= MI_EXE_FLUSH; | 122 | cmd |= MI_EXE_FLUSH; |
106 | 123 | ||
@@ -472,21 +489,30 @@ gen6_add_request(struct intel_ring_buffer *ring, | |||
472 | * @seqno - seqno which the waiter will block on | 489 | * @seqno - seqno which the waiter will block on |
473 | */ | 490 | */ |
474 | static int | 491 | static int |
475 | intel_ring_sync(struct intel_ring_buffer *waiter, | 492 | gen6_ring_sync(struct intel_ring_buffer *waiter, |
476 | struct intel_ring_buffer *signaller, | 493 | struct intel_ring_buffer *signaller, |
477 | int ring, | 494 | u32 seqno) |
478 | u32 seqno) | ||
479 | { | 495 | { |
480 | int ret; | 496 | int ret; |
481 | u32 dw1 = MI_SEMAPHORE_MBOX | | 497 | u32 dw1 = MI_SEMAPHORE_MBOX | |
482 | MI_SEMAPHORE_COMPARE | | 498 | MI_SEMAPHORE_COMPARE | |
483 | MI_SEMAPHORE_REGISTER; | 499 | MI_SEMAPHORE_REGISTER; |
484 | 500 | ||
501 | /* Throughout all of the GEM code, seqno passed implies our current | ||
502 | * seqno is >= the last seqno executed. However for hardware the | ||
503 | * comparison is strictly greater than. | ||
504 | */ | ||
505 | seqno -= 1; | ||
506 | |||
507 | WARN_ON(signaller->semaphore_register[waiter->id] == | ||
508 | MI_SEMAPHORE_SYNC_INVALID); | ||
509 | |||
485 | ret = intel_ring_begin(waiter, 4); | 510 | ret = intel_ring_begin(waiter, 4); |
486 | if (ret) | 511 | if (ret) |
487 | return ret; | 512 | return ret; |
488 | 513 | ||
489 | intel_ring_emit(waiter, dw1 | signaller->semaphore_register[ring]); | 514 | intel_ring_emit(waiter, |
515 | dw1 | signaller->semaphore_register[waiter->id]); | ||
490 | intel_ring_emit(waiter, seqno); | 516 | intel_ring_emit(waiter, seqno); |
491 | intel_ring_emit(waiter, 0); | 517 | intel_ring_emit(waiter, 0); |
492 | intel_ring_emit(waiter, MI_NOOP); | 518 | intel_ring_emit(waiter, MI_NOOP); |
@@ -495,47 +521,6 @@ intel_ring_sync(struct intel_ring_buffer *waiter, | |||
495 | return 0; | 521 | return 0; |
496 | } | 522 | } |
497 | 523 | ||
498 | /* VCS->RCS (RVSYNC) or BCS->RCS (RBSYNC) */ | ||
499 | int | ||
500 | render_ring_sync_to(struct intel_ring_buffer *waiter, | ||
501 | struct intel_ring_buffer *signaller, | ||
502 | u32 seqno) | ||
503 | { | ||
504 | WARN_ON(signaller->semaphore_register[RCS] == MI_SEMAPHORE_SYNC_INVALID); | ||
505 | return intel_ring_sync(waiter, | ||
506 | signaller, | ||
507 | RCS, | ||
508 | seqno); | ||
509 | } | ||
510 | |||
511 | /* RCS->VCS (VRSYNC) or BCS->VCS (VBSYNC) */ | ||
512 | int | ||
513 | gen6_bsd_ring_sync_to(struct intel_ring_buffer *waiter, | ||
514 | struct intel_ring_buffer *signaller, | ||
515 | u32 seqno) | ||
516 | { | ||
517 | WARN_ON(signaller->semaphore_register[VCS] == MI_SEMAPHORE_SYNC_INVALID); | ||
518 | return intel_ring_sync(waiter, | ||
519 | signaller, | ||
520 | VCS, | ||
521 | seqno); | ||
522 | } | ||
523 | |||
524 | /* RCS->BCS (BRSYNC) or VCS->BCS (BVSYNC) */ | ||
525 | int | ||
526 | gen6_blt_ring_sync_to(struct intel_ring_buffer *waiter, | ||
527 | struct intel_ring_buffer *signaller, | ||
528 | u32 seqno) | ||
529 | { | ||
530 | WARN_ON(signaller->semaphore_register[BCS] == MI_SEMAPHORE_SYNC_INVALID); | ||
531 | return intel_ring_sync(waiter, | ||
532 | signaller, | ||
533 | BCS, | ||
534 | seqno); | ||
535 | } | ||
536 | |||
537 | |||
538 | |||
539 | #define PIPE_CONTROL_FLUSH(ring__, addr__) \ | 524 | #define PIPE_CONTROL_FLUSH(ring__, addr__) \ |
540 | do { \ | 525 | do { \ |
541 | intel_ring_emit(ring__, GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE | \ | 526 | intel_ring_emit(ring__, GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE | \ |
@@ -597,27 +582,6 @@ pc_render_add_request(struct intel_ring_buffer *ring, | |||
597 | return 0; | 582 | return 0; |
598 | } | 583 | } |
599 | 584 | ||
600 | static int | ||
601 | render_ring_add_request(struct intel_ring_buffer *ring, | ||
602 | u32 *result) | ||
603 | { | ||
604 | u32 seqno = i915_gem_next_request_seqno(ring); | ||
605 | int ret; | ||
606 | |||
607 | ret = intel_ring_begin(ring, 4); | ||
608 | if (ret) | ||
609 | return ret; | ||
610 | |||
611 | intel_ring_emit(ring, MI_STORE_DWORD_INDEX); | ||
612 | intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); | ||
613 | intel_ring_emit(ring, seqno); | ||
614 | intel_ring_emit(ring, MI_USER_INTERRUPT); | ||
615 | intel_ring_advance(ring); | ||
616 | |||
617 | *result = seqno; | ||
618 | return 0; | ||
619 | } | ||
620 | |||
621 | static u32 | 585 | static u32 |
622 | gen6_ring_get_seqno(struct intel_ring_buffer *ring) | 586 | gen6_ring_get_seqno(struct intel_ring_buffer *ring) |
623 | { | 587 | { |
@@ -644,40 +608,43 @@ pc_render_get_seqno(struct intel_ring_buffer *ring) | |||
644 | return pc->cpu_page[0]; | 608 | return pc->cpu_page[0]; |
645 | } | 609 | } |
646 | 610 | ||
647 | static void | 611 | static bool |
648 | ironlake_enable_irq(drm_i915_private_t *dev_priv, u32 mask) | 612 | gen5_ring_get_irq(struct intel_ring_buffer *ring) |
649 | { | 613 | { |
650 | dev_priv->gt_irq_mask &= ~mask; | 614 | struct drm_device *dev = ring->dev; |
651 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask); | 615 | drm_i915_private_t *dev_priv = dev->dev_private; |
652 | POSTING_READ(GTIMR); | ||
653 | } | ||
654 | 616 | ||
655 | static void | 617 | if (!dev->irq_enabled) |
656 | ironlake_disable_irq(drm_i915_private_t *dev_priv, u32 mask) | 618 | return false; |
657 | { | ||
658 | dev_priv->gt_irq_mask |= mask; | ||
659 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask); | ||
660 | POSTING_READ(GTIMR); | ||
661 | } | ||
662 | 619 | ||
663 | static void | 620 | spin_lock(&ring->irq_lock); |
664 | i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask) | 621 | if (ring->irq_refcount++ == 0) { |
665 | { | 622 | dev_priv->gt_irq_mask &= ~ring->irq_enable_mask; |
666 | dev_priv->irq_mask &= ~mask; | 623 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask); |
667 | I915_WRITE(IMR, dev_priv->irq_mask); | 624 | POSTING_READ(GTIMR); |
668 | POSTING_READ(IMR); | 625 | } |
626 | spin_unlock(&ring->irq_lock); | ||
627 | |||
628 | return true; | ||
669 | } | 629 | } |
670 | 630 | ||
671 | static void | 631 | static void |
672 | i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask) | 632 | gen5_ring_put_irq(struct intel_ring_buffer *ring) |
673 | { | 633 | { |
674 | dev_priv->irq_mask |= mask; | 634 | struct drm_device *dev = ring->dev; |
675 | I915_WRITE(IMR, dev_priv->irq_mask); | 635 | drm_i915_private_t *dev_priv = dev->dev_private; |
676 | POSTING_READ(IMR); | 636 | |
637 | spin_lock(&ring->irq_lock); | ||
638 | if (--ring->irq_refcount == 0) { | ||
639 | dev_priv->gt_irq_mask |= ring->irq_enable_mask; | ||
640 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask); | ||
641 | POSTING_READ(GTIMR); | ||
642 | } | ||
643 | spin_unlock(&ring->irq_lock); | ||
677 | } | 644 | } |
678 | 645 | ||
679 | static bool | 646 | static bool |
680 | render_ring_get_irq(struct intel_ring_buffer *ring) | 647 | i9xx_ring_get_irq(struct intel_ring_buffer *ring) |
681 | { | 648 | { |
682 | struct drm_device *dev = ring->dev; | 649 | struct drm_device *dev = ring->dev; |
683 | drm_i915_private_t *dev_priv = dev->dev_private; | 650 | drm_i915_private_t *dev_priv = dev->dev_private; |
@@ -687,11 +654,9 @@ render_ring_get_irq(struct intel_ring_buffer *ring) | |||
687 | 654 | ||
688 | spin_lock(&ring->irq_lock); | 655 | spin_lock(&ring->irq_lock); |
689 | if (ring->irq_refcount++ == 0) { | 656 | if (ring->irq_refcount++ == 0) { |
690 | if (INTEL_INFO(dev)->gen >= 5) | 657 | dev_priv->irq_mask &= ~ring->irq_enable_mask; |
691 | ironlake_enable_irq(dev_priv, | 658 | I915_WRITE(IMR, dev_priv->irq_mask); |
692 | GT_PIPE_NOTIFY | GT_USER_INTERRUPT); | 659 | POSTING_READ(IMR); |
693 | else | ||
694 | i915_enable_irq(dev_priv, I915_USER_INTERRUPT); | ||
695 | } | 660 | } |
696 | spin_unlock(&ring->irq_lock); | 661 | spin_unlock(&ring->irq_lock); |
697 | 662 | ||
@@ -699,19 +664,16 @@ render_ring_get_irq(struct intel_ring_buffer *ring) | |||
699 | } | 664 | } |
700 | 665 | ||
701 | static void | 666 | static void |
702 | render_ring_put_irq(struct intel_ring_buffer *ring) | 667 | i9xx_ring_put_irq(struct intel_ring_buffer *ring) |
703 | { | 668 | { |
704 | struct drm_device *dev = ring->dev; | 669 | struct drm_device *dev = ring->dev; |
705 | drm_i915_private_t *dev_priv = dev->dev_private; | 670 | drm_i915_private_t *dev_priv = dev->dev_private; |
706 | 671 | ||
707 | spin_lock(&ring->irq_lock); | 672 | spin_lock(&ring->irq_lock); |
708 | if (--ring->irq_refcount == 0) { | 673 | if (--ring->irq_refcount == 0) { |
709 | if (INTEL_INFO(dev)->gen >= 5) | 674 | dev_priv->irq_mask |= ring->irq_enable_mask; |
710 | ironlake_disable_irq(dev_priv, | 675 | I915_WRITE(IMR, dev_priv->irq_mask); |
711 | GT_USER_INTERRUPT | | 676 | POSTING_READ(IMR); |
712 | GT_PIPE_NOTIFY); | ||
713 | else | ||
714 | i915_disable_irq(dev_priv, I915_USER_INTERRUPT); | ||
715 | } | 677 | } |
716 | spin_unlock(&ring->irq_lock); | 678 | spin_unlock(&ring->irq_lock); |
717 | } | 679 | } |
@@ -765,7 +727,7 @@ bsd_ring_flush(struct intel_ring_buffer *ring, | |||
765 | } | 727 | } |
766 | 728 | ||
767 | static int | 729 | static int |
768 | ring_add_request(struct intel_ring_buffer *ring, | 730 | i9xx_add_request(struct intel_ring_buffer *ring, |
769 | u32 *result) | 731 | u32 *result) |
770 | { | 732 | { |
771 | u32 seqno; | 733 | u32 seqno; |
@@ -792,7 +754,6 @@ gen6_ring_get_irq(struct intel_ring_buffer *ring) | |||
792 | { | 754 | { |
793 | struct drm_device *dev = ring->dev; | 755 | struct drm_device *dev = ring->dev; |
794 | drm_i915_private_t *dev_priv = dev->dev_private; | 756 | drm_i915_private_t *dev_priv = dev->dev_private; |
795 | u32 mask = ring->irq_enable; | ||
796 | 757 | ||
797 | if (!dev->irq_enabled) | 758 | if (!dev->irq_enabled) |
798 | return false; | 759 | return false; |
@@ -804,9 +765,10 @@ gen6_ring_get_irq(struct intel_ring_buffer *ring) | |||
804 | 765 | ||
805 | spin_lock(&ring->irq_lock); | 766 | spin_lock(&ring->irq_lock); |
806 | if (ring->irq_refcount++ == 0) { | 767 | if (ring->irq_refcount++ == 0) { |
807 | ring->irq_mask &= ~mask; | 768 | I915_WRITE_IMR(ring, ~ring->irq_enable_mask); |
808 | I915_WRITE_IMR(ring, ring->irq_mask); | 769 | dev_priv->gt_irq_mask &= ~ring->irq_enable_mask; |
809 | ironlake_enable_irq(dev_priv, mask); | 770 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask); |
771 | POSTING_READ(GTIMR); | ||
810 | } | 772 | } |
811 | spin_unlock(&ring->irq_lock); | 773 | spin_unlock(&ring->irq_lock); |
812 | 774 | ||
@@ -818,105 +780,69 @@ gen6_ring_put_irq(struct intel_ring_buffer *ring) | |||
818 | { | 780 | { |
819 | struct drm_device *dev = ring->dev; | 781 | struct drm_device *dev = ring->dev; |
820 | drm_i915_private_t *dev_priv = dev->dev_private; | 782 | drm_i915_private_t *dev_priv = dev->dev_private; |
821 | u32 mask = ring->irq_enable; | ||
822 | 783 | ||
823 | spin_lock(&ring->irq_lock); | 784 | spin_lock(&ring->irq_lock); |
824 | if (--ring->irq_refcount == 0) { | 785 | if (--ring->irq_refcount == 0) { |
825 | ring->irq_mask |= mask; | 786 | I915_WRITE_IMR(ring, ~0); |
826 | I915_WRITE_IMR(ring, ring->irq_mask); | 787 | dev_priv->gt_irq_mask |= ring->irq_enable_mask; |
827 | ironlake_disable_irq(dev_priv, mask); | 788 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask); |
789 | POSTING_READ(GTIMR); | ||
828 | } | 790 | } |
829 | spin_unlock(&ring->irq_lock); | 791 | spin_unlock(&ring->irq_lock); |
830 | 792 | ||
831 | gen6_gt_force_wake_put(dev_priv); | 793 | gen6_gt_force_wake_put(dev_priv); |
832 | } | 794 | } |
833 | 795 | ||
834 | static bool | 796 | static int |
835 | bsd_ring_get_irq(struct intel_ring_buffer *ring) | 797 | i965_dispatch_execbuffer(struct intel_ring_buffer *ring, u32 offset, u32 length) |
836 | { | 798 | { |
837 | struct drm_device *dev = ring->dev; | 799 | int ret; |
838 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
839 | |||
840 | if (!dev->irq_enabled) | ||
841 | return false; | ||
842 | 800 | ||
843 | spin_lock(&ring->irq_lock); | 801 | ret = intel_ring_begin(ring, 2); |
844 | if (ring->irq_refcount++ == 0) { | 802 | if (ret) |
845 | if (IS_G4X(dev)) | 803 | return ret; |
846 | i915_enable_irq(dev_priv, I915_BSD_USER_INTERRUPT); | ||
847 | else | ||
848 | ironlake_enable_irq(dev_priv, GT_BSD_USER_INTERRUPT); | ||
849 | } | ||
850 | spin_unlock(&ring->irq_lock); | ||
851 | 804 | ||
852 | return true; | 805 | intel_ring_emit(ring, |
853 | } | 806 | MI_BATCH_BUFFER_START | |
854 | static void | 807 | MI_BATCH_GTT | |
855 | bsd_ring_put_irq(struct intel_ring_buffer *ring) | 808 | MI_BATCH_NON_SECURE_I965); |
856 | { | 809 | intel_ring_emit(ring, offset); |
857 | struct drm_device *dev = ring->dev; | 810 | intel_ring_advance(ring); |
858 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
859 | 811 | ||
860 | spin_lock(&ring->irq_lock); | 812 | return 0; |
861 | if (--ring->irq_refcount == 0) { | ||
862 | if (IS_G4X(dev)) | ||
863 | i915_disable_irq(dev_priv, I915_BSD_USER_INTERRUPT); | ||
864 | else | ||
865 | ironlake_disable_irq(dev_priv, GT_BSD_USER_INTERRUPT); | ||
866 | } | ||
867 | spin_unlock(&ring->irq_lock); | ||
868 | } | 813 | } |
869 | 814 | ||
870 | static int | 815 | static int |
871 | ring_dispatch_execbuffer(struct intel_ring_buffer *ring, u32 offset, u32 length) | 816 | i830_dispatch_execbuffer(struct intel_ring_buffer *ring, |
817 | u32 offset, u32 len) | ||
872 | { | 818 | { |
873 | int ret; | 819 | int ret; |
874 | 820 | ||
875 | ret = intel_ring_begin(ring, 2); | 821 | ret = intel_ring_begin(ring, 4); |
876 | if (ret) | 822 | if (ret) |
877 | return ret; | 823 | return ret; |
878 | 824 | ||
879 | intel_ring_emit(ring, | 825 | intel_ring_emit(ring, MI_BATCH_BUFFER); |
880 | MI_BATCH_BUFFER_START | (2 << 6) | | 826 | intel_ring_emit(ring, offset | MI_BATCH_NON_SECURE); |
881 | MI_BATCH_NON_SECURE_I965); | 827 | intel_ring_emit(ring, offset + len - 8); |
882 | intel_ring_emit(ring, offset); | 828 | intel_ring_emit(ring, 0); |
883 | intel_ring_advance(ring); | 829 | intel_ring_advance(ring); |
884 | 830 | ||
885 | return 0; | 831 | return 0; |
886 | } | 832 | } |
887 | 833 | ||
888 | static int | 834 | static int |
889 | render_ring_dispatch_execbuffer(struct intel_ring_buffer *ring, | 835 | i915_dispatch_execbuffer(struct intel_ring_buffer *ring, |
890 | u32 offset, u32 len) | 836 | u32 offset, u32 len) |
891 | { | 837 | { |
892 | struct drm_device *dev = ring->dev; | ||
893 | int ret; | 838 | int ret; |
894 | 839 | ||
895 | if (IS_I830(dev) || IS_845G(dev)) { | 840 | ret = intel_ring_begin(ring, 2); |
896 | ret = intel_ring_begin(ring, 4); | 841 | if (ret) |
897 | if (ret) | 842 | return ret; |
898 | return ret; | ||
899 | |||
900 | intel_ring_emit(ring, MI_BATCH_BUFFER); | ||
901 | intel_ring_emit(ring, offset | MI_BATCH_NON_SECURE); | ||
902 | intel_ring_emit(ring, offset + len - 8); | ||
903 | intel_ring_emit(ring, 0); | ||
904 | } else { | ||
905 | ret = intel_ring_begin(ring, 2); | ||
906 | if (ret) | ||
907 | return ret; | ||
908 | 843 | ||
909 | if (INTEL_INFO(dev)->gen >= 4) { | 844 | intel_ring_emit(ring, MI_BATCH_BUFFER_START | MI_BATCH_GTT); |
910 | intel_ring_emit(ring, | 845 | intel_ring_emit(ring, offset | MI_BATCH_NON_SECURE); |
911 | MI_BATCH_BUFFER_START | (2 << 6) | | ||
912 | MI_BATCH_NON_SECURE_I965); | ||
913 | intel_ring_emit(ring, offset); | ||
914 | } else { | ||
915 | intel_ring_emit(ring, | ||
916 | MI_BATCH_BUFFER_START | (2 << 6)); | ||
917 | intel_ring_emit(ring, offset | MI_BATCH_NON_SECURE); | ||
918 | } | ||
919 | } | ||
920 | intel_ring_advance(ring); | 846 | intel_ring_advance(ring); |
921 | 847 | ||
922 | return 0; | 848 | return 0; |
@@ -983,8 +909,8 @@ err: | |||
983 | return ret; | 909 | return ret; |
984 | } | 910 | } |
985 | 911 | ||
986 | int intel_init_ring_buffer(struct drm_device *dev, | 912 | static int intel_init_ring_buffer(struct drm_device *dev, |
987 | struct intel_ring_buffer *ring) | 913 | struct intel_ring_buffer *ring) |
988 | { | 914 | { |
989 | struct drm_i915_gem_object *obj; | 915 | struct drm_i915_gem_object *obj; |
990 | int ret; | 916 | int ret; |
@@ -993,10 +919,10 @@ int intel_init_ring_buffer(struct drm_device *dev, | |||
993 | INIT_LIST_HEAD(&ring->active_list); | 919 | INIT_LIST_HEAD(&ring->active_list); |
994 | INIT_LIST_HEAD(&ring->request_list); | 920 | INIT_LIST_HEAD(&ring->request_list); |
995 | INIT_LIST_HEAD(&ring->gpu_write_list); | 921 | INIT_LIST_HEAD(&ring->gpu_write_list); |
922 | ring->size = 32 * PAGE_SIZE; | ||
996 | 923 | ||
997 | init_waitqueue_head(&ring->irq_queue); | 924 | init_waitqueue_head(&ring->irq_queue); |
998 | spin_lock_init(&ring->irq_lock); | 925 | spin_lock_init(&ring->irq_lock); |
999 | ring->irq_mask = ~0; | ||
1000 | 926 | ||
1001 | if (I915_NEED_GFX_HWS(dev)) { | 927 | if (I915_NEED_GFX_HWS(dev)) { |
1002 | ret = init_status_page(ring); | 928 | ret = init_status_page(ring); |
@@ -1040,7 +966,7 @@ int intel_init_ring_buffer(struct drm_device *dev, | |||
1040 | * of the buffer. | 966 | * of the buffer. |
1041 | */ | 967 | */ |
1042 | ring->effective_size = ring->size; | 968 | ring->effective_size = ring->size; |
1043 | if (IS_I830(ring->dev)) | 969 | if (IS_I830(ring->dev) || IS_845G(ring->dev)) |
1044 | ring->effective_size -= 128; | 970 | ring->effective_size -= 128; |
1045 | 971 | ||
1046 | return 0; | 972 | return 0; |
@@ -1263,44 +1189,6 @@ void intel_ring_advance(struct intel_ring_buffer *ring) | |||
1263 | ring->write_tail(ring, ring->tail); | 1189 | ring->write_tail(ring, ring->tail); |
1264 | } | 1190 | } |
1265 | 1191 | ||
1266 | static const struct intel_ring_buffer render_ring = { | ||
1267 | .name = "render ring", | ||
1268 | .id = RCS, | ||
1269 | .mmio_base = RENDER_RING_BASE, | ||
1270 | .size = 32 * PAGE_SIZE, | ||
1271 | .init = init_render_ring, | ||
1272 | .write_tail = ring_write_tail, | ||
1273 | .flush = render_ring_flush, | ||
1274 | .add_request = render_ring_add_request, | ||
1275 | .get_seqno = ring_get_seqno, | ||
1276 | .irq_get = render_ring_get_irq, | ||
1277 | .irq_put = render_ring_put_irq, | ||
1278 | .dispatch_execbuffer = render_ring_dispatch_execbuffer, | ||
1279 | .cleanup = render_ring_cleanup, | ||
1280 | .sync_to = render_ring_sync_to, | ||
1281 | .semaphore_register = {MI_SEMAPHORE_SYNC_INVALID, | ||
1282 | MI_SEMAPHORE_SYNC_RV, | ||
1283 | MI_SEMAPHORE_SYNC_RB}, | ||
1284 | .signal_mbox = {GEN6_VRSYNC, GEN6_BRSYNC}, | ||
1285 | }; | ||
1286 | |||
1287 | /* ring buffer for bit-stream decoder */ | ||
1288 | |||
1289 | static const struct intel_ring_buffer bsd_ring = { | ||
1290 | .name = "bsd ring", | ||
1291 | .id = VCS, | ||
1292 | .mmio_base = BSD_RING_BASE, | ||
1293 | .size = 32 * PAGE_SIZE, | ||
1294 | .init = init_ring_common, | ||
1295 | .write_tail = ring_write_tail, | ||
1296 | .flush = bsd_ring_flush, | ||
1297 | .add_request = ring_add_request, | ||
1298 | .get_seqno = ring_get_seqno, | ||
1299 | .irq_get = bsd_ring_get_irq, | ||
1300 | .irq_put = bsd_ring_put_irq, | ||
1301 | .dispatch_execbuffer = ring_dispatch_execbuffer, | ||
1302 | }; | ||
1303 | |||
1304 | 1192 | ||
1305 | static void gen6_bsd_ring_write_tail(struct intel_ring_buffer *ring, | 1193 | static void gen6_bsd_ring_write_tail(struct intel_ring_buffer *ring, |
1306 | u32 value) | 1194 | u32 value) |
@@ -1363,28 +1251,6 @@ gen6_ring_dispatch_execbuffer(struct intel_ring_buffer *ring, | |||
1363 | return 0; | 1251 | return 0; |
1364 | } | 1252 | } |
1365 | 1253 | ||
1366 | /* ring buffer for Video Codec for Gen6+ */ | ||
1367 | static const struct intel_ring_buffer gen6_bsd_ring = { | ||
1368 | .name = "gen6 bsd ring", | ||
1369 | .id = VCS, | ||
1370 | .mmio_base = GEN6_BSD_RING_BASE, | ||
1371 | .size = 32 * PAGE_SIZE, | ||
1372 | .init = init_ring_common, | ||
1373 | .write_tail = gen6_bsd_ring_write_tail, | ||
1374 | .flush = gen6_ring_flush, | ||
1375 | .add_request = gen6_add_request, | ||
1376 | .get_seqno = gen6_ring_get_seqno, | ||
1377 | .irq_enable = GEN6_BSD_USER_INTERRUPT, | ||
1378 | .irq_get = gen6_ring_get_irq, | ||
1379 | .irq_put = gen6_ring_put_irq, | ||
1380 | .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, | ||
1381 | .sync_to = gen6_bsd_ring_sync_to, | ||
1382 | .semaphore_register = {MI_SEMAPHORE_SYNC_VR, | ||
1383 | MI_SEMAPHORE_SYNC_INVALID, | ||
1384 | MI_SEMAPHORE_SYNC_VB}, | ||
1385 | .signal_mbox = {GEN6_RVSYNC, GEN6_BVSYNC}, | ||
1386 | }; | ||
1387 | |||
1388 | /* Blitter support (SandyBridge+) */ | 1254 | /* Blitter support (SandyBridge+) */ |
1389 | 1255 | ||
1390 | static int blt_ring_flush(struct intel_ring_buffer *ring, | 1256 | static int blt_ring_flush(struct intel_ring_buffer *ring, |
@@ -1408,44 +1274,58 @@ static int blt_ring_flush(struct intel_ring_buffer *ring, | |||
1408 | return 0; | 1274 | return 0; |
1409 | } | 1275 | } |
1410 | 1276 | ||
1411 | static const struct intel_ring_buffer gen6_blt_ring = { | ||
1412 | .name = "blt ring", | ||
1413 | .id = BCS, | ||
1414 | .mmio_base = BLT_RING_BASE, | ||
1415 | .size = 32 * PAGE_SIZE, | ||
1416 | .init = init_ring_common, | ||
1417 | .write_tail = ring_write_tail, | ||
1418 | .flush = blt_ring_flush, | ||
1419 | .add_request = gen6_add_request, | ||
1420 | .get_seqno = gen6_ring_get_seqno, | ||
1421 | .irq_get = gen6_ring_get_irq, | ||
1422 | .irq_put = gen6_ring_put_irq, | ||
1423 | .irq_enable = GEN6_BLITTER_USER_INTERRUPT, | ||
1424 | .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, | ||
1425 | .sync_to = gen6_blt_ring_sync_to, | ||
1426 | .semaphore_register = {MI_SEMAPHORE_SYNC_BR, | ||
1427 | MI_SEMAPHORE_SYNC_BV, | ||
1428 | MI_SEMAPHORE_SYNC_INVALID}, | ||
1429 | .signal_mbox = {GEN6_RBSYNC, GEN6_VBSYNC}, | ||
1430 | }; | ||
1431 | |||
1432 | int intel_init_render_ring_buffer(struct drm_device *dev) | 1277 | int intel_init_render_ring_buffer(struct drm_device *dev) |
1433 | { | 1278 | { |
1434 | drm_i915_private_t *dev_priv = dev->dev_private; | 1279 | drm_i915_private_t *dev_priv = dev->dev_private; |
1435 | struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; | 1280 | struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; |
1436 | 1281 | ||
1437 | *ring = render_ring; | 1282 | ring->name = "render ring"; |
1283 | ring->id = RCS; | ||
1284 | ring->mmio_base = RENDER_RING_BASE; | ||
1285 | |||
1438 | if (INTEL_INFO(dev)->gen >= 6) { | 1286 | if (INTEL_INFO(dev)->gen >= 6) { |
1439 | ring->add_request = gen6_add_request; | 1287 | ring->add_request = gen6_add_request; |
1440 | ring->flush = gen6_render_ring_flush; | 1288 | ring->flush = gen6_render_ring_flush; |
1441 | ring->irq_get = gen6_ring_get_irq; | 1289 | ring->irq_get = gen6_ring_get_irq; |
1442 | ring->irq_put = gen6_ring_put_irq; | 1290 | ring->irq_put = gen6_ring_put_irq; |
1443 | ring->irq_enable = GT_USER_INTERRUPT; | 1291 | ring->irq_enable_mask = GT_USER_INTERRUPT; |
1444 | ring->get_seqno = gen6_ring_get_seqno; | 1292 | ring->get_seqno = gen6_ring_get_seqno; |
1293 | ring->sync_to = gen6_ring_sync; | ||
1294 | ring->semaphore_register[0] = MI_SEMAPHORE_SYNC_INVALID; | ||
1295 | ring->semaphore_register[1] = MI_SEMAPHORE_SYNC_RV; | ||
1296 | ring->semaphore_register[2] = MI_SEMAPHORE_SYNC_RB; | ||
1297 | ring->signal_mbox[0] = GEN6_VRSYNC; | ||
1298 | ring->signal_mbox[1] = GEN6_BRSYNC; | ||
1445 | } else if (IS_GEN5(dev)) { | 1299 | } else if (IS_GEN5(dev)) { |
1446 | ring->add_request = pc_render_add_request; | 1300 | ring->add_request = pc_render_add_request; |
1301 | ring->flush = gen4_render_ring_flush; | ||
1447 | ring->get_seqno = pc_render_get_seqno; | 1302 | ring->get_seqno = pc_render_get_seqno; |
1303 | ring->irq_get = gen5_ring_get_irq; | ||
1304 | ring->irq_put = gen5_ring_put_irq; | ||
1305 | ring->irq_enable_mask = GT_USER_INTERRUPT | GT_PIPE_NOTIFY; | ||
1306 | } else { | ||
1307 | ring->add_request = i9xx_add_request; | ||
1308 | if (INTEL_INFO(dev)->gen < 4) | ||
1309 | ring->flush = gen2_render_ring_flush; | ||
1310 | else | ||
1311 | ring->flush = gen4_render_ring_flush; | ||
1312 | ring->get_seqno = ring_get_seqno; | ||
1313 | ring->irq_get = i9xx_ring_get_irq; | ||
1314 | ring->irq_put = i9xx_ring_put_irq; | ||
1315 | ring->irq_enable_mask = I915_USER_INTERRUPT; | ||
1448 | } | 1316 | } |
1317 | ring->write_tail = ring_write_tail; | ||
1318 | if (INTEL_INFO(dev)->gen >= 6) | ||
1319 | ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; | ||
1320 | else if (INTEL_INFO(dev)->gen >= 4) | ||
1321 | ring->dispatch_execbuffer = i965_dispatch_execbuffer; | ||
1322 | else if (IS_I830(dev) || IS_845G(dev)) | ||
1323 | ring->dispatch_execbuffer = i830_dispatch_execbuffer; | ||
1324 | else | ||
1325 | ring->dispatch_execbuffer = i915_dispatch_execbuffer; | ||
1326 | ring->init = init_render_ring; | ||
1327 | ring->cleanup = render_ring_cleanup; | ||
1328 | |||
1449 | 1329 | ||
1450 | if (!I915_NEED_GFX_HWS(dev)) { | 1330 | if (!I915_NEED_GFX_HWS(dev)) { |
1451 | ring->status_page.page_addr = dev_priv->status_page_dmah->vaddr; | 1331 | ring->status_page.page_addr = dev_priv->status_page_dmah->vaddr; |
@@ -1460,17 +1340,37 @@ int intel_render_ring_init_dri(struct drm_device *dev, u64 start, u32 size) | |||
1460 | drm_i915_private_t *dev_priv = dev->dev_private; | 1340 | drm_i915_private_t *dev_priv = dev->dev_private; |
1461 | struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; | 1341 | struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; |
1462 | 1342 | ||
1463 | *ring = render_ring; | 1343 | ring->name = "render ring"; |
1344 | ring->id = RCS; | ||
1345 | ring->mmio_base = RENDER_RING_BASE; | ||
1346 | |||
1464 | if (INTEL_INFO(dev)->gen >= 6) { | 1347 | if (INTEL_INFO(dev)->gen >= 6) { |
1465 | ring->add_request = gen6_add_request; | 1348 | /* non-kms not supported on gen6+ */ |
1466 | ring->irq_get = gen6_ring_get_irq; | 1349 | return -ENODEV; |
1467 | ring->irq_put = gen6_ring_put_irq; | ||
1468 | ring->irq_enable = GT_USER_INTERRUPT; | ||
1469 | } else if (IS_GEN5(dev)) { | ||
1470 | ring->add_request = pc_render_add_request; | ||
1471 | ring->get_seqno = pc_render_get_seqno; | ||
1472 | } | 1350 | } |
1473 | 1351 | ||
1352 | /* Note: gem is not supported on gen5/ilk without kms (the corresponding | ||
1353 | * gem_init ioctl returns with -ENODEV). Hence we do not need to set up | ||
1354 | * the special gen5 functions. */ | ||
1355 | ring->add_request = i9xx_add_request; | ||
1356 | if (INTEL_INFO(dev)->gen < 4) | ||
1357 | ring->flush = gen2_render_ring_flush; | ||
1358 | else | ||
1359 | ring->flush = gen4_render_ring_flush; | ||
1360 | ring->get_seqno = ring_get_seqno; | ||
1361 | ring->irq_get = i9xx_ring_get_irq; | ||
1362 | ring->irq_put = i9xx_ring_put_irq; | ||
1363 | ring->irq_enable_mask = I915_USER_INTERRUPT; | ||
1364 | ring->write_tail = ring_write_tail; | ||
1365 | if (INTEL_INFO(dev)->gen >= 4) | ||
1366 | ring->dispatch_execbuffer = i965_dispatch_execbuffer; | ||
1367 | else if (IS_I830(dev) || IS_845G(dev)) | ||
1368 | ring->dispatch_execbuffer = i830_dispatch_execbuffer; | ||
1369 | else | ||
1370 | ring->dispatch_execbuffer = i915_dispatch_execbuffer; | ||
1371 | ring->init = init_render_ring; | ||
1372 | ring->cleanup = render_ring_cleanup; | ||
1373 | |||
1474 | if (!I915_NEED_GFX_HWS(dev)) | 1374 | if (!I915_NEED_GFX_HWS(dev)) |
1475 | ring->status_page.page_addr = dev_priv->status_page_dmah->vaddr; | 1375 | ring->status_page.page_addr = dev_priv->status_page_dmah->vaddr; |
1476 | 1376 | ||
@@ -1506,10 +1406,46 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) | |||
1506 | drm_i915_private_t *dev_priv = dev->dev_private; | 1406 | drm_i915_private_t *dev_priv = dev->dev_private; |
1507 | struct intel_ring_buffer *ring = &dev_priv->ring[VCS]; | 1407 | struct intel_ring_buffer *ring = &dev_priv->ring[VCS]; |
1508 | 1408 | ||
1509 | if (IS_GEN6(dev) || IS_GEN7(dev)) | 1409 | ring->name = "bsd ring"; |
1510 | *ring = gen6_bsd_ring; | 1410 | ring->id = VCS; |
1511 | else | 1411 | |
1512 | *ring = bsd_ring; | 1412 | ring->write_tail = ring_write_tail; |
1413 | if (IS_GEN6(dev) || IS_GEN7(dev)) { | ||
1414 | ring->mmio_base = GEN6_BSD_RING_BASE; | ||
1415 | /* gen6 bsd needs a special wa for tail updates */ | ||
1416 | if (IS_GEN6(dev)) | ||
1417 | ring->write_tail = gen6_bsd_ring_write_tail; | ||
1418 | ring->flush = gen6_ring_flush; | ||
1419 | ring->add_request = gen6_add_request; | ||
1420 | ring->get_seqno = gen6_ring_get_seqno; | ||
1421 | ring->irq_enable_mask = GEN6_BSD_USER_INTERRUPT; | ||
1422 | ring->irq_get = gen6_ring_get_irq; | ||
1423 | ring->irq_put = gen6_ring_put_irq; | ||
1424 | ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; | ||
1425 | ring->sync_to = gen6_ring_sync; | ||
1426 | ring->semaphore_register[0] = MI_SEMAPHORE_SYNC_VR; | ||
1427 | ring->semaphore_register[1] = MI_SEMAPHORE_SYNC_INVALID; | ||
1428 | ring->semaphore_register[2] = MI_SEMAPHORE_SYNC_VB; | ||
1429 | ring->signal_mbox[0] = GEN6_RVSYNC; | ||
1430 | ring->signal_mbox[1] = GEN6_BVSYNC; | ||
1431 | } else { | ||
1432 | ring->mmio_base = BSD_RING_BASE; | ||
1433 | ring->flush = bsd_ring_flush; | ||
1434 | ring->add_request = i9xx_add_request; | ||
1435 | ring->get_seqno = ring_get_seqno; | ||
1436 | if (IS_GEN5(dev)) { | ||
1437 | ring->irq_enable_mask = GT_BSD_USER_INTERRUPT; | ||
1438 | ring->irq_get = gen5_ring_get_irq; | ||
1439 | ring->irq_put = gen5_ring_put_irq; | ||
1440 | } else { | ||
1441 | ring->irq_enable_mask = I915_BSD_USER_INTERRUPT; | ||
1442 | ring->irq_get = i9xx_ring_get_irq; | ||
1443 | ring->irq_put = i9xx_ring_put_irq; | ||
1444 | } | ||
1445 | ring->dispatch_execbuffer = i965_dispatch_execbuffer; | ||
1446 | } | ||
1447 | ring->init = init_ring_common; | ||
1448 | |||
1513 | 1449 | ||
1514 | return intel_init_ring_buffer(dev, ring); | 1450 | return intel_init_ring_buffer(dev, ring); |
1515 | } | 1451 | } |
@@ -1519,7 +1455,25 @@ int intel_init_blt_ring_buffer(struct drm_device *dev) | |||
1519 | drm_i915_private_t *dev_priv = dev->dev_private; | 1455 | drm_i915_private_t *dev_priv = dev->dev_private; |
1520 | struct intel_ring_buffer *ring = &dev_priv->ring[BCS]; | 1456 | struct intel_ring_buffer *ring = &dev_priv->ring[BCS]; |
1521 | 1457 | ||
1522 | *ring = gen6_blt_ring; | 1458 | ring->name = "blitter ring"; |
1459 | ring->id = BCS; | ||
1460 | |||
1461 | ring->mmio_base = BLT_RING_BASE; | ||
1462 | ring->write_tail = ring_write_tail; | ||
1463 | ring->flush = blt_ring_flush; | ||
1464 | ring->add_request = gen6_add_request; | ||
1465 | ring->get_seqno = gen6_ring_get_seqno; | ||
1466 | ring->irq_enable_mask = GEN6_BLITTER_USER_INTERRUPT; | ||
1467 | ring->irq_get = gen6_ring_get_irq; | ||
1468 | ring->irq_put = gen6_ring_put_irq; | ||
1469 | ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; | ||
1470 | ring->sync_to = gen6_ring_sync; | ||
1471 | ring->semaphore_register[0] = MI_SEMAPHORE_SYNC_BR; | ||
1472 | ring->semaphore_register[1] = MI_SEMAPHORE_SYNC_BV; | ||
1473 | ring->semaphore_register[2] = MI_SEMAPHORE_SYNC_INVALID; | ||
1474 | ring->signal_mbox[0] = GEN6_RBSYNC; | ||
1475 | ring->signal_mbox[1] = GEN6_VBSYNC; | ||
1476 | ring->init = init_ring_common; | ||
1523 | 1477 | ||
1524 | return intel_init_ring_buffer(dev, ring); | 1478 | return intel_init_ring_buffer(dev, ring); |
1525 | } | 1479 | } |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 3488a5a127db..06a66adf69c2 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h | |||
@@ -58,8 +58,7 @@ struct intel_ring_buffer { | |||
58 | 58 | ||
59 | spinlock_t irq_lock; | 59 | spinlock_t irq_lock; |
60 | u32 irq_refcount; | 60 | u32 irq_refcount; |
61 | u32 irq_mask; | 61 | u32 irq_enable_mask; /* bitmask to enable ring interrupt */ |
62 | u32 irq_enable; /* IRQs enabled for this ring */ | ||
63 | u32 irq_seqno; /* last seq seem at irq time */ | 62 | u32 irq_seqno; /* last seq seem at irq time */ |
64 | u32 trace_irq_seqno; | 63 | u32 trace_irq_seqno; |
65 | u32 waiting_seqno; | 64 | u32 waiting_seqno; |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 6898145b44ce..c330efd59a0e 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -443,9 +443,17 @@ static const char *cmd_status_names[] = { | |||
443 | static bool intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd, | 443 | static bool intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd, |
444 | const void *args, int args_len) | 444 | const void *args, int args_len) |
445 | { | 445 | { |
446 | u8 buf[args_len*2 + 2], status; | 446 | u8 *buf, status; |
447 | struct i2c_msg msgs[args_len + 3]; | 447 | struct i2c_msg *msgs; |
448 | int i, ret; | 448 | int i, ret = true; |
449 | |||
450 | buf = (u8 *)kzalloc(args_len * 2 + 2, GFP_KERNEL); | ||
451 | if (!buf) | ||
452 | return false; | ||
453 | |||
454 | msgs = kcalloc(args_len + 3, sizeof(*msgs), GFP_KERNEL); | ||
455 | if (!msgs) | ||
456 | return false; | ||
449 | 457 | ||
450 | intel_sdvo_debug_write(intel_sdvo, cmd, args, args_len); | 458 | intel_sdvo_debug_write(intel_sdvo, cmd, args, args_len); |
451 | 459 | ||
@@ -479,15 +487,19 @@ static bool intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd, | |||
479 | ret = i2c_transfer(intel_sdvo->i2c, msgs, i+3); | 487 | ret = i2c_transfer(intel_sdvo->i2c, msgs, i+3); |
480 | if (ret < 0) { | 488 | if (ret < 0) { |
481 | DRM_DEBUG_KMS("I2c transfer returned %d\n", ret); | 489 | DRM_DEBUG_KMS("I2c transfer returned %d\n", ret); |
482 | return false; | 490 | ret = false; |
491 | goto out; | ||
483 | } | 492 | } |
484 | if (ret != i+3) { | 493 | if (ret != i+3) { |
485 | /* failure in I2C transfer */ | 494 | /* failure in I2C transfer */ |
486 | DRM_DEBUG_KMS("I2c transfer returned %d/%d\n", ret, i+3); | 495 | DRM_DEBUG_KMS("I2c transfer returned %d/%d\n", ret, i+3); |
487 | return false; | 496 | ret = false; |
488 | } | 497 | } |
489 | 498 | ||
490 | return true; | 499 | out: |
500 | kfree(msgs); | ||
501 | kfree(buf); | ||
502 | return ret; | ||
491 | } | 503 | } |
492 | 504 | ||
493 | static bool intel_sdvo_read_response(struct intel_sdvo *intel_sdvo, | 505 | static bool intel_sdvo_read_response(struct intel_sdvo *intel_sdvo, |
@@ -1258,7 +1270,7 @@ intel_sdvo_get_analog_edid(struct drm_connector *connector) | |||
1258 | dev_priv->crt_ddc_pin)); | 1270 | dev_priv->crt_ddc_pin)); |
1259 | } | 1271 | } |
1260 | 1272 | ||
1261 | enum drm_connector_status | 1273 | static enum drm_connector_status |
1262 | intel_sdvo_tmds_sink_detect(struct drm_connector *connector) | 1274 | intel_sdvo_tmds_sink_detect(struct drm_connector *connector) |
1263 | { | 1275 | { |
1264 | struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); | 1276 | struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); |
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index a464771a7240..fbf03b996587 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c | |||
@@ -95,7 +95,6 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, | |||
95 | /* must disable */ | 95 | /* must disable */ |
96 | sprctl |= SPRITE_TRICKLE_FEED_DISABLE; | 96 | sprctl |= SPRITE_TRICKLE_FEED_DISABLE; |
97 | sprctl |= SPRITE_ENABLE; | 97 | sprctl |= SPRITE_ENABLE; |
98 | sprctl |= SPRITE_DEST_KEY; | ||
99 | 98 | ||
100 | /* Sizes are 0 based */ | 99 | /* Sizes are 0 based */ |
101 | src_w--; | 100 | src_w--; |
@@ -112,13 +111,13 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, | |||
112 | */ | 111 | */ |
113 | if (crtc_w != src_w || crtc_h != src_h) { | 112 | if (crtc_w != src_w || crtc_h != src_h) { |
114 | dev_priv->sprite_scaling_enabled = true; | 113 | dev_priv->sprite_scaling_enabled = true; |
115 | sandybridge_update_wm(dev); | 114 | intel_update_watermarks(dev); |
116 | intel_wait_for_vblank(dev, pipe); | 115 | intel_wait_for_vblank(dev, pipe); |
117 | sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h; | 116 | sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h; |
118 | } else { | 117 | } else { |
119 | dev_priv->sprite_scaling_enabled = false; | 118 | dev_priv->sprite_scaling_enabled = false; |
120 | /* potentially re-enable LP watermarks */ | 119 | /* potentially re-enable LP watermarks */ |
121 | sandybridge_update_wm(dev); | 120 | intel_update_watermarks(dev); |
122 | } | 121 | } |
123 | 122 | ||
124 | I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]); | 123 | I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]); |
@@ -134,7 +133,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, | |||
134 | I915_WRITE(SPRSIZE(pipe), (crtc_h << 16) | crtc_w); | 133 | I915_WRITE(SPRSIZE(pipe), (crtc_h << 16) | crtc_w); |
135 | I915_WRITE(SPRSCALE(pipe), sprscale); | 134 | I915_WRITE(SPRSCALE(pipe), sprscale); |
136 | I915_WRITE(SPRCTL(pipe), sprctl); | 135 | I915_WRITE(SPRCTL(pipe), sprctl); |
137 | I915_WRITE(SPRSURF(pipe), obj->gtt_offset); | 136 | I915_MODIFY_DISPBASE(SPRSURF(pipe), obj->gtt_offset); |
138 | POSTING_READ(SPRSURF(pipe)); | 137 | POSTING_READ(SPRSURF(pipe)); |
139 | } | 138 | } |
140 | 139 | ||
@@ -150,7 +149,7 @@ ivb_disable_plane(struct drm_plane *plane) | |||
150 | /* Can't leave the scaler enabled... */ | 149 | /* Can't leave the scaler enabled... */ |
151 | I915_WRITE(SPRSCALE(pipe), 0); | 150 | I915_WRITE(SPRSCALE(pipe), 0); |
152 | /* Activate double buffered register update */ | 151 | /* Activate double buffered register update */ |
153 | I915_WRITE(SPRSURF(pipe), 0); | 152 | I915_MODIFY_DISPBASE(SPRSURF(pipe), 0); |
154 | POSTING_READ(SPRSURF(pipe)); | 153 | POSTING_READ(SPRSURF(pipe)); |
155 | } | 154 | } |
156 | 155 | ||
@@ -209,7 +208,7 @@ ivb_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key) | |||
209 | } | 208 | } |
210 | 209 | ||
211 | static void | 210 | static void |
212 | snb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, | 211 | ilk_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, |
213 | struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, | 212 | struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, |
214 | unsigned int crtc_w, unsigned int crtc_h, | 213 | unsigned int crtc_w, unsigned int crtc_h, |
215 | uint32_t x, uint32_t y, | 214 | uint32_t x, uint32_t y, |
@@ -219,7 +218,7 @@ snb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, | |||
219 | struct drm_i915_private *dev_priv = dev->dev_private; | 218 | struct drm_i915_private *dev_priv = dev->dev_private; |
220 | struct intel_plane *intel_plane = to_intel_plane(plane); | 219 | struct intel_plane *intel_plane = to_intel_plane(plane); |
221 | int pipe = intel_plane->pipe, pixel_size; | 220 | int pipe = intel_plane->pipe, pixel_size; |
222 | u32 dvscntr, dvsscale = 0; | 221 | u32 dvscntr, dvsscale; |
223 | 222 | ||
224 | dvscntr = I915_READ(DVSCNTR(pipe)); | 223 | dvscntr = I915_READ(DVSCNTR(pipe)); |
225 | 224 | ||
@@ -263,8 +262,8 @@ snb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, | |||
263 | if (obj->tiling_mode != I915_TILING_NONE) | 262 | if (obj->tiling_mode != I915_TILING_NONE) |
264 | dvscntr |= DVS_TILED; | 263 | dvscntr |= DVS_TILED; |
265 | 264 | ||
266 | /* must disable */ | 265 | if (IS_GEN6(dev)) |
267 | dvscntr |= DVS_TRICKLE_FEED_DISABLE; | 266 | dvscntr |= DVS_TRICKLE_FEED_DISABLE; /* must disable */ |
268 | dvscntr |= DVS_ENABLE; | 267 | dvscntr |= DVS_ENABLE; |
269 | 268 | ||
270 | /* Sizes are 0 based */ | 269 | /* Sizes are 0 based */ |
@@ -275,7 +274,8 @@ snb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, | |||
275 | 274 | ||
276 | intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size); | 275 | intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size); |
277 | 276 | ||
278 | if (crtc_w != src_w || crtc_h != src_h) | 277 | dvsscale = 0; |
278 | if (IS_GEN5(dev) || crtc_w != src_w || crtc_h != src_h) | ||
279 | dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h; | 279 | dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h; |
280 | 280 | ||
281 | I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]); | 281 | I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]); |
@@ -291,12 +291,12 @@ snb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, | |||
291 | I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w); | 291 | I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w); |
292 | I915_WRITE(DVSSCALE(pipe), dvsscale); | 292 | I915_WRITE(DVSSCALE(pipe), dvsscale); |
293 | I915_WRITE(DVSCNTR(pipe), dvscntr); | 293 | I915_WRITE(DVSCNTR(pipe), dvscntr); |
294 | I915_WRITE(DVSSURF(pipe), obj->gtt_offset); | 294 | I915_MODIFY_DISPBASE(DVSSURF(pipe), obj->gtt_offset); |
295 | POSTING_READ(DVSSURF(pipe)); | 295 | POSTING_READ(DVSSURF(pipe)); |
296 | } | 296 | } |
297 | 297 | ||
298 | static void | 298 | static void |
299 | snb_disable_plane(struct drm_plane *plane) | 299 | ilk_disable_plane(struct drm_plane *plane) |
300 | { | 300 | { |
301 | struct drm_device *dev = plane->dev; | 301 | struct drm_device *dev = plane->dev; |
302 | struct drm_i915_private *dev_priv = dev->dev_private; | 302 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -307,7 +307,7 @@ snb_disable_plane(struct drm_plane *plane) | |||
307 | /* Disable the scaler */ | 307 | /* Disable the scaler */ |
308 | I915_WRITE(DVSSCALE(pipe), 0); | 308 | I915_WRITE(DVSSCALE(pipe), 0); |
309 | /* Flush double buffered register updates */ | 309 | /* Flush double buffered register updates */ |
310 | I915_WRITE(DVSSURF(pipe), 0); | 310 | I915_MODIFY_DISPBASE(DVSSURF(pipe), 0); |
311 | POSTING_READ(DVSSURF(pipe)); | 311 | POSTING_READ(DVSSURF(pipe)); |
312 | } | 312 | } |
313 | 313 | ||
@@ -334,7 +334,7 @@ intel_disable_primary(struct drm_crtc *crtc) | |||
334 | } | 334 | } |
335 | 335 | ||
336 | static int | 336 | static int |
337 | snb_update_colorkey(struct drm_plane *plane, | 337 | ilk_update_colorkey(struct drm_plane *plane, |
338 | struct drm_intel_sprite_colorkey *key) | 338 | struct drm_intel_sprite_colorkey *key) |
339 | { | 339 | { |
340 | struct drm_device *dev = plane->dev; | 340 | struct drm_device *dev = plane->dev; |
@@ -363,7 +363,7 @@ snb_update_colorkey(struct drm_plane *plane, | |||
363 | } | 363 | } |
364 | 364 | ||
365 | static void | 365 | static void |
366 | snb_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key) | 366 | ilk_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key) |
367 | { | 367 | { |
368 | struct drm_device *dev = plane->dev; | 368 | struct drm_device *dev = plane->dev; |
369 | struct drm_i915_private *dev_priv = dev->dev_private; | 369 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -617,6 +617,14 @@ static const struct drm_plane_funcs intel_plane_funcs = { | |||
617 | .destroy = intel_destroy_plane, | 617 | .destroy = intel_destroy_plane, |
618 | }; | 618 | }; |
619 | 619 | ||
620 | static uint32_t ilk_plane_formats[] = { | ||
621 | DRM_FORMAT_XRGB8888, | ||
622 | DRM_FORMAT_YUYV, | ||
623 | DRM_FORMAT_YVYU, | ||
624 | DRM_FORMAT_UYVY, | ||
625 | DRM_FORMAT_VYUY, | ||
626 | }; | ||
627 | |||
620 | static uint32_t snb_plane_formats[] = { | 628 | static uint32_t snb_plane_formats[] = { |
621 | DRM_FORMAT_XBGR8888, | 629 | DRM_FORMAT_XBGR8888, |
622 | DRM_FORMAT_XRGB8888, | 630 | DRM_FORMAT_XRGB8888, |
@@ -631,34 +639,56 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe) | |||
631 | { | 639 | { |
632 | struct intel_plane *intel_plane; | 640 | struct intel_plane *intel_plane; |
633 | unsigned long possible_crtcs; | 641 | unsigned long possible_crtcs; |
642 | const uint32_t *plane_formats; | ||
643 | int num_plane_formats; | ||
634 | int ret; | 644 | int ret; |
635 | 645 | ||
636 | if (!(IS_GEN6(dev) || IS_GEN7(dev))) | 646 | if (INTEL_INFO(dev)->gen < 5) |
637 | return -ENODEV; | 647 | return -ENODEV; |
638 | 648 | ||
639 | intel_plane = kzalloc(sizeof(struct intel_plane), GFP_KERNEL); | 649 | intel_plane = kzalloc(sizeof(struct intel_plane), GFP_KERNEL); |
640 | if (!intel_plane) | 650 | if (!intel_plane) |
641 | return -ENOMEM; | 651 | return -ENOMEM; |
642 | 652 | ||
643 | if (IS_GEN6(dev)) { | 653 | switch (INTEL_INFO(dev)->gen) { |
654 | case 5: | ||
655 | case 6: | ||
644 | intel_plane->max_downscale = 16; | 656 | intel_plane->max_downscale = 16; |
645 | intel_plane->update_plane = snb_update_plane; | 657 | intel_plane->update_plane = ilk_update_plane; |
646 | intel_plane->disable_plane = snb_disable_plane; | 658 | intel_plane->disable_plane = ilk_disable_plane; |
647 | intel_plane->update_colorkey = snb_update_colorkey; | 659 | intel_plane->update_colorkey = ilk_update_colorkey; |
648 | intel_plane->get_colorkey = snb_get_colorkey; | 660 | intel_plane->get_colorkey = ilk_get_colorkey; |
649 | } else if (IS_GEN7(dev)) { | 661 | |
662 | if (IS_GEN6(dev)) { | ||
663 | plane_formats = snb_plane_formats; | ||
664 | num_plane_formats = ARRAY_SIZE(snb_plane_formats); | ||
665 | } else { | ||
666 | plane_formats = ilk_plane_formats; | ||
667 | num_plane_formats = ARRAY_SIZE(ilk_plane_formats); | ||
668 | } | ||
669 | break; | ||
670 | |||
671 | case 7: | ||
650 | intel_plane->max_downscale = 2; | 672 | intel_plane->max_downscale = 2; |
651 | intel_plane->update_plane = ivb_update_plane; | 673 | intel_plane->update_plane = ivb_update_plane; |
652 | intel_plane->disable_plane = ivb_disable_plane; | 674 | intel_plane->disable_plane = ivb_disable_plane; |
653 | intel_plane->update_colorkey = ivb_update_colorkey; | 675 | intel_plane->update_colorkey = ivb_update_colorkey; |
654 | intel_plane->get_colorkey = ivb_get_colorkey; | 676 | intel_plane->get_colorkey = ivb_get_colorkey; |
677 | |||
678 | plane_formats = snb_plane_formats; | ||
679 | num_plane_formats = ARRAY_SIZE(snb_plane_formats); | ||
680 | break; | ||
681 | |||
682 | default: | ||
683 | return -ENODEV; | ||
655 | } | 684 | } |
656 | 685 | ||
657 | intel_plane->pipe = pipe; | 686 | intel_plane->pipe = pipe; |
658 | possible_crtcs = (1 << pipe); | 687 | possible_crtcs = (1 << pipe); |
659 | ret = drm_plane_init(dev, &intel_plane->base, possible_crtcs, | 688 | ret = drm_plane_init(dev, &intel_plane->base, possible_crtcs, |
660 | &intel_plane_funcs, snb_plane_formats, | 689 | &intel_plane_funcs, |
661 | ARRAY_SIZE(snb_plane_formats), false); | 690 | plane_formats, num_plane_formats, |
691 | false); | ||
662 | if (ret) | 692 | if (ret) |
663 | kfree(intel_plane); | 693 | kfree(intel_plane); |
664 | 694 | ||
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index ca12c709f3eb..67f444d632fb 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
@@ -811,7 +811,7 @@ intel_tv_mode_lookup(const char *tv_format) | |||
811 | { | 811 | { |
812 | int i; | 812 | int i; |
813 | 813 | ||
814 | for (i = 0; i < sizeof(tv_modes) / sizeof(tv_modes[0]); i++) { | 814 | for (i = 0; i < ARRAY_SIZE(tv_modes); i++) { |
815 | const struct tv_mode *tv_mode = &tv_modes[i]; | 815 | const struct tv_mode *tv_mode = &tv_modes[i]; |
816 | 816 | ||
817 | if (!strcmp(tv_format, tv_mode->name)) | 817 | if (!strcmp(tv_format, tv_mode->name)) |
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index 06b209b2e229..b92a694caa0d 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c | |||
@@ -230,6 +230,10 @@ atombios_dvo_setup(struct drm_encoder *encoder, int action) | |||
230 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | 230 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) |
231 | return; | 231 | return; |
232 | 232 | ||
233 | /* some R4xx chips have the wrong frev */ | ||
234 | if (rdev->family <= CHIP_RV410) | ||
235 | frev = 1; | ||
236 | |||
233 | switch (frev) { | 237 | switch (frev) { |
234 | case 1: | 238 | case 1: |
235 | switch (crev) { | 239 | switch (crev) { |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index e11df778e194..cb1141854282 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -2557,7 +2557,7 @@ static void r100_pll_errata_after_data(struct radeon_device *rdev) | |||
2557 | * or the chip could hang on a subsequent access | 2557 | * or the chip could hang on a subsequent access |
2558 | */ | 2558 | */ |
2559 | if (rdev->pll_errata & CHIP_ERRATA_PLL_DELAY) { | 2559 | if (rdev->pll_errata & CHIP_ERRATA_PLL_DELAY) { |
2560 | udelay(5000); | 2560 | mdelay(5); |
2561 | } | 2561 | } |
2562 | 2562 | ||
2563 | /* This function is required to workaround a hardware bug in some (all?) | 2563 | /* This function is required to workaround a hardware bug in some (all?) |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 8f84bd67ce7f..222245d0138a 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -2839,7 +2839,7 @@ void r600_rlc_stop(struct radeon_device *rdev) | |||
2839 | /* r7xx asics need to soft reset RLC before halting */ | 2839 | /* r7xx asics need to soft reset RLC before halting */ |
2840 | WREG32(SRBM_SOFT_RESET, SOFT_RESET_RLC); | 2840 | WREG32(SRBM_SOFT_RESET, SOFT_RESET_RLC); |
2841 | RREG32(SRBM_SOFT_RESET); | 2841 | RREG32(SRBM_SOFT_RESET); |
2842 | udelay(15000); | 2842 | mdelay(15); |
2843 | WREG32(SRBM_SOFT_RESET, 0); | 2843 | WREG32(SRBM_SOFT_RESET, 0); |
2844 | RREG32(SRBM_SOFT_RESET); | 2844 | RREG32(SRBM_SOFT_RESET); |
2845 | } | 2845 | } |
diff --git a/drivers/gpu/drm/radeon/r600_cp.c b/drivers/gpu/drm/radeon/r600_cp.c index 84c546250955..75ed17c96115 100644 --- a/drivers/gpu/drm/radeon/r600_cp.c +++ b/drivers/gpu/drm/radeon/r600_cp.c | |||
@@ -407,7 +407,7 @@ static void r600_cp_load_microcode(drm_radeon_private_t *dev_priv) | |||
407 | 407 | ||
408 | RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); | 408 | RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); |
409 | RADEON_READ(R600_GRBM_SOFT_RESET); | 409 | RADEON_READ(R600_GRBM_SOFT_RESET); |
410 | DRM_UDELAY(15000); | 410 | mdelay(15); |
411 | RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); | 411 | RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); |
412 | 412 | ||
413 | fw_data = (const __be32 *)dev_priv->me_fw->data; | 413 | fw_data = (const __be32 *)dev_priv->me_fw->data; |
@@ -500,7 +500,7 @@ static void r700_cp_load_microcode(drm_radeon_private_t *dev_priv) | |||
500 | 500 | ||
501 | RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); | 501 | RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); |
502 | RADEON_READ(R600_GRBM_SOFT_RESET); | 502 | RADEON_READ(R600_GRBM_SOFT_RESET); |
503 | DRM_UDELAY(15000); | 503 | mdelay(15); |
504 | RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); | 504 | RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); |
505 | 505 | ||
506 | fw_data = (const __be32 *)dev_priv->pfp_fw->data; | 506 | fw_data = (const __be32 *)dev_priv->pfp_fw->data; |
@@ -1797,7 +1797,7 @@ static void r600_cp_init_ring_buffer(struct drm_device *dev, | |||
1797 | 1797 | ||
1798 | RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); | 1798 | RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); |
1799 | RADEON_READ(R600_GRBM_SOFT_RESET); | 1799 | RADEON_READ(R600_GRBM_SOFT_RESET); |
1800 | DRM_UDELAY(15000); | 1800 | mdelay(15); |
1801 | RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); | 1801 | RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); |
1802 | 1802 | ||
1803 | 1803 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_clocks.c b/drivers/gpu/drm/radeon/radeon_clocks.c index 6ae0c75f016a..9c6b29a41927 100644 --- a/drivers/gpu/drm/radeon/radeon_clocks.c +++ b/drivers/gpu/drm/radeon/radeon_clocks.c | |||
@@ -633,7 +633,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) | |||
633 | tmp &= ~(R300_SCLK_FORCE_VAP); | 633 | tmp &= ~(R300_SCLK_FORCE_VAP); |
634 | tmp |= RADEON_SCLK_FORCE_CP; | 634 | tmp |= RADEON_SCLK_FORCE_CP; |
635 | WREG32_PLL(RADEON_SCLK_CNTL, tmp); | 635 | WREG32_PLL(RADEON_SCLK_CNTL, tmp); |
636 | udelay(15000); | 636 | mdelay(15); |
637 | 637 | ||
638 | tmp = RREG32_PLL(R300_SCLK_CNTL2); | 638 | tmp = RREG32_PLL(R300_SCLK_CNTL2); |
639 | tmp &= ~(R300_SCLK_FORCE_TCL | | 639 | tmp &= ~(R300_SCLK_FORCE_TCL | |
@@ -651,12 +651,12 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) | |||
651 | tmp |= (RADEON_ENGIN_DYNCLK_MODE | | 651 | tmp |= (RADEON_ENGIN_DYNCLK_MODE | |
652 | (0x01 << RADEON_ACTIVE_HILO_LAT_SHIFT)); | 652 | (0x01 << RADEON_ACTIVE_HILO_LAT_SHIFT)); |
653 | WREG32_PLL(RADEON_CLK_PWRMGT_CNTL, tmp); | 653 | WREG32_PLL(RADEON_CLK_PWRMGT_CNTL, tmp); |
654 | udelay(15000); | 654 | mdelay(15); |
655 | 655 | ||
656 | tmp = RREG32_PLL(RADEON_CLK_PIN_CNTL); | 656 | tmp = RREG32_PLL(RADEON_CLK_PIN_CNTL); |
657 | tmp |= RADEON_SCLK_DYN_START_CNTL; | 657 | tmp |= RADEON_SCLK_DYN_START_CNTL; |
658 | WREG32_PLL(RADEON_CLK_PIN_CNTL, tmp); | 658 | WREG32_PLL(RADEON_CLK_PIN_CNTL, tmp); |
659 | udelay(15000); | 659 | mdelay(15); |
660 | 660 | ||
661 | /* When DRI is enabled, setting DYN_STOP_LAT to zero can cause some R200 | 661 | /* When DRI is enabled, setting DYN_STOP_LAT to zero can cause some R200 |
662 | to lockup randomly, leave them as set by BIOS. | 662 | to lockup randomly, leave them as set by BIOS. |
@@ -696,7 +696,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) | |||
696 | tmp |= RADEON_SCLK_MORE_FORCEON; | 696 | tmp |= RADEON_SCLK_MORE_FORCEON; |
697 | } | 697 | } |
698 | WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp); | 698 | WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp); |
699 | udelay(15000); | 699 | mdelay(15); |
700 | } | 700 | } |
701 | 701 | ||
702 | /* RV200::A11 A12, RV250::A11 A12 */ | 702 | /* RV200::A11 A12, RV250::A11 A12 */ |
@@ -709,7 +709,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) | |||
709 | tmp |= RADEON_TCL_BYPASS_DISABLE; | 709 | tmp |= RADEON_TCL_BYPASS_DISABLE; |
710 | WREG32_PLL(RADEON_PLL_PWRMGT_CNTL, tmp); | 710 | WREG32_PLL(RADEON_PLL_PWRMGT_CNTL, tmp); |
711 | } | 711 | } |
712 | udelay(15000); | 712 | mdelay(15); |
713 | 713 | ||
714 | /*enable dynamic mode for display clocks (PIXCLK and PIX2CLK) */ | 714 | /*enable dynamic mode for display clocks (PIXCLK and PIX2CLK) */ |
715 | tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL); | 715 | tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL); |
@@ -722,14 +722,14 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) | |||
722 | RADEON_PIXCLK_TMDS_ALWAYS_ONb); | 722 | RADEON_PIXCLK_TMDS_ALWAYS_ONb); |
723 | 723 | ||
724 | WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); | 724 | WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); |
725 | udelay(15000); | 725 | mdelay(15); |
726 | 726 | ||
727 | tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL); | 727 | tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL); |
728 | tmp |= (RADEON_PIXCLK_ALWAYS_ONb | | 728 | tmp |= (RADEON_PIXCLK_ALWAYS_ONb | |
729 | RADEON_PIXCLK_DAC_ALWAYS_ONb); | 729 | RADEON_PIXCLK_DAC_ALWAYS_ONb); |
730 | 730 | ||
731 | WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp); | 731 | WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp); |
732 | udelay(15000); | 732 | mdelay(15); |
733 | } | 733 | } |
734 | } else { | 734 | } else { |
735 | /* Turn everything OFF (ForceON to everything) */ | 735 | /* Turn everything OFF (ForceON to everything) */ |
@@ -861,7 +861,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) | |||
861 | } | 861 | } |
862 | WREG32_PLL(RADEON_SCLK_CNTL, tmp); | 862 | WREG32_PLL(RADEON_SCLK_CNTL, tmp); |
863 | 863 | ||
864 | udelay(16000); | 864 | mdelay(16); |
865 | 865 | ||
866 | if ((rdev->family == CHIP_R300) || | 866 | if ((rdev->family == CHIP_R300) || |
867 | (rdev->family == CHIP_R350)) { | 867 | (rdev->family == CHIP_R350)) { |
@@ -870,7 +870,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) | |||
870 | R300_SCLK_FORCE_GA | | 870 | R300_SCLK_FORCE_GA | |
871 | R300_SCLK_FORCE_CBA); | 871 | R300_SCLK_FORCE_CBA); |
872 | WREG32_PLL(R300_SCLK_CNTL2, tmp); | 872 | WREG32_PLL(R300_SCLK_CNTL2, tmp); |
873 | udelay(16000); | 873 | mdelay(16); |
874 | } | 874 | } |
875 | 875 | ||
876 | if (rdev->flags & RADEON_IS_IGP) { | 876 | if (rdev->flags & RADEON_IS_IGP) { |
@@ -878,7 +878,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) | |||
878 | tmp &= ~(RADEON_FORCEON_MCLKA | | 878 | tmp &= ~(RADEON_FORCEON_MCLKA | |
879 | RADEON_FORCEON_YCLKA); | 879 | RADEON_FORCEON_YCLKA); |
880 | WREG32_PLL(RADEON_MCLK_CNTL, tmp); | 880 | WREG32_PLL(RADEON_MCLK_CNTL, tmp); |
881 | udelay(16000); | 881 | mdelay(16); |
882 | } | 882 | } |
883 | 883 | ||
884 | if ((rdev->family == CHIP_RV200) || | 884 | if ((rdev->family == CHIP_RV200) || |
@@ -887,7 +887,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) | |||
887 | tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL); | 887 | tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL); |
888 | tmp |= RADEON_SCLK_MORE_FORCEON; | 888 | tmp |= RADEON_SCLK_MORE_FORCEON; |
889 | WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp); | 889 | WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp); |
890 | udelay(16000); | 890 | mdelay(16); |
891 | } | 891 | } |
892 | 892 | ||
893 | tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL); | 893 | tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL); |
@@ -900,7 +900,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) | |||
900 | RADEON_PIXCLK_TMDS_ALWAYS_ONb); | 900 | RADEON_PIXCLK_TMDS_ALWAYS_ONb); |
901 | 901 | ||
902 | WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); | 902 | WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); |
903 | udelay(16000); | 903 | mdelay(16); |
904 | 904 | ||
905 | tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL); | 905 | tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL); |
906 | tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb | | 906 | tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb | |
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 81fc100be7e1..2cad9fde92fc 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
@@ -2845,7 +2845,7 @@ bool radeon_combios_external_tmds_setup(struct drm_encoder *encoder) | |||
2845 | case 4: | 2845 | case 4: |
2846 | val = RBIOS16(index); | 2846 | val = RBIOS16(index); |
2847 | index += 2; | 2847 | index += 2; |
2848 | udelay(val * 1000); | 2848 | mdelay(val); |
2849 | break; | 2849 | break; |
2850 | case 6: | 2850 | case 6: |
2851 | slave_addr = id & 0xff; | 2851 | slave_addr = id & 0xff; |
@@ -3044,7 +3044,7 @@ static void combios_parse_pll_table(struct drm_device *dev, uint16_t offset) | |||
3044 | udelay(150); | 3044 | udelay(150); |
3045 | break; | 3045 | break; |
3046 | case 2: | 3046 | case 2: |
3047 | udelay(1000); | 3047 | mdelay(1); |
3048 | break; | 3048 | break; |
3049 | case 3: | 3049 | case 3: |
3050 | while (tmp--) { | 3050 | while (tmp--) { |
@@ -3075,13 +3075,13 @@ static void combios_parse_pll_table(struct drm_device *dev, uint16_t offset) | |||
3075 | /*mclk_cntl |= 0x00001111;*//* ??? */ | 3075 | /*mclk_cntl |= 0x00001111;*//* ??? */ |
3076 | WREG32_PLL(RADEON_MCLK_CNTL, | 3076 | WREG32_PLL(RADEON_MCLK_CNTL, |
3077 | mclk_cntl); | 3077 | mclk_cntl); |
3078 | udelay(10000); | 3078 | mdelay(10); |
3079 | #endif | 3079 | #endif |
3080 | WREG32_PLL | 3080 | WREG32_PLL |
3081 | (RADEON_CLK_PWRMGT_CNTL, | 3081 | (RADEON_CLK_PWRMGT_CNTL, |
3082 | tmp & | 3082 | tmp & |
3083 | ~RADEON_CG_NO1_DEBUG_0); | 3083 | ~RADEON_CG_NO1_DEBUG_0); |
3084 | udelay(10000); | 3084 | mdelay(10); |
3085 | } | 3085 | } |
3086 | break; | 3086 | break; |
3087 | default: | 3087 | default: |
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index 85bcfc8923a7..3edec1c198e3 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c | |||
@@ -900,6 +900,10 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, | |||
900 | struct radeon_i2c_chan *i2c; | 900 | struct radeon_i2c_chan *i2c; |
901 | int ret; | 901 | int ret; |
902 | 902 | ||
903 | /* don't add the mm_i2c bus unless hw_i2c is enabled */ | ||
904 | if (rec->mm_i2c && (radeon_hw_i2c == 0)) | ||
905 | return NULL; | ||
906 | |||
903 | i2c = kzalloc(sizeof(struct radeon_i2c_chan), GFP_KERNEL); | 907 | i2c = kzalloc(sizeof(struct radeon_i2c_chan), GFP_KERNEL); |
904 | if (i2c == NULL) | 908 | if (i2c == NULL) |
905 | return NULL; | 909 | return NULL; |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index 2f46e0c8df53..42db254f6bb0 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c | |||
@@ -88,7 +88,7 @@ static void radeon_legacy_lvds_update(struct drm_encoder *encoder, int mode) | |||
88 | lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL); | 88 | lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL); |
89 | lvds_pll_cntl |= RADEON_LVDS_PLL_EN; | 89 | lvds_pll_cntl |= RADEON_LVDS_PLL_EN; |
90 | WREG32(RADEON_LVDS_PLL_CNTL, lvds_pll_cntl); | 90 | WREG32(RADEON_LVDS_PLL_CNTL, lvds_pll_cntl); |
91 | udelay(1000); | 91 | mdelay(1); |
92 | 92 | ||
93 | lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL); | 93 | lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL); |
94 | lvds_pll_cntl &= ~RADEON_LVDS_PLL_RESET; | 94 | lvds_pll_cntl &= ~RADEON_LVDS_PLL_RESET; |
@@ -101,7 +101,7 @@ static void radeon_legacy_lvds_update(struct drm_encoder *encoder, int mode) | |||
101 | (backlight_level << RADEON_LVDS_BL_MOD_LEVEL_SHIFT)); | 101 | (backlight_level << RADEON_LVDS_BL_MOD_LEVEL_SHIFT)); |
102 | if (is_mac) | 102 | if (is_mac) |
103 | lvds_gen_cntl |= RADEON_LVDS_BL_MOD_EN; | 103 | lvds_gen_cntl |= RADEON_LVDS_BL_MOD_EN; |
104 | udelay(panel_pwr_delay * 1000); | 104 | mdelay(panel_pwr_delay); |
105 | WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); | 105 | WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); |
106 | break; | 106 | break; |
107 | case DRM_MODE_DPMS_STANDBY: | 107 | case DRM_MODE_DPMS_STANDBY: |
@@ -118,10 +118,10 @@ static void radeon_legacy_lvds_update(struct drm_encoder *encoder, int mode) | |||
118 | WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); | 118 | WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); |
119 | lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN | RADEON_LVDS_DIGON); | 119 | lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN | RADEON_LVDS_DIGON); |
120 | } | 120 | } |
121 | udelay(panel_pwr_delay * 1000); | 121 | mdelay(panel_pwr_delay); |
122 | WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); | 122 | WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); |
123 | WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); | 123 | WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); |
124 | udelay(panel_pwr_delay * 1000); | 124 | mdelay(panel_pwr_delay); |
125 | break; | 125 | break; |
126 | } | 126 | } |
127 | 127 | ||
@@ -656,7 +656,7 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc | |||
656 | 656 | ||
657 | WREG32(RADEON_DAC_MACRO_CNTL, tmp); | 657 | WREG32(RADEON_DAC_MACRO_CNTL, tmp); |
658 | 658 | ||
659 | udelay(2000); | 659 | mdelay(2); |
660 | 660 | ||
661 | if (RREG32(RADEON_DAC_CNTL) & RADEON_DAC_CMP_OUTPUT) | 661 | if (RREG32(RADEON_DAC_CNTL) & RADEON_DAC_CMP_OUTPUT) |
662 | found = connector_status_connected; | 662 | found = connector_status_connected; |
@@ -1499,7 +1499,7 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder | |||
1499 | tmp = dac_cntl2 | RADEON_DAC2_DAC2_CLK_SEL | RADEON_DAC2_CMP_EN; | 1499 | tmp = dac_cntl2 | RADEON_DAC2_DAC2_CLK_SEL | RADEON_DAC2_CMP_EN; |
1500 | WREG32(RADEON_DAC_CNTL2, tmp); | 1500 | WREG32(RADEON_DAC_CNTL2, tmp); |
1501 | 1501 | ||
1502 | udelay(10000); | 1502 | mdelay(10); |
1503 | 1503 | ||
1504 | if (ASIC_IS_R300(rdev)) { | 1504 | if (ASIC_IS_R300(rdev)) { |
1505 | if (RREG32(RADEON_DAC_CNTL2) & RADEON_DAC2_CMP_OUT_B) | 1505 | if (RREG32(RADEON_DAC_CNTL2) & RADEON_DAC2_CMP_OUT_B) |
diff --git a/drivers/gpu/drm/savage/savage_state.c b/drivers/gpu/drm/savage/savage_state.c index 031aaaf79ac2..b6d8608375cd 100644 --- a/drivers/gpu/drm/savage/savage_state.c +++ b/drivers/gpu/drm/savage/savage_state.c | |||
@@ -988,7 +988,7 @@ int savage_bci_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_ | |||
988 | * for locking on FreeBSD. | 988 | * for locking on FreeBSD. |
989 | */ | 989 | */ |
990 | if (cmdbuf->size) { | 990 | if (cmdbuf->size) { |
991 | kcmd_addr = kmalloc(cmdbuf->size * 8, GFP_KERNEL); | 991 | kcmd_addr = kmalloc_array(cmdbuf->size, 8, GFP_KERNEL); |
992 | if (kcmd_addr == NULL) | 992 | if (kcmd_addr == NULL) |
993 | return -ENOMEM; | 993 | return -ENOMEM; |
994 | 994 | ||
@@ -1015,8 +1015,8 @@ int savage_bci_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_ | |||
1015 | cmdbuf->vb_addr = kvb_addr; | 1015 | cmdbuf->vb_addr = kvb_addr; |
1016 | } | 1016 | } |
1017 | if (cmdbuf->nbox) { | 1017 | if (cmdbuf->nbox) { |
1018 | kbox_addr = kmalloc(cmdbuf->nbox * sizeof(struct drm_clip_rect), | 1018 | kbox_addr = kmalloc_array(cmdbuf->nbox, sizeof(struct drm_clip_rect), |
1019 | GFP_KERNEL); | 1019 | GFP_KERNEL); |
1020 | if (kbox_addr == NULL) { | 1020 | if (kbox_addr == NULL) { |
1021 | ret = -ENOMEM; | 1021 | ret = -ENOMEM; |
1022 | goto done; | 1022 | goto done; |