diff --git a/Documentation/driver-api/device-io.rst b/Documentation/driver-api/device-io.rst index e9f04b1815d1..4d2baac0311c 100644 --- a/Documentation/driver-api/device-io.rst +++ b/Documentation/driver-api/device-io.rst @@ -502,6 +502,15 @@ pcim_iomap() Not using these wrappers may make drivers unusable on certain platforms with stricter rules for mapping I/O memory. +Generalizing Access to System and I/O Memory +============================================ + +.. kernel-doc:: include/linux/iosys-map.h + :doc: overview + +.. kernel-doc:: include/linux/iosys-map.h + :internal: + Public Functions Provided ========================= diff --git a/Documentation/driver-api/dma-buf.rst b/Documentation/driver-api/dma-buf.rst index 2cd7db82d9fe..55006678394a 100644 --- a/Documentation/driver-api/dma-buf.rst +++ b/Documentation/driver-api/dma-buf.rst @@ -128,15 +128,6 @@ Kernel Functions and Structures Reference .. kernel-doc:: include/linux/dma-buf.h :internal: -Buffer Mapping Helpers -~~~~~~~~~~~~~~~~~~~~~~ - -.. kernel-doc:: include/linux/dma-buf-map.h - :doc: overview - -.. kernel-doc:: include/linux/dma-buf-map.h - :internal: - Reservation Objects ------------------- diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst index 1b2372ef4131..ee842606e883 100644 --- a/Documentation/gpu/todo.rst +++ b/Documentation/gpu/todo.rst @@ -222,7 +222,7 @@ Convert drivers to use drm_fbdev_generic_setup() Most drivers can use drm_fbdev_generic_setup(). Driver have to implement atomic modesetting and GEM vmap support. Historically, generic fbdev emulation expected the framebuffer in system memory or system-like memory. By employing -struct dma_buf_map, drivers with frambuffers in I/O memory can be supported +struct iosys_map, drivers with frambuffers in I/O memory can be supported as well. Contact: Maintainer of the driver you plan to convert @@ -234,7 +234,7 @@ Reimplement functions in drm_fbdev_fb_ops without fbdev A number of callback functions in drm_fbdev_fb_ops could benefit from being rewritten without dependencies on the fbdev module. Some of the -helpers could further benefit from using struct dma_buf_map instead of +helpers could further benefit from using struct iosys_map instead of raw pointers. Contact: Thomas Zimmermann , Daniel Vetter @@ -434,19 +434,19 @@ Contact: Emil Velikov, respective driver maintainers Level: Intermediate -Use struct dma_buf_map throughout codebase ------------------------------------------- +Use struct iosys_map throughout codebase +---------------------------------------- -Pointers to shared device memory are stored in struct dma_buf_map. Each +Pointers to shared device memory are stored in struct iosys_map. Each instance knows whether it refers to system or I/O memory. Most of the DRM-wide -interface have been converted to use struct dma_buf_map, but implementations +interface have been converted to use struct iosys_map, but implementations often still use raw pointers. -The task is to use struct dma_buf_map where it makes sense. +The task is to use struct iosys_map where it makes sense. -* Memory managers should use struct dma_buf_map for dma-buf-imported buffers. -* TTM might benefit from using struct dma_buf_map internally. -* Framebuffer copying and blitting helpers should operate on struct dma_buf_map. +* Memory managers should use struct iosys_map for dma-buf-imported buffers. +* TTM might benefit from using struct iosys_map internally. +* Framebuffer copying and blitting helpers should operate on struct iosys_map. Contact: Thomas Zimmermann , Christian König, Daniel Vetter diff --git a/MAINTAINERS b/MAINTAINERS index f41088418aae..1a18eafee497 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5734,7 +5734,7 @@ T: git git://anongit.freedesktop.org/drm/drm-misc F: Documentation/driver-api/dma-buf.rst F: drivers/dma-buf/ F: include/linux/*fence.h -F: include/linux/dma-buf* +F: include/linux/dma-buf.h F: include/linux/dma-resv.h K: \bdma_(?:buf|fence|resv)\b @@ -10050,6 +10050,13 @@ F: include/linux/iova.h F: include/linux/of_iommu.h F: include/uapi/linux/iommu.h +IOSYS-MAP HELPERS +M: Thomas Zimmermann +L: dri-devel@lists.freedesktop.org +S: Maintained +T: git git://anongit.freedesktop.org/drm/drm-misc +F: include/linux/iosys-map.h + IO_URING M: Jens Axboe R: Pavel Begunkov diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c index dc7da08bc700..bd6dad83c65b 100644 --- a/arch/x86/kernel/early-quirks.c +++ b/arch/x86/kernel/early-quirks.c @@ -555,6 +555,7 @@ static const struct pci_device_id intel_early_ids[] __initconst = { INTEL_RKL_IDS(&gen11_early_ops), INTEL_ADLS_IDS(&gen11_early_ops), INTEL_ADLP_IDS(&gen11_early_ops), + INTEL_ADLN_IDS(&gen11_early_ops), INTEL_RPLS_IDS(&gen11_early_ops), }; diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index 602b12d7470d..df23239b04fc 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -1047,8 +1047,8 @@ EXPORT_SYMBOL_NS_GPL(dma_buf_move_notify, DMA_BUF); * * Interfaces:: * - * void \*dma_buf_vmap(struct dma_buf \*dmabuf, struct dma_buf_map \*map) - * void dma_buf_vunmap(struct dma_buf \*dmabuf, struct dma_buf_map \*map) + * void \*dma_buf_vmap(struct dma_buf \*dmabuf, struct iosys_map \*map) + * void dma_buf_vunmap(struct dma_buf \*dmabuf, struct iosys_map \*map) * * The vmap call can fail if there is no vmap support in the exporter, or if * it runs out of vmalloc space. Note that the dma-buf layer keeps a reference @@ -1260,12 +1260,12 @@ EXPORT_SYMBOL_NS_GPL(dma_buf_mmap, DMA_BUF); * * Returns 0 on success, or a negative errno code otherwise. */ -int dma_buf_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map) +int dma_buf_vmap(struct dma_buf *dmabuf, struct iosys_map *map) { - struct dma_buf_map ptr; + struct iosys_map ptr; int ret = 0; - dma_buf_map_clear(map); + iosys_map_clear(map); if (WARN_ON(!dmabuf)) return -EINVAL; @@ -1276,12 +1276,12 @@ int dma_buf_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map) mutex_lock(&dmabuf->lock); if (dmabuf->vmapping_counter) { dmabuf->vmapping_counter++; - BUG_ON(dma_buf_map_is_null(&dmabuf->vmap_ptr)); + BUG_ON(iosys_map_is_null(&dmabuf->vmap_ptr)); *map = dmabuf->vmap_ptr; goto out_unlock; } - BUG_ON(dma_buf_map_is_set(&dmabuf->vmap_ptr)); + BUG_ON(iosys_map_is_set(&dmabuf->vmap_ptr)); ret = dmabuf->ops->vmap(dmabuf, &ptr); if (WARN_ON_ONCE(ret)) @@ -1303,20 +1303,20 @@ EXPORT_SYMBOL_NS_GPL(dma_buf_vmap, DMA_BUF); * @dmabuf: [in] buffer to vunmap * @map: [in] vmap pointer to vunmap */ -void dma_buf_vunmap(struct dma_buf *dmabuf, struct dma_buf_map *map) +void dma_buf_vunmap(struct dma_buf *dmabuf, struct iosys_map *map) { if (WARN_ON(!dmabuf)) return; - BUG_ON(dma_buf_map_is_null(&dmabuf->vmap_ptr)); + BUG_ON(iosys_map_is_null(&dmabuf->vmap_ptr)); BUG_ON(dmabuf->vmapping_counter == 0); - BUG_ON(!dma_buf_map_is_equal(&dmabuf->vmap_ptr, map)); + BUG_ON(!iosys_map_is_equal(&dmabuf->vmap_ptr, map)); mutex_lock(&dmabuf->lock); if (--dmabuf->vmapping_counter == 0) { if (dmabuf->ops->vunmap) dmabuf->ops->vunmap(dmabuf, map); - dma_buf_map_clear(&dmabuf->vmap_ptr); + iosys_map_clear(&dmabuf->vmap_ptr); } mutex_unlock(&dmabuf->lock); } diff --git a/drivers/dma-buf/heaps/cma_heap.c b/drivers/dma-buf/heaps/cma_heap.c index 83f02bd51dda..28fb04eccdd0 100644 --- a/drivers/dma-buf/heaps/cma_heap.c +++ b/drivers/dma-buf/heaps/cma_heap.c @@ -202,7 +202,7 @@ static void *cma_heap_do_vmap(struct cma_heap_buffer *buffer) return vaddr; } -static int cma_heap_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map) +static int cma_heap_vmap(struct dma_buf *dmabuf, struct iosys_map *map) { struct cma_heap_buffer *buffer = dmabuf->priv; void *vaddr; @@ -211,7 +211,7 @@ static int cma_heap_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map) mutex_lock(&buffer->lock); if (buffer->vmap_cnt) { buffer->vmap_cnt++; - dma_buf_map_set_vaddr(map, buffer->vaddr); + iosys_map_set_vaddr(map, buffer->vaddr); goto out; } @@ -222,14 +222,14 @@ static int cma_heap_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map) } buffer->vaddr = vaddr; buffer->vmap_cnt++; - dma_buf_map_set_vaddr(map, buffer->vaddr); + iosys_map_set_vaddr(map, buffer->vaddr); out: mutex_unlock(&buffer->lock); return ret; } -static void cma_heap_vunmap(struct dma_buf *dmabuf, struct dma_buf_map *map) +static void cma_heap_vunmap(struct dma_buf *dmabuf, struct iosys_map *map) { struct cma_heap_buffer *buffer = dmabuf->priv; @@ -239,7 +239,7 @@ static void cma_heap_vunmap(struct dma_buf *dmabuf, struct dma_buf_map *map) buffer->vaddr = NULL; } mutex_unlock(&buffer->lock); - dma_buf_map_clear(map); + iosys_map_clear(map); } static void cma_heap_dma_buf_release(struct dma_buf *dmabuf) diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c index ab7fd896d2c4..fcf836ba9c1f 100644 --- a/drivers/dma-buf/heaps/system_heap.c +++ b/drivers/dma-buf/heaps/system_heap.c @@ -241,7 +241,7 @@ static void *system_heap_do_vmap(struct system_heap_buffer *buffer) return vaddr; } -static int system_heap_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map) +static int system_heap_vmap(struct dma_buf *dmabuf, struct iosys_map *map) { struct system_heap_buffer *buffer = dmabuf->priv; void *vaddr; @@ -250,7 +250,7 @@ static int system_heap_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map) mutex_lock(&buffer->lock); if (buffer->vmap_cnt) { buffer->vmap_cnt++; - dma_buf_map_set_vaddr(map, buffer->vaddr); + iosys_map_set_vaddr(map, buffer->vaddr); goto out; } @@ -262,14 +262,14 @@ static int system_heap_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map) buffer->vaddr = vaddr; buffer->vmap_cnt++; - dma_buf_map_set_vaddr(map, buffer->vaddr); + iosys_map_set_vaddr(map, buffer->vaddr); out: mutex_unlock(&buffer->lock); return ret; } -static void system_heap_vunmap(struct dma_buf *dmabuf, struct dma_buf_map *map) +static void system_heap_vunmap(struct dma_buf *dmabuf, struct iosys_map *map) { struct system_heap_buffer *buffer = dmabuf->priv; @@ -279,7 +279,7 @@ static void system_heap_vunmap(struct dma_buf *dmabuf, struct dma_buf_map *map) buffer->vaddr = NULL; } mutex_unlock(&buffer->lock); - dma_buf_map_clear(map); + iosys_map_clear(map); } static void system_heap_dma_buf_release(struct dma_buf *dmabuf) diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index 00bfa41ff7cb..9c8d56b0a41b 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -107,7 +107,7 @@ struct ast_cursor_plane { struct { struct drm_gem_vram_object *gbo; - struct dma_buf_map map; + struct iosys_map map; u64 off; } hwc[AST_DEFAULT_HWC_NUM]; diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index ab52efb15670..2c7115a4d81f 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -804,11 +804,11 @@ ast_cursor_plane_helper_atomic_update(struct drm_plane *plane, struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(new_state); struct drm_framebuffer *fb = new_state->fb; struct ast_private *ast = to_ast_private(plane->dev); - struct dma_buf_map dst_map = + struct iosys_map dst_map = ast_cursor_plane->hwc[ast_cursor_plane->next_hwc_index].map; u64 dst_off = ast_cursor_plane->hwc[ast_cursor_plane->next_hwc_index].off; - struct dma_buf_map src_map = shadow_plane_state->data[0]; + struct iosys_map src_map = shadow_plane_state->data[0]; unsigned int offset_x, offset_y; u16 x, y; u8 x_offset, y_offset; @@ -886,7 +886,7 @@ static void ast_cursor_plane_destroy(struct drm_plane *plane) struct ast_cursor_plane *ast_cursor_plane = to_ast_cursor_plane(plane); size_t i; struct drm_gem_vram_object *gbo; - struct dma_buf_map map; + struct iosys_map map; for (i = 0; i < ARRAY_SIZE(ast_cursor_plane->hwc); ++i) { gbo = ast_cursor_plane->hwc[i].gbo; @@ -913,7 +913,7 @@ static int ast_cursor_plane_init(struct ast_private *ast) struct drm_plane *cursor_plane = &ast_cursor_plane->base; size_t size, i; struct drm_gem_vram_object *gbo; - struct dma_buf_map map; + struct iosys_map map; int ret; s64 off; diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c index f19d9acbe959..4bb093ccf1b8 100644 --- a/drivers/gpu/drm/drm_cache.c +++ b/drivers/gpu/drm/drm_cache.c @@ -28,10 +28,10 @@ * Authors: Thomas Hellström */ -#include +#include #include #include -#include +#include #include #include @@ -214,14 +214,14 @@ bool drm_need_swiotlb(int dma_bits) } EXPORT_SYMBOL(drm_need_swiotlb); -static void memcpy_fallback(struct dma_buf_map *dst, - const struct dma_buf_map *src, +static void memcpy_fallback(struct iosys_map *dst, + const struct iosys_map *src, unsigned long len) { if (!dst->is_iomem && !src->is_iomem) { memcpy(dst->vaddr, src->vaddr, len); } else if (!src->is_iomem) { - dma_buf_map_memcpy_to(dst, src->vaddr, len); + iosys_map_memcpy_to(dst, src->vaddr, len); } else if (!dst->is_iomem) { memcpy_fromio(dst->vaddr, src->vaddr_iomem, len); } else { @@ -305,8 +305,8 @@ static void __drm_memcpy_from_wc(void *dst, const void *src, unsigned long len) * Tries an arch optimized memcpy for prefetching reading out of a WC region, * and if no such beast is available, falls back to a normal memcpy. */ -void drm_memcpy_from_wc(struct dma_buf_map *dst, - const struct dma_buf_map *src, +void drm_memcpy_from_wc(struct iosys_map *dst, + const struct iosys_map *src, unsigned long len) { if (WARN_ON(in_interrupt())) { @@ -343,8 +343,8 @@ void drm_memcpy_init_early(void) static_branch_enable(&has_movntdqa); } #else -void drm_memcpy_from_wc(struct dma_buf_map *dst, - const struct dma_buf_map *src, +void drm_memcpy_from_wc(struct iosys_map *dst, + const struct iosys_map *src, unsigned long len) { WARN_ON(in_interrupt()); diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c index ce45e380f4a2..af3b7395bf69 100644 --- a/drivers/gpu/drm/drm_client.c +++ b/drivers/gpu/drm/drm_client.c @@ -3,7 +3,7 @@ * Copyright 2018 Noralf Trønnes */ -#include +#include #include #include #include @@ -309,9 +309,10 @@ err_delete: * 0 on success, or a negative errno code otherwise. */ int -drm_client_buffer_vmap(struct drm_client_buffer *buffer, struct dma_buf_map *map_copy) +drm_client_buffer_vmap(struct drm_client_buffer *buffer, + struct iosys_map *map_copy) { - struct dma_buf_map *map = &buffer->map; + struct iosys_map *map = &buffer->map; int ret; /* @@ -342,7 +343,7 @@ EXPORT_SYMBOL(drm_client_buffer_vmap); */ void drm_client_buffer_vunmap(struct drm_client_buffer *buffer) { - struct dma_buf_map *map = &buffer->map; + struct iosys_map *map = &buffer->map; drm_gem_vunmap(buffer->gem, map); } diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index ed43b987d306..e9a9d35fbf5e 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -373,7 +373,7 @@ static void drm_fb_helper_resume_worker(struct work_struct *work) static void drm_fb_helper_damage_blit_real(struct drm_fb_helper *fb_helper, struct drm_clip_rect *clip, - struct dma_buf_map *dst) + struct iosys_map *dst) { struct drm_framebuffer *fb = fb_helper->fb; unsigned int cpp = fb->format->cpp[0]; @@ -382,11 +382,11 @@ static void drm_fb_helper_damage_blit_real(struct drm_fb_helper *fb_helper, size_t len = (clip->x2 - clip->x1) * cpp; unsigned int y; - dma_buf_map_incr(dst, offset); /* go to first pixel within clip rect */ + iosys_map_incr(dst, offset); /* go to first pixel within clip rect */ for (y = clip->y1; y < clip->y2; y++) { - dma_buf_map_memcpy_to(dst, src, len); - dma_buf_map_incr(dst, fb->pitches[0]); + iosys_map_memcpy_to(dst, src, len); + iosys_map_incr(dst, fb->pitches[0]); src += fb->pitches[0]; } } @@ -395,7 +395,7 @@ static int drm_fb_helper_damage_blit(struct drm_fb_helper *fb_helper, struct drm_clip_rect *clip) { struct drm_client_buffer *buffer = fb_helper->buffer; - struct dma_buf_map map, dst; + struct iosys_map map, dst; int ret; /* @@ -2322,7 +2322,7 @@ static int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper, struct drm_framebuffer *fb; struct fb_info *fbi; u32 format; - struct dma_buf_map map; + struct iosys_map map; int ret; drm_dbg_kms(dev, "surface width(%d), height(%d) and bpp(%d)\n", diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 4dcdec6487bb..8c7b24f4b0e4 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include @@ -1165,7 +1165,7 @@ void drm_gem_unpin(struct drm_gem_object *obj) obj->funcs->unpin(obj); } -int drm_gem_vmap(struct drm_gem_object *obj, struct dma_buf_map *map) +int drm_gem_vmap(struct drm_gem_object *obj, struct iosys_map *map) { int ret; @@ -1175,23 +1175,23 @@ int drm_gem_vmap(struct drm_gem_object *obj, struct dma_buf_map *map) ret = obj->funcs->vmap(obj, map); if (ret) return ret; - else if (dma_buf_map_is_null(map)) + else if (iosys_map_is_null(map)) return -ENOMEM; return 0; } EXPORT_SYMBOL(drm_gem_vmap); -void drm_gem_vunmap(struct drm_gem_object *obj, struct dma_buf_map *map) +void drm_gem_vunmap(struct drm_gem_object *obj, struct iosys_map *map) { - if (dma_buf_map_is_null(map)) + if (iosys_map_is_null(map)) return; if (obj->funcs->vunmap) obj->funcs->vunmap(obj, map); /* Always set the mapping to NULL. Callers may rely on this. */ - dma_buf_map_clear(map); + iosys_map_clear(map); } EXPORT_SYMBOL(drm_gem_vunmap); diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c index cefd0cbf9deb..88c432a7cb3c 100644 --- a/drivers/gpu/drm/drm_gem_cma_helper.c +++ b/drivers/gpu/drm/drm_gem_cma_helper.c @@ -209,7 +209,7 @@ drm_gem_cma_create_with_handle(struct drm_file *file_priv, void drm_gem_cma_free(struct drm_gem_cma_object *cma_obj) { struct drm_gem_object *gem_obj = &cma_obj->base; - struct dma_buf_map map = DMA_BUF_MAP_INIT_VADDR(cma_obj->vaddr); + struct iosys_map map = IOSYS_MAP_INIT_VADDR(cma_obj->vaddr); if (gem_obj->import_attach) { if (cma_obj->vaddr) @@ -480,9 +480,10 @@ EXPORT_SYMBOL_GPL(drm_gem_cma_prime_import_sg_table); * Returns: * 0 on success, or a negative error code otherwise. */ -int drm_gem_cma_vmap(struct drm_gem_cma_object *cma_obj, struct dma_buf_map *map) +int drm_gem_cma_vmap(struct drm_gem_cma_object *cma_obj, + struct iosys_map *map) { - dma_buf_map_set_vaddr(map, cma_obj->vaddr); + iosys_map_set_vaddr(map, cma_obj->vaddr); return 0; } @@ -557,7 +558,7 @@ drm_gem_cma_prime_import_sg_table_vmap(struct drm_device *dev, { struct drm_gem_cma_object *cma_obj; struct drm_gem_object *obj; - struct dma_buf_map map; + struct iosys_map map; int ret; ret = dma_buf_vmap(attach->dmabuf, &map); diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c b/drivers/gpu/drm/drm_gem_framebuffer_helper.c index 746fd8c73845..f4619803acd0 100644 --- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c +++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c @@ -321,7 +321,7 @@ EXPORT_SYMBOL_GPL(drm_gem_fb_create_with_dirty); * @data: returns the data address for each BO, can be NULL * * This function maps all buffer objects of the given framebuffer into - * kernel address space and stores them in struct dma_buf_map. If the + * kernel address space and stores them in struct iosys_map. If the * mapping operation fails for one of the BOs, the function unmaps the * already established mappings automatically. * @@ -335,8 +335,8 @@ EXPORT_SYMBOL_GPL(drm_gem_fb_create_with_dirty); * 0 on success, or a negative errno code otherwise. */ int drm_gem_fb_vmap(struct drm_framebuffer *fb, - struct dma_buf_map map[static DRM_FORMAT_MAX_PLANES], - struct dma_buf_map data[DRM_FORMAT_MAX_PLANES]) + struct iosys_map map[static DRM_FORMAT_MAX_PLANES], + struct iosys_map data[DRM_FORMAT_MAX_PLANES]) { struct drm_gem_object *obj; unsigned int i; @@ -345,7 +345,7 @@ int drm_gem_fb_vmap(struct drm_framebuffer *fb, for (i = 0; i < DRM_FORMAT_MAX_PLANES; ++i) { obj = drm_gem_fb_get_obj(fb, i); if (!obj) { - dma_buf_map_clear(&map[i]); + iosys_map_clear(&map[i]); continue; } ret = drm_gem_vmap(obj, &map[i]); @@ -356,9 +356,9 @@ int drm_gem_fb_vmap(struct drm_framebuffer *fb, if (data) { for (i = 0; i < DRM_FORMAT_MAX_PLANES; ++i) { memcpy(&data[i], &map[i], sizeof(data[i])); - if (dma_buf_map_is_null(&data[i])) + if (iosys_map_is_null(&data[i])) continue; - dma_buf_map_incr(&data[i], fb->offsets[i]); + iosys_map_incr(&data[i], fb->offsets[i]); } } @@ -386,7 +386,7 @@ EXPORT_SYMBOL(drm_gem_fb_vmap); * See drm_gem_fb_vmap() for more information. */ void drm_gem_fb_vunmap(struct drm_framebuffer *fb, - struct dma_buf_map map[static DRM_FORMAT_MAX_PLANES]) + struct iosys_map map[static DRM_FORMAT_MAX_PLANES]) { unsigned int i = DRM_FORMAT_MAX_PLANES; struct drm_gem_object *obj; @@ -396,7 +396,7 @@ void drm_gem_fb_vunmap(struct drm_framebuffer *fb, obj = drm_gem_fb_get_obj(fb, i); if (!obj) continue; - if (dma_buf_map_is_null(&map[i])) + if (iosys_map_is_null(&map[i])) continue; drm_gem_vunmap(obj, &map[i]); } diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c index 621924116eb4..3e738aea2664 100644 --- a/drivers/gpu/drm/drm_gem_shmem_helper.c +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c @@ -286,13 +286,14 @@ void drm_gem_shmem_unpin(struct drm_gem_shmem_object *shmem) } EXPORT_SYMBOL(drm_gem_shmem_unpin); -static int drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem, struct dma_buf_map *map) +static int drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem, + struct iosys_map *map) { struct drm_gem_object *obj = &shmem->base; int ret = 0; if (shmem->vmap_use_count++ > 0) { - dma_buf_map_set_vaddr(map, shmem->vaddr); + iosys_map_set_vaddr(map, shmem->vaddr); return 0; } @@ -319,7 +320,7 @@ static int drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem, struct if (!shmem->vaddr) ret = -ENOMEM; else - dma_buf_map_set_vaddr(map, shmem->vaddr); + iosys_map_set_vaddr(map, shmem->vaddr); } if (ret) { @@ -353,7 +354,8 @@ err_zero_use: * Returns: * 0 on success or a negative error code on failure. */ -int drm_gem_shmem_vmap(struct drm_gem_shmem_object *shmem, struct dma_buf_map *map) +int drm_gem_shmem_vmap(struct drm_gem_shmem_object *shmem, + struct iosys_map *map) { int ret; @@ -368,7 +370,7 @@ int drm_gem_shmem_vmap(struct drm_gem_shmem_object *shmem, struct dma_buf_map *m EXPORT_SYMBOL(drm_gem_shmem_vmap); static void drm_gem_shmem_vunmap_locked(struct drm_gem_shmem_object *shmem, - struct dma_buf_map *map) + struct iosys_map *map) { struct drm_gem_object *obj = &shmem->base; @@ -400,7 +402,8 @@ static void drm_gem_shmem_vunmap_locked(struct drm_gem_shmem_object *shmem, * This function hides the differences between dma-buf imported and natively * allocated objects. */ -void drm_gem_shmem_vunmap(struct drm_gem_shmem_object *shmem, struct dma_buf_map *map) +void drm_gem_shmem_vunmap(struct drm_gem_shmem_object *shmem, + struct iosys_map *map) { mutex_lock(&shmem->vmap_lock); drm_gem_shmem_vunmap_locked(shmem, map); diff --git a/drivers/gpu/drm/drm_gem_ttm_helper.c b/drivers/gpu/drm/drm_gem_ttm_helper.c index ecf3d2a54a98..d5962a34c01d 100644 --- a/drivers/gpu/drm/drm_gem_ttm_helper.c +++ b/drivers/gpu/drm/drm_gem_ttm_helper.c @@ -61,7 +61,7 @@ EXPORT_SYMBOL(drm_gem_ttm_print_info); * 0 on success, or a negative errno code otherwise. */ int drm_gem_ttm_vmap(struct drm_gem_object *gem, - struct dma_buf_map *map) + struct iosys_map *map) { struct ttm_buffer_object *bo = drm_gem_ttm_of_gem(gem); @@ -78,7 +78,7 @@ EXPORT_SYMBOL(drm_gem_ttm_vmap); * &drm_gem_object_funcs.vmap callback. */ void drm_gem_ttm_vunmap(struct drm_gem_object *gem, - struct dma_buf_map *map) + struct iosys_map *map) { struct ttm_buffer_object *bo = drm_gem_ttm_of_gem(gem); diff --git a/drivers/gpu/drm/drm_gem_vram_helper.c b/drivers/gpu/drm/drm_gem_vram_helper.c index 3f00192215d1..dc7f938bfff2 100644 --- a/drivers/gpu/drm/drm_gem_vram_helper.c +++ b/drivers/gpu/drm/drm_gem_vram_helper.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-or-later -#include +#include #include #include @@ -116,7 +116,7 @@ static void drm_gem_vram_cleanup(struct drm_gem_vram_object *gbo) */ WARN_ON(gbo->vmap_use_count); - WARN_ON(dma_buf_map_is_set(&gbo->map)); + WARN_ON(iosys_map_is_set(&gbo->map)); drm_gem_object_release(&gbo->bo.base); } @@ -365,7 +365,7 @@ int drm_gem_vram_unpin(struct drm_gem_vram_object *gbo) EXPORT_SYMBOL(drm_gem_vram_unpin); static int drm_gem_vram_kmap_locked(struct drm_gem_vram_object *gbo, - struct dma_buf_map *map) + struct iosys_map *map) { int ret; @@ -377,7 +377,7 @@ static int drm_gem_vram_kmap_locked(struct drm_gem_vram_object *gbo, * page mapping might still be around. Only vmap if the there's * no mapping present. */ - if (dma_buf_map_is_null(&gbo->map)) { + if (iosys_map_is_null(&gbo->map)) { ret = ttm_bo_vmap(&gbo->bo, &gbo->map); if (ret) return ret; @@ -391,14 +391,14 @@ out: } static void drm_gem_vram_kunmap_locked(struct drm_gem_vram_object *gbo, - struct dma_buf_map *map) + struct iosys_map *map) { struct drm_device *dev = gbo->bo.base.dev; if (drm_WARN_ON_ONCE(dev, !gbo->vmap_use_count)) return; - if (drm_WARN_ON_ONCE(dev, !dma_buf_map_is_equal(&gbo->map, map))) + if (drm_WARN_ON_ONCE(dev, !iosys_map_is_equal(&gbo->map, map))) return; /* BUG: map not mapped from this BO */ if (--gbo->vmap_use_count > 0) @@ -428,7 +428,7 @@ static void drm_gem_vram_kunmap_locked(struct drm_gem_vram_object *gbo, * Returns: * 0 on success, or a negative error code otherwise. */ -int drm_gem_vram_vmap(struct drm_gem_vram_object *gbo, struct dma_buf_map *map) +int drm_gem_vram_vmap(struct drm_gem_vram_object *gbo, struct iosys_map *map) { int ret; @@ -463,7 +463,8 @@ EXPORT_SYMBOL(drm_gem_vram_vmap); * A call to drm_gem_vram_vunmap() unmaps and unpins a GEM VRAM buffer. See * the documentation for drm_gem_vram_vmap() for more information. */ -void drm_gem_vram_vunmap(struct drm_gem_vram_object *gbo, struct dma_buf_map *map) +void drm_gem_vram_vunmap(struct drm_gem_vram_object *gbo, + struct iosys_map *map) { int ret; @@ -567,7 +568,7 @@ static void drm_gem_vram_bo_driver_move_notify(struct drm_gem_vram_object *gbo) return; ttm_bo_vunmap(bo, &gbo->map); - dma_buf_map_clear(&gbo->map); /* explicitly clear mapping for next vmap call */ + iosys_map_clear(&gbo->map); /* explicitly clear mapping for next vmap call */ } static int drm_gem_vram_bo_driver_move(struct drm_gem_vram_object *gbo, @@ -802,7 +803,8 @@ static void drm_gem_vram_object_unpin(struct drm_gem_object *gem) * Returns: * 0 on success, or a negative error code otherwise. */ -static int drm_gem_vram_object_vmap(struct drm_gem_object *gem, struct dma_buf_map *map) +static int drm_gem_vram_object_vmap(struct drm_gem_object *gem, + struct iosys_map *map) { struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem); @@ -815,7 +817,8 @@ static int drm_gem_vram_object_vmap(struct drm_gem_object *gem, struct dma_buf_m * @gem: The GEM object to unmap * @map: Kernel virtual address where the VRAM GEM object was mapped */ -static void drm_gem_vram_object_vunmap(struct drm_gem_object *gem, struct dma_buf_map *map) +static void drm_gem_vram_object_vunmap(struct drm_gem_object *gem, + struct iosys_map *map) { struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem); diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h index 17f3548c8ed2..1fbbc19f1ac0 100644 --- a/drivers/gpu/drm/drm_internal.h +++ b/drivers/gpu/drm/drm_internal.h @@ -33,7 +33,7 @@ struct dentry; struct dma_buf; -struct dma_buf_map; +struct iosys_map; struct drm_connector; struct drm_crtc; struct drm_framebuffer; @@ -174,8 +174,8 @@ void drm_gem_print_info(struct drm_printer *p, unsigned int indent, int drm_gem_pin(struct drm_gem_object *obj); void drm_gem_unpin(struct drm_gem_object *obj); -int drm_gem_vmap(struct drm_gem_object *obj, struct dma_buf_map *map); -void drm_gem_vunmap(struct drm_gem_object *obj, struct dma_buf_map *map); +int drm_gem_vmap(struct drm_gem_object *obj, struct iosys_map *map); +void drm_gem_vunmap(struct drm_gem_object *obj, struct iosys_map *map); int drm_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev, u32 handle); diff --git a/drivers/gpu/drm/drm_mipi_dbi.c b/drivers/gpu/drm/drm_mipi_dbi.c index 0327d595e028..9314f2ead79f 100644 --- a/drivers/gpu/drm/drm_mipi_dbi.c +++ b/drivers/gpu/drm/drm_mipi_dbi.c @@ -201,8 +201,8 @@ int mipi_dbi_buf_copy(void *dst, struct drm_framebuffer *fb, struct drm_rect *clip, bool swap) { struct drm_gem_object *gem = drm_gem_fb_get_obj(fb, 0); - struct dma_buf_map map[DRM_FORMAT_MAX_PLANES]; - struct dma_buf_map data[DRM_FORMAT_MAX_PLANES]; + struct iosys_map map[DRM_FORMAT_MAX_PLANES]; + struct iosys_map data[DRM_FORMAT_MAX_PLANES]; void *src; int ret; @@ -258,8 +258,8 @@ static void mipi_dbi_set_window_address(struct mipi_dbi_dev *dbidev, static void mipi_dbi_fb_dirty(struct drm_framebuffer *fb, struct drm_rect *rect) { - struct dma_buf_map map[DRM_FORMAT_MAX_PLANES]; - struct dma_buf_map data[DRM_FORMAT_MAX_PLANES]; + struct iosys_map map[DRM_FORMAT_MAX_PLANES]; + struct iosys_map data[DRM_FORMAT_MAX_PLANES]; struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(fb->dev); unsigned int height = rect->y2 - rect->y1; unsigned int width = rect->x2 - rect->x1; diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c index b910978d3e48..4e853acfd1e8 100644 --- a/drivers/gpu/drm/drm_panel_orientation_quirks.c +++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c @@ -180,6 +180,12 @@ static const struct dmi_system_id orientation_data[] = { DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MicroPC"), }, .driver_data = (void *)&lcd720x1280_rightside_up, + }, { /* GPD Win Max */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "GPD"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "G1619-01"), + }, + .driver_data = (void *)&lcd800x1280_rightside_up, }, { /* * GPD Pocket, note that the the DMI data is less generic then * it seems, devices with a board-vendor of "AMI Corporation" diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index c773d3dfb1ab..e3f09f18110c 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -674,7 +674,7 @@ EXPORT_SYMBOL(drm_gem_unmap_dma_buf); * * Returns 0 on success or a negative errno code otherwise. */ -int drm_gem_dmabuf_vmap(struct dma_buf *dma_buf, struct dma_buf_map *map) +int drm_gem_dmabuf_vmap(struct dma_buf *dma_buf, struct iosys_map *map) { struct drm_gem_object *obj = dma_buf->priv; @@ -690,7 +690,7 @@ EXPORT_SYMBOL(drm_gem_dmabuf_vmap); * Releases a kernel virtual mapping. This can be used as the * &dma_buf_ops.vunmap callback. Calls into &drm_gem_object_funcs.vunmap for device specific handling. */ -void drm_gem_dmabuf_vunmap(struct dma_buf *dma_buf, struct dma_buf_map *map) +void drm_gem_dmabuf_vunmap(struct dma_buf *dma_buf, struct iosys_map *map) { struct drm_gem_object *obj = dma_buf->priv; diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.h b/drivers/gpu/drm/etnaviv/etnaviv_drv.h index 049ae87de9be..f32f4771dada 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.h @@ -49,7 +49,7 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data, int etnaviv_gem_mmap_offset(struct drm_gem_object *obj, u64 *offset); struct sg_table *etnaviv_gem_prime_get_sg_table(struct drm_gem_object *obj); -int etnaviv_gem_prime_vmap(struct drm_gem_object *obj, struct dma_buf_map *map); +int etnaviv_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map); struct drm_gem_object *etnaviv_gem_prime_import_sg_table(struct drm_device *dev, struct dma_buf_attachment *attach, struct sg_table *sg); int etnaviv_gem_prime_pin(struct drm_gem_object *obj); diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c index 6788ea8490d1..3fa2da149639 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c @@ -25,14 +25,14 @@ struct sg_table *etnaviv_gem_prime_get_sg_table(struct drm_gem_object *obj) return drm_prime_pages_to_sg(obj->dev, etnaviv_obj->pages, npages); } -int etnaviv_gem_prime_vmap(struct drm_gem_object *obj, struct dma_buf_map *map) +int etnaviv_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map) { void *vaddr; vaddr = etnaviv_gem_vmap(obj); if (!vaddr) return -ENOMEM; - dma_buf_map_set_vaddr(map, vaddr); + iosys_map_set_vaddr(map, vaddr); return 0; } @@ -62,7 +62,7 @@ void etnaviv_gem_prime_unpin(struct drm_gem_object *obj) static void etnaviv_gem_prime_release(struct etnaviv_gem_object *etnaviv_obj) { - struct dma_buf_map map = DMA_BUF_MAP_INIT_VADDR(etnaviv_obj->vaddr); + struct iosys_map map = IOSYS_MAP_INIT_VADDR(etnaviv_obj->vaddr); if (etnaviv_obj->vaddr) dma_buf_vunmap(etnaviv_obj->base.import_attach->dmabuf, &map); @@ -77,7 +77,7 @@ static void etnaviv_gem_prime_release(struct etnaviv_gem_object *etnaviv_obj) static void *etnaviv_gem_prime_vmap_impl(struct etnaviv_gem_object *etnaviv_obj) { - struct dma_buf_map map; + struct iosys_map map; int ret; lockdep_assert_held(&etnaviv_obj->lock); diff --git a/drivers/gpu/drm/gud/gud_pipe.c b/drivers/gpu/drm/gud/gud_pipe.c index a150a5a4b5d4..4873f9799f41 100644 --- a/drivers/gpu/drm/gud/gud_pipe.c +++ b/drivers/gpu/drm/gud/gud_pipe.c @@ -152,8 +152,8 @@ static int gud_prep_flush(struct gud_device *gdrm, struct drm_framebuffer *fb, { struct dma_buf_attachment *import_attach = fb->obj[0]->import_attach; u8 compression = gdrm->compression; - struct dma_buf_map map[DRM_FORMAT_MAX_PLANES]; - struct dma_buf_map map_data[DRM_FORMAT_MAX_PLANES]; + struct iosys_map map[DRM_FORMAT_MAX_PLANES]; + struct iosys_map map_data[DRM_FORMAT_MAX_PLANES]; void *vaddr, *buf; size_t pitch, len; int ret = 0; diff --git a/drivers/gpu/drm/hyperv/hyperv_drm_modeset.c b/drivers/gpu/drm/hyperv/hyperv_drm_modeset.c index 93f51e70a951..e82b815f83a6 100644 --- a/drivers/gpu/drm/hyperv/hyperv_drm_modeset.c +++ b/drivers/gpu/drm/hyperv/hyperv_drm_modeset.c @@ -19,7 +19,7 @@ #include "hyperv_drm.h" static int hyperv_blit_to_vram_rect(struct drm_framebuffer *fb, - const struct dma_buf_map *map, + const struct iosys_map *map, struct drm_rect *rect) { struct hyperv_drm_device *hv = to_hv(fb->dev); @@ -38,7 +38,8 @@ static int hyperv_blit_to_vram_rect(struct drm_framebuffer *fb, return 0; } -static int hyperv_blit_to_vram_fullscreen(struct drm_framebuffer *fb, const struct dma_buf_map *map) +static int hyperv_blit_to_vram_fullscreen(struct drm_framebuffer *fb, + const struct iosys_map *map) { struct drm_rect fullscreen = { .x1 = 0, diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index b136234120c4..139e0e7eba94 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -32,8 +32,9 @@ subdir-ccflags-y += -I$(srctree)/$(src) # core driver code i915-y += i915_driver.o \ i915_config.o \ - i915_irq.o \ i915_getparam.o \ + i915_ioctl.o \ + i915_irq.o \ i915_mitigations.o \ i915_module.o \ i915_params.o \ diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c index f37677df6ebf..f67bbaaad8e0 100644 --- a/drivers/gpu/drm/i915/display/g4x_dp.c +++ b/drivers/gpu/drm/i915/display/g4x_dp.c @@ -18,6 +18,7 @@ #include "intel_fifo_underrun.h" #include "intel_hdmi.h" #include "intel_hotplug.h" +#include "intel_pch_display.h" #include "intel_pps.h" #include "vlv_sideband.h" @@ -333,6 +334,21 @@ static bool intel_dp_get_hw_state(struct intel_encoder *encoder, return ret; } +static void g4x_dp_get_m_n(struct intel_crtc_state *crtc_state) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + + if (crtc_state->has_pch_encoder) { + intel_pch_transcoder_get_m1_n1(crtc, &crtc_state->dp_m_n); + intel_pch_transcoder_get_m2_n2(crtc, &crtc_state->dp_m2_n2); + } else { + intel_cpu_transcoder_get_m1_n1(crtc, crtc_state->cpu_transcoder, + &crtc_state->dp_m_n); + intel_cpu_transcoder_get_m2_n2(crtc, crtc_state->cpu_transcoder, + &crtc_state->dp_m2_n2); + } +} + static void intel_dp_get_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { @@ -384,7 +400,7 @@ static void intel_dp_get_config(struct intel_encoder *encoder, pipe_config->lane_count = ((tmp & DP_PORT_WIDTH_MASK) >> DP_PORT_WIDTH_SHIFT) + 1; - intel_dp_get_m_n(crtc, pipe_config); + g4x_dp_get_m_n(pipe_config); if (port == PORT_A) { if ((intel_de_read(dev_priv, DP_A) & DP_PLL_FREQ_MASK) == DP_PLL_FREQ_162MHZ) diff --git a/drivers/gpu/drm/i915/display/g4x_hdmi.h b/drivers/gpu/drm/i915/display/g4x_hdmi.h index 7aca14b602c6..db9a93bc9321 100644 --- a/drivers/gpu/drm/i915/display/g4x_hdmi.h +++ b/drivers/gpu/drm/i915/display/g4x_hdmi.h @@ -8,7 +8,7 @@ #include -#include "i915_reg.h" +#include "i915_reg_defs.h" enum port; struct drm_i915_private; diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c index 85950ff67609..a87b65cd41fd 100644 --- a/drivers/gpu/drm/i915/display/i9xx_plane.c +++ b/drivers/gpu/drm/i915/display/i9xx_plane.c @@ -125,7 +125,7 @@ static struct intel_fbc *i9xx_plane_fbc(struct drm_i915_private *dev_priv, enum i9xx_plane_id i9xx_plane) { if (i9xx_plane_has_fbc(dev_priv, i9xx_plane)) - return dev_priv->fbc; + return dev_priv->fbc[INTEL_FBC_A]; else return NULL; } @@ -155,51 +155,51 @@ static u32 i9xx_plane_ctl(const struct intel_crtc_state *crtc_state, unsigned int rotation = plane_state->hw.rotation; u32 dspcntr; - dspcntr = DISPLAY_PLANE_ENABLE; + dspcntr = DISP_ENABLE; if (IS_G4X(dev_priv) || IS_IRONLAKE(dev_priv) || IS_SANDYBRIDGE(dev_priv) || IS_IVYBRIDGE(dev_priv)) - dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE; + dspcntr |= DISP_TRICKLE_FEED_DISABLE; switch (fb->format->format) { case DRM_FORMAT_C8: - dspcntr |= DISPPLANE_8BPP; + dspcntr |= DISP_FORMAT_8BPP; break; case DRM_FORMAT_XRGB1555: - dspcntr |= DISPPLANE_BGRX555; + dspcntr |= DISP_FORMAT_BGRX555; break; case DRM_FORMAT_ARGB1555: - dspcntr |= DISPPLANE_BGRA555; + dspcntr |= DISP_FORMAT_BGRA555; break; case DRM_FORMAT_RGB565: - dspcntr |= DISPPLANE_BGRX565; + dspcntr |= DISP_FORMAT_BGRX565; break; case DRM_FORMAT_XRGB8888: - dspcntr |= DISPPLANE_BGRX888; + dspcntr |= DISP_FORMAT_BGRX888; break; case DRM_FORMAT_XBGR8888: - dspcntr |= DISPPLANE_RGBX888; + dspcntr |= DISP_FORMAT_RGBX888; break; case DRM_FORMAT_ARGB8888: - dspcntr |= DISPPLANE_BGRA888; + dspcntr |= DISP_FORMAT_BGRA888; break; case DRM_FORMAT_ABGR8888: - dspcntr |= DISPPLANE_RGBA888; + dspcntr |= DISP_FORMAT_RGBA888; break; case DRM_FORMAT_XRGB2101010: - dspcntr |= DISPPLANE_BGRX101010; + dspcntr |= DISP_FORMAT_BGRX101010; break; case DRM_FORMAT_XBGR2101010: - dspcntr |= DISPPLANE_RGBX101010; + dspcntr |= DISP_FORMAT_RGBX101010; break; case DRM_FORMAT_ARGB2101010: - dspcntr |= DISPPLANE_BGRA101010; + dspcntr |= DISP_FORMAT_BGRA101010; break; case DRM_FORMAT_ABGR2101010: - dspcntr |= DISPPLANE_RGBA101010; + dspcntr |= DISP_FORMAT_RGBA101010; break; case DRM_FORMAT_XBGR16161616F: - dspcntr |= DISPPLANE_RGBX161616; + dspcntr |= DISP_FORMAT_RGBX161616; break; default: MISSING_CASE(fb->format->format); @@ -208,13 +208,13 @@ static u32 i9xx_plane_ctl(const struct intel_crtc_state *crtc_state, if (DISPLAY_VER(dev_priv) >= 4 && fb->modifier == I915_FORMAT_MOD_X_TILED) - dspcntr |= DISPPLANE_TILED; + dspcntr |= DISP_TILED; if (rotation & DRM_MODE_ROTATE_180) - dspcntr |= DISPPLANE_ROTATE_180; + dspcntr |= DISP_ROTATE_180; if (rotation & DRM_MODE_REFLECT_X) - dspcntr |= DISPPLANE_MIRROR; + dspcntr |= DISP_MIRROR; return dspcntr; } @@ -354,13 +354,13 @@ static u32 i9xx_plane_ctl_crtc(const struct intel_crtc_state *crtc_state) u32 dspcntr = 0; if (crtc_state->gamma_enable) - dspcntr |= DISPPLANE_GAMMA_ENABLE; + dspcntr |= DISP_PIPE_GAMMA_ENABLE; if (crtc_state->csc_enable) - dspcntr |= DISPPLANE_PIPE_CSC_ENABLE; + dspcntr |= DISP_PIPE_CSC_ENABLE; if (DISPLAY_VER(dev_priv) < 5) - dspcntr |= DISPPLANE_SEL_PIPE(crtc->pipe); + dspcntr |= DISP_PIPE_SEL(crtc->pipe); return dspcntr; } @@ -437,9 +437,9 @@ static void i9xx_plane_update_noarm(struct intel_plane *plane, * program whatever is there. */ intel_de_write_fw(dev_priv, DSPPOS(i9xx_plane), - (crtc_y << 16) | crtc_x); + DISP_POS_Y(crtc_y) | DISP_POS_X(crtc_x)); intel_de_write_fw(dev_priv, DSPSIZE(i9xx_plane), - ((crtc_h - 1) << 16) | (crtc_w - 1)); + DISP_HEIGHT(crtc_h - 1) | DISP_WIDTH(crtc_w - 1)); } spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); @@ -474,20 +474,20 @@ static void i9xx_plane_update_arm(struct intel_plane *plane, int crtc_h = drm_rect_height(&plane_state->uapi.dst); intel_de_write_fw(dev_priv, PRIMPOS(i9xx_plane), - (crtc_y << 16) | crtc_x); + PRIM_POS_Y(crtc_y) | PRIM_POS_X(crtc_x)); intel_de_write_fw(dev_priv, PRIMSIZE(i9xx_plane), - ((crtc_h - 1) << 16) | (crtc_w - 1)); + PRIM_HEIGHT(crtc_h - 1) | PRIM_WIDTH(crtc_w - 1)); intel_de_write_fw(dev_priv, PRIMCNSTALPHA(i9xx_plane), 0); } if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { intel_de_write_fw(dev_priv, DSPOFFSET(i9xx_plane), - (y << 16) | x); + DISP_OFFSET_Y(y) | DISP_OFFSET_X(x)); } else if (DISPLAY_VER(dev_priv) >= 4) { intel_de_write_fw(dev_priv, DSPLINOFF(i9xx_plane), linear_offset); intel_de_write_fw(dev_priv, DSPTILEOFF(i9xx_plane), - (y << 16) | x); + DISP_OFFSET_Y(y) | DISP_OFFSET_X(x)); } /* @@ -564,7 +564,7 @@ g4x_primary_async_flip(struct intel_plane *plane, unsigned long irqflags; if (async_flip) - dspcntr |= DISPPLANE_ASYNC_FLIP; + dspcntr |= DISP_ASYNC_FLIP; spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); intel_de_write_fw(dev_priv, DSPCNTR(i9xx_plane), dspcntr); @@ -696,13 +696,12 @@ static bool i9xx_plane_get_hw_state(struct intel_plane *plane, val = intel_de_read(dev_priv, DSPCNTR(i9xx_plane)); - ret = val & DISPLAY_PLANE_ENABLE; + ret = val & DISP_ENABLE; if (DISPLAY_VER(dev_priv) >= 5) *pipe = plane->pipe; else - *pipe = (val & DISPPLANE_SEL_PIPE_MASK) >> - DISPPLANE_SEL_PIPE_SHIFT; + *pipe = REG_FIELD_GET(DISP_PIPE_SEL_MASK, val); intel_display_power_put(dev_priv, power_domain, wakeref); @@ -958,32 +957,32 @@ fail: static int i9xx_format_to_fourcc(int format) { switch (format) { - case DISPPLANE_8BPP: + case DISP_FORMAT_8BPP: return DRM_FORMAT_C8; - case DISPPLANE_BGRA555: + case DISP_FORMAT_BGRA555: return DRM_FORMAT_ARGB1555; - case DISPPLANE_BGRX555: + case DISP_FORMAT_BGRX555: return DRM_FORMAT_XRGB1555; - case DISPPLANE_BGRX565: + case DISP_FORMAT_BGRX565: return DRM_FORMAT_RGB565; default: - case DISPPLANE_BGRX888: + case DISP_FORMAT_BGRX888: return DRM_FORMAT_XRGB8888; - case DISPPLANE_RGBX888: + case DISP_FORMAT_RGBX888: return DRM_FORMAT_XBGR8888; - case DISPPLANE_BGRA888: + case DISP_FORMAT_BGRA888: return DRM_FORMAT_ARGB8888; - case DISPPLANE_RGBA888: + case DISP_FORMAT_RGBA888: return DRM_FORMAT_ABGR8888; - case DISPPLANE_BGRX101010: + case DISP_FORMAT_BGRX101010: return DRM_FORMAT_XRGB2101010; - case DISPPLANE_RGBX101010: + case DISP_FORMAT_RGBX101010: return DRM_FORMAT_XBGR2101010; - case DISPPLANE_BGRA101010: + case DISP_FORMAT_BGRA101010: return DRM_FORMAT_ARGB2101010; - case DISPPLANE_RGBA101010: + case DISP_FORMAT_RGBA101010: return DRM_FORMAT_ABGR2101010; - case DISPPLANE_RGBX161616: + case DISP_FORMAT_RGBX161616: return DRM_FORMAT_XBGR16161616F; } } @@ -1021,26 +1020,26 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc, val = intel_de_read(dev_priv, DSPCNTR(i9xx_plane)); if (DISPLAY_VER(dev_priv) >= 4) { - if (val & DISPPLANE_TILED) { + if (val & DISP_TILED) { plane_config->tiling = I915_TILING_X; fb->modifier = I915_FORMAT_MOD_X_TILED; } - if (val & DISPPLANE_ROTATE_180) + if (val & DISP_ROTATE_180) plane_config->rotation = DRM_MODE_ROTATE_180; } if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B && - val & DISPPLANE_MIRROR) + val & DISP_MIRROR) plane_config->rotation |= DRM_MODE_REFLECT_X; - pixel_format = val & DISPPLANE_PIXFORMAT_MASK; + pixel_format = val & DISP_FORMAT_MASK; fourcc = i9xx_format_to_fourcc(pixel_format); fb->format = drm_format_info(fourcc); if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { offset = intel_de_read(dev_priv, DSPOFFSET(i9xx_plane)); - base = intel_de_read(dev_priv, DSPSURF(i9xx_plane)) & 0xfffff000; + base = intel_de_read(dev_priv, DSPSURF(i9xx_plane)) & DISP_ADDR_MASK; } else if (DISPLAY_VER(dev_priv) >= 4) { if (plane_config->tiling) offset = intel_de_read(dev_priv, @@ -1048,15 +1047,15 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc, else offset = intel_de_read(dev_priv, DSPLINOFF(i9xx_plane)); - base = intel_de_read(dev_priv, DSPSURF(i9xx_plane)) & 0xfffff000; + base = intel_de_read(dev_priv, DSPSURF(i9xx_plane)) & DISP_ADDR_MASK; } else { base = intel_de_read(dev_priv, DSPADDR(i9xx_plane)); } plane_config->base = base; val = intel_de_read(dev_priv, PIPESRC(pipe)); - fb->width = ((val >> 16) & 0xfff) + 1; - fb->height = ((val >> 0) & 0xfff) + 1; + fb->width = REG_FIELD_GET(PIPESRC_WIDTH_MASK, val) + 1; + fb->height = REG_FIELD_GET(PIPESRC_HEIGHT_MASK, val) + 1; val = intel_de_read(dev_priv, DSPSTRIDE(i9xx_plane)); fb->pitches[0] = val & 0xffffffc0; diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c index 5781e9fac8b4..2d5bb9195b20 100644 --- a/drivers/gpu/drm/i915/display/icl_dsi.c +++ b/drivers/gpu/drm/i915/display/icl_dsi.c @@ -32,6 +32,7 @@ #include "intel_atomic.h" #include "intel_backlight.h" #include "intel_combo_phy.h" +#include "intel_combo_phy_regs.h" #include "intel_connector.h" #include "intel_crtc.h" #include "intel_ddi.h" @@ -1050,7 +1051,7 @@ static void gen11_dsi_enable_transcoder(struct intel_encoder *encoder) /* wait for transcoder to be enabled */ if (intel_de_wait_for_set(dev_priv, PIPECONF(dsi_trans), - I965_PIPECONF_ACTIVE, 10)) + PIPECONF_STATE_ENABLE, 10)) drm_err(&dev_priv->drm, "DSI transcoder not enabled\n"); } @@ -1232,8 +1233,6 @@ static void gen11_dsi_pre_enable(struct intel_atomic_state *state, intel_dsc_dsi_pps_write(encoder, pipe_config); - intel_dsc_enable(pipe_config); - /* step6c: configure transcoder timings */ gen11_dsi_set_transcoder_timings(encoder, pipe_config); } @@ -1320,7 +1319,7 @@ static void gen11_dsi_disable_transcoder(struct intel_encoder *encoder) /* wait for transcoder to be disabled */ if (intel_de_wait_for_clear(dev_priv, PIPECONF(dsi_trans), - I965_PIPECONF_ACTIVE, 50)) + PIPECONF_STATE_ENABLE, 50)) drm_err(&dev_priv->drm, "DSI trancoder not disabled\n"); } diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c index a62550711e98..093904065112 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic.c +++ b/drivers/gpu/drm/i915/display/intel_atomic.c @@ -34,6 +34,8 @@ #include #include +#include "i915_drv.h" +#include "i915_reg.h" #include "intel_atomic.h" #include "intel_cdclk.h" #include "intel_display_types.h" diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index c2c512cd8ec0..bec02333bdeb 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -109,6 +109,7 @@ intel_plane_duplicate_state(struct drm_plane *plane) intel_state->ggtt_vma = NULL; intel_state->dpt_vma = NULL; intel_state->flags = 0; + intel_state->do_async_flip = false; /* add reference to fb */ if (intel_state->hw.fb) @@ -491,7 +492,7 @@ void intel_plane_update_arm(struct intel_plane *plane, trace_intel_plane_update_arm(&plane->base, crtc); - if (crtc_state->uapi.async_flip && plane->async_flip) + if (plane_state->do_async_flip) plane->async_flip(plane, crtc_state, plane_state, true); else plane->update_arm(plane, crtc_state, plane_state); @@ -601,6 +602,7 @@ int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state, int min_scale, int max_scale, bool can_position) { + struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev); struct drm_framebuffer *fb = plane_state->hw.fb; struct drm_rect *src = &plane_state->uapi.src; struct drm_rect *dst = &plane_state->uapi.dst; @@ -619,7 +621,7 @@ int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state, hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale); vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale); if (hscale < 0 || vscale < 0) { - DRM_DEBUG_KMS("Invalid scaling of plane\n"); + drm_dbg_kms(&i915->drm, "Invalid scaling of plane\n"); drm_rect_debug_print("src: ", src, true); drm_rect_debug_print("dst: ", dst, false); return -ERANGE; @@ -644,7 +646,7 @@ int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state, if (!can_position && plane_state->uapi.visible && !drm_rect_equals(dst, &clip)) { - DRM_DEBUG_KMS("Plane must cover entire CRTC\n"); + drm_dbg_kms(&i915->drm, "Plane must cover entire CRTC\n"); drm_rect_debug_print("dst: ", dst, false); drm_rect_debug_print("clip: ", &clip, false); return -EINVAL; diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h index 7907f601598e..ead789709477 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h @@ -16,6 +16,7 @@ struct intel_crtc; struct intel_crtc_state; struct intel_plane; struct intel_plane_state; +enum plane_id; unsigned int intel_adjusted_rate(const struct drm_rect *src, const struct drm_rect *dst, diff --git a/drivers/gpu/drm/i915/display/intel_backlight.c b/drivers/gpu/drm/i915/display/intel_backlight.c index 9523411cddd8..98f7ea44042f 100644 --- a/drivers/gpu/drm/i915/display/intel_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_backlight.c @@ -13,6 +13,7 @@ #include "intel_dp_aux_backlight.h" #include "intel_dsi_dcs_backlight.h" #include "intel_panel.h" +#include "intel_pci_config.h" /** * scale - scale values from one range to another @@ -433,6 +434,8 @@ static void ext_pwm_disable_backlight(const struct drm_connector_state *old_conn struct intel_connector *connector = to_intel_connector(old_conn_state->connector); struct intel_panel *panel = &connector->panel; + intel_backlight_set_pwm_level(old_conn_state, level); + panel->backlight.pwm_state.enabled = false; pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state); } diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c index 1ff1f1c426b2..aec0efd5350e 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.c +++ b/drivers/gpu/drm/i915/display/intel_bios.c @@ -32,6 +32,7 @@ #include "display/intel_gmbus.h" #include "i915_drv.h" +#include "i915_reg.h" #define _INTEL_BIOS_PRIVATE #include "intel_vbt_defs.h" @@ -905,26 +906,6 @@ parse_psr(struct drm_i915_private *i915, const struct bdb_header *bdb) i915->vbt.psr.idle_frames = psr_table->idle_frames < 0 ? 0 : psr_table->idle_frames > 15 ? 15 : psr_table->idle_frames; - switch (psr_table->lines_to_wait) { - case 0: - i915->vbt.psr.lines_to_wait = PSR_0_LINES_TO_WAIT; - break; - case 1: - i915->vbt.psr.lines_to_wait = PSR_1_LINE_TO_WAIT; - break; - case 2: - i915->vbt.psr.lines_to_wait = PSR_4_LINES_TO_WAIT; - break; - case 3: - i915->vbt.psr.lines_to_wait = PSR_8_LINES_TO_WAIT; - break; - default: - drm_dbg_kms(&i915->drm, - "VBT has unknown PSR lines to wait %u\n", - psr_table->lines_to_wait); - break; - } - /* * New psr options 0=500us, 1=100us, 2=2500us, 3=0us * Old decimal value is wake up time in multiples of 100 us. @@ -2073,14 +2054,16 @@ static void parse_ddi_port(struct drm_i915_private *i915, i915->vbt.ports[port] = devdata; } +static bool has_ddi_port_info(struct drm_i915_private *i915) +{ + return DISPLAY_VER(i915) >= 5 || IS_G4X(i915); +} + static void parse_ddi_ports(struct drm_i915_private *i915) { struct intel_bios_encoder_data *devdata; - if (!HAS_DDI(i915) && !IS_CHERRYVIEW(i915)) - return; - - if (i915->vbt.version < 155) + if (!has_ddi_port_info(i915)) return; list_for_each_entry(devdata, &i915->vbt.display_devices, node) @@ -2335,6 +2318,63 @@ bool intel_bios_is_valid_vbt(const void *buf, size_t size) return vbt; } +static struct vbt_header *spi_oprom_get_vbt(struct drm_i915_private *i915) +{ + u32 count, data, found, store = 0; + u32 static_region, oprom_offset; + u32 oprom_size = 0x200000; + u16 vbt_size; + u32 *vbt; + + static_region = intel_uncore_read(&i915->uncore, SPI_STATIC_REGIONS); + static_region &= OPTIONROM_SPI_REGIONID_MASK; + intel_uncore_write(&i915->uncore, PRIMARY_SPI_REGIONID, static_region); + + oprom_offset = intel_uncore_read(&i915->uncore, OROM_OFFSET); + oprom_offset &= OROM_OFFSET_MASK; + + for (count = 0; count < oprom_size; count += 4) { + intel_uncore_write(&i915->uncore, PRIMARY_SPI_ADDRESS, oprom_offset + count); + data = intel_uncore_read(&i915->uncore, PRIMARY_SPI_TRIGGER); + + if (data == *((const u32 *)"$VBT")) { + found = oprom_offset + count; + break; + } + } + + if (count >= oprom_size) + goto err_not_found; + + /* Get VBT size and allocate space for the VBT */ + intel_uncore_write(&i915->uncore, PRIMARY_SPI_ADDRESS, found + + offsetof(struct vbt_header, vbt_size)); + vbt_size = intel_uncore_read(&i915->uncore, PRIMARY_SPI_TRIGGER); + vbt_size &= 0xffff; + + vbt = kzalloc(round_up(vbt_size, 4), GFP_KERNEL); + if (!vbt) + goto err_not_found; + + for (count = 0; count < vbt_size; count += 4) { + intel_uncore_write(&i915->uncore, PRIMARY_SPI_ADDRESS, found + count); + data = intel_uncore_read(&i915->uncore, PRIMARY_SPI_TRIGGER); + *(vbt + store++) = data; + } + + if (!intel_bios_is_valid_vbt(vbt, vbt_size)) + goto err_free_vbt; + + drm_dbg_kms(&i915->drm, "Found valid VBT in SPI flash\n"); + + return (struct vbt_header *)vbt; + +err_free_vbt: + kfree(vbt); +err_not_found: + return NULL; +} + static struct vbt_header *oprom_get_vbt(struct drm_i915_private *i915) { struct pci_dev *pdev = to_pci_dev(i915->drm.dev); @@ -2384,6 +2424,8 @@ static struct vbt_header *oprom_get_vbt(struct drm_i915_private *i915) pci_unmap_rom(pdev, oprom); + drm_dbg_kms(&i915->drm, "Found valid VBT in PCI ROM\n"); + return vbt; err_free_vbt: @@ -2418,17 +2460,23 @@ void intel_bios_init(struct drm_i915_private *i915) init_vbt_defaults(i915); - /* If the OpRegion does not have VBT, look in PCI ROM. */ + /* + * If the OpRegion does not have VBT, look in SPI flash through MMIO or + * PCI mapping + */ + if (!vbt && IS_DGFX(i915)) { + oprom_vbt = spi_oprom_get_vbt(i915); + vbt = oprom_vbt; + } + if (!vbt) { oprom_vbt = oprom_get_vbt(i915); - if (!oprom_vbt) - goto out; - vbt = oprom_vbt; - - drm_dbg_kms(&i915->drm, "Found valid VBT in PCI ROM\n"); } + if (!vbt) + goto out; + bdb = get_bdb_header(vbt); i915->vbt.version = bdb->version; @@ -2596,37 +2644,10 @@ bool intel_bios_is_lvds_present(struct drm_i915_private *i915, u8 *i2c_pin) */ bool intel_bios_is_port_present(struct drm_i915_private *i915, enum port port) { - const struct intel_bios_encoder_data *devdata; - const struct child_device_config *child; - static const struct { - u16 dp, hdmi; - } port_mapping[] = { - [PORT_B] = { DVO_PORT_DPB, DVO_PORT_HDMIB, }, - [PORT_C] = { DVO_PORT_DPC, DVO_PORT_HDMIC, }, - [PORT_D] = { DVO_PORT_DPD, DVO_PORT_HDMID, }, - [PORT_E] = { DVO_PORT_DPE, DVO_PORT_HDMIE, }, - [PORT_F] = { DVO_PORT_DPF, DVO_PORT_HDMIF, }, - }; + if (WARN_ON(!has_ddi_port_info(i915))) + return true; - if (HAS_DDI(i915)) - return i915->vbt.ports[port]; - - /* FIXME maybe deal with port A as well? */ - if (drm_WARN_ON(&i915->drm, - port == PORT_A) || port >= ARRAY_SIZE(port_mapping)) - return false; - - list_for_each_entry(devdata, &i915->vbt.display_devices, node) { - child = &devdata->child; - - if ((child->dvo_port == port_mapping[port].dp || - child->dvo_port == port_mapping[port].hdmi) && - (child->device_type & (DEVICE_TYPE_TMDS_DVI_SIGNALING | - DEVICE_TYPE_DISPLAYPORT_OUTPUT))) - return true; - } - - return false; + return i915->vbt.ports[port]; } /** @@ -2638,40 +2659,18 @@ bool intel_bios_is_port_present(struct drm_i915_private *i915, enum port port) */ bool intel_bios_is_port_edp(struct drm_i915_private *i915, enum port port) { - const struct intel_bios_encoder_data *devdata; - const struct child_device_config *child; - static const short port_mapping[] = { - [PORT_B] = DVO_PORT_DPB, - [PORT_C] = DVO_PORT_DPC, - [PORT_D] = DVO_PORT_DPD, - [PORT_E] = DVO_PORT_DPE, - [PORT_F] = DVO_PORT_DPF, - }; + const struct intel_bios_encoder_data *devdata = + intel_bios_encoder_data_lookup(i915, port); - if (HAS_DDI(i915)) { - const struct intel_bios_encoder_data *devdata; - - devdata = intel_bios_encoder_data_lookup(i915, port); - - return devdata && intel_bios_encoder_supports_edp(devdata); - } - - list_for_each_entry(devdata, &i915->vbt.display_devices, node) { - child = &devdata->child; - - if (child->dvo_port == port_mapping[port] && - (child->device_type & DEVICE_TYPE_eDP_BITS) == - (DEVICE_TYPE_eDP & DEVICE_TYPE_eDP_BITS)) - return true; - } - - return false; + return devdata && intel_bios_encoder_supports_edp(devdata); } -static bool child_dev_is_dp_dual_mode(const struct child_device_config *child) +static bool intel_bios_encoder_supports_dp_dual_mode(const struct intel_bios_encoder_data *devdata) { - if ((child->device_type & DEVICE_TYPE_DP_DUAL_MODE_BITS) != - (DEVICE_TYPE_DP_DUAL_MODE & DEVICE_TYPE_DP_DUAL_MODE_BITS)) + const struct child_device_config *child = &devdata->child; + + if (!intel_bios_encoder_supports_dp(devdata) || + !intel_bios_encoder_supports_hdmi(devdata)) return false; if (dvo_port_type(child->dvo_port) == DVO_PORT_DPA) @@ -2688,40 +2687,10 @@ static bool child_dev_is_dp_dual_mode(const struct child_device_config *child) bool intel_bios_is_port_dp_dual_mode(struct drm_i915_private *i915, enum port port) { - static const struct { - u16 dp, hdmi; - } port_mapping[] = { - /* - * Buggy VBTs may declare DP ports as having - * HDMI type dvo_port :( So let's check both. - */ - [PORT_B] = { DVO_PORT_DPB, DVO_PORT_HDMIB, }, - [PORT_C] = { DVO_PORT_DPC, DVO_PORT_HDMIC, }, - [PORT_D] = { DVO_PORT_DPD, DVO_PORT_HDMID, }, - [PORT_E] = { DVO_PORT_DPE, DVO_PORT_HDMIE, }, - [PORT_F] = { DVO_PORT_DPF, DVO_PORT_HDMIF, }, - }; - const struct intel_bios_encoder_data *devdata; + const struct intel_bios_encoder_data *devdata = + intel_bios_encoder_data_lookup(i915, port); - if (HAS_DDI(i915)) { - const struct intel_bios_encoder_data *devdata; - - devdata = intel_bios_encoder_data_lookup(i915, port); - - return devdata && child_dev_is_dp_dual_mode(&devdata->child); - } - - if (port == PORT_A || port >= ARRAY_SIZE(port_mapping)) - return false; - - list_for_each_entry(devdata, &i915->vbt.display_devices, node) { - if ((devdata->child.dvo_port == port_mapping[port].dp || - devdata->child.dvo_port == port_mapping[port].hdmi) && - child_dev_is_dp_dual_mode(&devdata->child)) - return true; - } - - return false; + return devdata && intel_bios_encoder_supports_dp_dual_mode(devdata); } /** diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index 2da4aacc956b..5dce3cf0ed12 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -5,6 +5,7 @@ #include +#include "i915_reg.h" #include "intel_atomic.h" #include "intel_bw.h" #include "intel_cdclk.h" @@ -75,10 +76,9 @@ static int icl_pcode_read_qgv_point_info(struct drm_i915_private *dev_priv, u16 dclk; int ret; - ret = sandybridge_pcode_read(dev_priv, - ICL_PCODE_MEM_SUBSYSYSTEM_INFO | - ICL_PCODE_MEM_SS_READ_QGV_POINT_INFO(point), - &val, &val2); + ret = snb_pcode_read(dev_priv, ICL_PCODE_MEM_SUBSYSYSTEM_INFO | + ICL_PCODE_MEM_SS_READ_QGV_POINT_INFO(point), + &val, &val2); if (ret) return ret; @@ -102,10 +102,8 @@ static int adls_pcode_read_psf_gv_point_info(struct drm_i915_private *dev_priv, int ret; int i; - ret = sandybridge_pcode_read(dev_priv, - ICL_PCODE_MEM_SUBSYSYSTEM_INFO | - ADL_PCODE_MEM_SS_READ_PSF_GV_INFO, - &val, NULL); + ret = snb_pcode_read(dev_priv, ICL_PCODE_MEM_SUBSYSYSTEM_INFO | + ADL_PCODE_MEM_SS_READ_PSF_GV_INFO, &val, NULL); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index c30cf8d2b835..4b140a014ca8 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -31,6 +31,7 @@ #include "intel_crtc.h" #include "intel_de.h" #include "intel_display_types.h" +#include "intel_pci_config.h" #include "intel_pcode.h" #include "intel_psr.h" #include "vlv_sideband.h" @@ -63,6 +64,17 @@ * dividers can be programmed correctly. */ +struct intel_cdclk_funcs { + void (*get_cdclk)(struct drm_i915_private *i915, + struct intel_cdclk_config *cdclk_config); + void (*set_cdclk)(struct drm_i915_private *i915, + const struct intel_cdclk_config *cdclk_config, + enum pipe pipe); + int (*bw_calc_min_cdclk)(struct intel_atomic_state *state); + int (*modeset_calc_cdclk)(struct intel_cdclk_state *state); + u8 (*calc_voltage_level)(int cdclk); +}; + void intel_cdclk_get_cdclk(struct drm_i915_private *dev_priv, struct intel_cdclk_config *cdclk_config) { @@ -793,8 +805,7 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv, "trying to change cdclk frequency with cdclk not enabled\n")) return; - ret = sandybridge_pcode_write(dev_priv, - BDW_PCODE_DISPLAY_FREQ_CHANGE_REQ, 0x0); + ret = snb_pcode_write(dev_priv, BDW_PCODE_DISPLAY_FREQ_CHANGE_REQ, 0x0); if (ret) { drm_err(&dev_priv->drm, "failed to inform pcode about cdclk change\n"); @@ -822,8 +833,8 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv, LCPLL_CD_SOURCE_FCLK_DONE) == 0, 1)) drm_err(&dev_priv->drm, "Switching back to LCPLL failed\n"); - sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ, - cdclk_config->voltage_level); + snb_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ, + cdclk_config->voltage_level); intel_de_write(dev_priv, CDCLK_FREQ, DIV_ROUND_CLOSEST(cdclk, 1000) - 1); @@ -1126,8 +1137,8 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv, intel_de_posting_read(dev_priv, CDCLK_CTL); /* inform PCU of the change */ - sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL, - cdclk_config->voltage_level); + snb_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL, + cdclk_config->voltage_level); intel_update_cdclk(dev_priv); } @@ -1145,7 +1156,7 @@ static void skl_sanitize_cdclk(struct drm_i915_private *dev_priv) goto sanitize; intel_update_cdclk(dev_priv); - intel_dump_cdclk_config(&dev_priv->cdclk.hw, "Current CDCLK"); + intel_cdclk_dump_config(dev_priv, &dev_priv->cdclk.hw, "Current CDCLK"); /* Is PLL enabled and locked ? */ if (dev_priv->cdclk.hw.vco == 0 || @@ -1614,7 +1625,7 @@ static void adlp_cdclk_pll_crawl(struct drm_i915_private *dev_priv, int vco) /* Timeout 200us */ if (intel_de_wait_for_set(dev_priv, BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK | BXT_DE_PLL_FREQ_REQ_ACK, 1)) - DRM_ERROR("timeout waiting for FREQ change request ack\n"); + drm_err(&dev_priv->drm, "timeout waiting for FREQ change request ack\n"); val &= ~BXT_DE_PLL_FREQ_REQ; intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, val); @@ -1705,10 +1716,9 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, * BSpec requires us to wait up to 150usec, but that leads to * timeouts; the 2ms used here is based on experiment. */ - ret = sandybridge_pcode_write_timeout(dev_priv, - HSW_PCODE_DE_WRITE_FREQ_REQ, - 0x80000000, 150, 2); - + ret = snb_pcode_write_timeout(dev_priv, + HSW_PCODE_DE_WRITE_FREQ_REQ, + 0x80000000, 150, 2); if (ret) { drm_err(&dev_priv->drm, "Failed to inform PCU about cdclk change (err %d, freq %d)\n", @@ -1769,8 +1779,8 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, intel_crtc_wait_for_next_vblank(intel_crtc_for_pipe(dev_priv, pipe)); if (DISPLAY_VER(dev_priv) >= 11) { - ret = sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL, - cdclk_config->voltage_level); + ret = snb_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL, + cdclk_config->voltage_level); } else { /* * The timeout isn't specified, the 2ms used here is based on @@ -1778,10 +1788,10 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, * FIXME: Waiting for the request completion could be delayed * until the next PCODE request based on BSpec. */ - ret = sandybridge_pcode_write_timeout(dev_priv, - HSW_PCODE_DE_WRITE_FREQ_REQ, - cdclk_config->voltage_level, - 150, 2); + ret = snb_pcode_write_timeout(dev_priv, + HSW_PCODE_DE_WRITE_FREQ_REQ, + cdclk_config->voltage_level, + 150, 2); } if (ret) { @@ -1807,7 +1817,7 @@ static void bxt_sanitize_cdclk(struct drm_i915_private *dev_priv) int cdclk, clock, vco; intel_update_cdclk(dev_priv); - intel_dump_cdclk_config(&dev_priv->cdclk.hw, "Current CDCLK"); + intel_cdclk_dump_config(dev_priv, &dev_priv->cdclk.hw, "Current CDCLK"); if (dev_priv->cdclk.hw.vco == 0 || dev_priv->cdclk.hw.cdclk == dev_priv->cdclk.hw.bypass) @@ -2047,13 +2057,14 @@ static bool intel_cdclk_changed(const struct intel_cdclk_config *a, a->voltage_level != b->voltage_level; } -void intel_dump_cdclk_config(const struct intel_cdclk_config *cdclk_config, +void intel_cdclk_dump_config(struct drm_i915_private *i915, + const struct intel_cdclk_config *cdclk_config, const char *context) { - DRM_DEBUG_DRIVER("%s %d kHz, VCO %d kHz, ref %d kHz, bypass %d kHz, voltage level %d\n", - context, cdclk_config->cdclk, cdclk_config->vco, - cdclk_config->ref, cdclk_config->bypass, - cdclk_config->voltage_level); + drm_dbg_kms(&i915->drm, "%s %d kHz, VCO %d kHz, ref %d kHz, bypass %d kHz, voltage level %d\n", + context, cdclk_config->cdclk, cdclk_config->vco, + cdclk_config->ref, cdclk_config->bypass, + cdclk_config->voltage_level); } /** @@ -2077,7 +2088,7 @@ static void intel_set_cdclk(struct drm_i915_private *dev_priv, if (drm_WARN_ON_ONCE(&dev_priv->drm, !dev_priv->cdclk_funcs->set_cdclk)) return; - intel_dump_cdclk_config(cdclk_config, "Changing CDCLK to"); + intel_cdclk_dump_config(dev_priv, cdclk_config, "Changing CDCLK to"); for_each_intel_encoder_with_psr(&dev_priv->drm, encoder) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); @@ -2120,8 +2131,8 @@ static void intel_set_cdclk(struct drm_i915_private *dev_priv, if (drm_WARN(&dev_priv->drm, intel_cdclk_changed(&dev_priv->cdclk.hw, cdclk_config), "cdclk state doesn't match!\n")) { - intel_dump_cdclk_config(&dev_priv->cdclk.hw, "[hw state]"); - intel_dump_cdclk_config(cdclk_config, "[sw state]"); + intel_cdclk_dump_config(dev_priv, &dev_priv->cdclk.hw, "[hw state]"); + intel_cdclk_dump_config(dev_priv, cdclk_config, "[sw state]"); } } diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.h b/drivers/gpu/drm/i915/display/intel_cdclk.h index fc638522e445..df66f66fbad0 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.h +++ b/drivers/gpu/drm/i915/display/intel_cdclk.h @@ -8,7 +8,6 @@ #include -#include "i915_drv.h" #include "intel_display.h" #include "intel_global_state.h" @@ -16,6 +15,11 @@ struct drm_i915_private; struct intel_atomic_state; struct intel_crtc_state; +struct intel_cdclk_config { + unsigned int cdclk, vco, ref, bypass; + u8 voltage_level; +}; + struct intel_cdclk_state { struct intel_global_state base; @@ -58,7 +62,8 @@ bool intel_cdclk_needs_modeset(const struct intel_cdclk_config *a, const struct intel_cdclk_config *b); void intel_set_cdclk_pre_plane_update(struct intel_atomic_state *state); void intel_set_cdclk_post_plane_update(struct intel_atomic_state *state); -void intel_dump_cdclk_config(const struct intel_cdclk_config *cdclk_config, +void intel_cdclk_dump_config(struct drm_i915_private *i915, + const struct intel_cdclk_config *cdclk_config, const char *context); int intel_modeset_calc_cdclk(struct intel_atomic_state *state); void intel_cdclk_get_cdclk(struct drm_i915_private *dev_priv, diff --git a/drivers/gpu/drm/i915/display/intel_combo_phy.c b/drivers/gpu/drm/i915/display/intel_combo_phy.c index f628e0542933..4dfe77351b8b 100644 --- a/drivers/gpu/drm/i915/display/intel_combo_phy.c +++ b/drivers/gpu/drm/i915/display/intel_combo_phy.c @@ -4,6 +4,7 @@ */ #include "intel_combo_phy.h" +#include "intel_combo_phy_regs.h" #include "intel_de.h" #include "intel_display_types.h" diff --git a/drivers/gpu/drm/i915/display/intel_combo_phy_regs.h b/drivers/gpu/drm/i915/display/intel_combo_phy_regs.h new file mode 100644 index 000000000000..2ed65193ca19 --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_combo_phy_regs.h @@ -0,0 +1,162 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2022 Intel Corporation + */ + +#ifndef __INTEL_COMBO_PHY_REGS__ +#define __INTEL_COMBO_PHY_REGS__ + +#include "i915_reg_defs.h" + +#define _ICL_COMBOPHY_A 0x162000 +#define _ICL_COMBOPHY_B 0x6C000 +#define _EHL_COMBOPHY_C 0x160000 +#define _RKL_COMBOPHY_D 0x161000 +#define _ADL_COMBOPHY_E 0x16B000 + +#define _ICL_COMBOPHY(phy) _PICK(phy, _ICL_COMBOPHY_A, \ + _ICL_COMBOPHY_B, \ + _EHL_COMBOPHY_C, \ + _RKL_COMBOPHY_D, \ + _ADL_COMBOPHY_E) + +/* ICL Port CL_DW registers */ +#define _ICL_PORT_CL_DW(dw, phy) (_ICL_COMBOPHY(phy) + \ + 4 * (dw)) + +#define ICL_PORT_CL_DW5(phy) _MMIO(_ICL_PORT_CL_DW(5, phy)) +#define CL_POWER_DOWN_ENABLE (1 << 4) +#define SUS_CLOCK_CONFIG (3 << 0) + +#define ICL_PORT_CL_DW10(phy) _MMIO(_ICL_PORT_CL_DW(10, phy)) +#define PG_SEQ_DELAY_OVERRIDE_MASK (3 << 25) +#define PG_SEQ_DELAY_OVERRIDE_SHIFT 25 +#define PG_SEQ_DELAY_OVERRIDE_ENABLE (1 << 24) +#define PWR_UP_ALL_LANES (0x0 << 4) +#define PWR_DOWN_LN_3_2_1 (0xe << 4) +#define PWR_DOWN_LN_3_2 (0xc << 4) +#define PWR_DOWN_LN_3 (0x8 << 4) +#define PWR_DOWN_LN_2_1_0 (0x7 << 4) +#define PWR_DOWN_LN_1_0 (0x3 << 4) +#define PWR_DOWN_LN_3_1 (0xa << 4) +#define PWR_DOWN_LN_3_1_0 (0xb << 4) +#define PWR_DOWN_LN_MASK (0xf << 4) +#define PWR_DOWN_LN_SHIFT 4 +#define EDP4K2K_MODE_OVRD_EN (1 << 3) +#define EDP4K2K_MODE_OVRD_OPTIMIZED (1 << 2) + +#define ICL_PORT_CL_DW12(phy) _MMIO(_ICL_PORT_CL_DW(12, phy)) +#define ICL_LANE_ENABLE_AUX (1 << 0) + +/* ICL Port COMP_DW registers */ +#define _ICL_PORT_COMP 0x100 +#define _ICL_PORT_COMP_DW(dw, phy) (_ICL_COMBOPHY(phy) + \ + _ICL_PORT_COMP + 4 * (dw)) + +#define ICL_PORT_COMP_DW0(phy) _MMIO(_ICL_PORT_COMP_DW(0, phy)) +#define COMP_INIT (1 << 31) + +#define ICL_PORT_COMP_DW1(phy) _MMIO(_ICL_PORT_COMP_DW(1, phy)) + +#define ICL_PORT_COMP_DW3(phy) _MMIO(_ICL_PORT_COMP_DW(3, phy)) +#define PROCESS_INFO_DOT_0 (0 << 26) +#define PROCESS_INFO_DOT_1 (1 << 26) +#define PROCESS_INFO_DOT_4 (2 << 26) +#define PROCESS_INFO_MASK (7 << 26) +#define PROCESS_INFO_SHIFT 26 +#define VOLTAGE_INFO_0_85V (0 << 24) +#define VOLTAGE_INFO_0_95V (1 << 24) +#define VOLTAGE_INFO_1_05V (2 << 24) +#define VOLTAGE_INFO_MASK (3 << 24) +#define VOLTAGE_INFO_SHIFT 24 + +#define ICL_PORT_COMP_DW8(phy) _MMIO(_ICL_PORT_COMP_DW(8, phy)) +#define IREFGEN (1 << 24) + +#define ICL_PORT_COMP_DW9(phy) _MMIO(_ICL_PORT_COMP_DW(9, phy)) + +#define ICL_PORT_COMP_DW10(phy) _MMIO(_ICL_PORT_COMP_DW(10, phy)) + +/* ICL Port PCS registers */ +#define _ICL_PORT_PCS_AUX 0x300 +#define _ICL_PORT_PCS_GRP 0x600 +#define _ICL_PORT_PCS_LN(ln) (0x800 + (ln) * 0x100) +#define _ICL_PORT_PCS_DW_AUX(dw, phy) (_ICL_COMBOPHY(phy) + \ + _ICL_PORT_PCS_AUX + 4 * (dw)) +#define _ICL_PORT_PCS_DW_GRP(dw, phy) (_ICL_COMBOPHY(phy) + \ + _ICL_PORT_PCS_GRP + 4 * (dw)) +#define _ICL_PORT_PCS_DW_LN(dw, ln, phy) (_ICL_COMBOPHY(phy) + \ + _ICL_PORT_PCS_LN(ln) + 4 * (dw)) +#define ICL_PORT_PCS_DW1_AUX(phy) _MMIO(_ICL_PORT_PCS_DW_AUX(1, phy)) +#define ICL_PORT_PCS_DW1_GRP(phy) _MMIO(_ICL_PORT_PCS_DW_GRP(1, phy)) +#define ICL_PORT_PCS_DW1_LN(ln, phy) _MMIO(_ICL_PORT_PCS_DW_LN(1, ln, phy)) +#define DCC_MODE_SELECT_MASK (0x3 << 20) +#define DCC_MODE_SELECT_CONTINUOSLY (0x3 << 20) +#define COMMON_KEEPER_EN (1 << 26) +#define LATENCY_OPTIM_MASK (0x3 << 2) +#define LATENCY_OPTIM_VAL(x) ((x) << 2) + +/* ICL Port TX registers */ +#define _ICL_PORT_TX_AUX 0x380 +#define _ICL_PORT_TX_GRP 0x680 +#define _ICL_PORT_TX_LN(ln) (0x880 + (ln) * 0x100) + +#define _ICL_PORT_TX_DW_AUX(dw, phy) (_ICL_COMBOPHY(phy) + \ + _ICL_PORT_TX_AUX + 4 * (dw)) +#define _ICL_PORT_TX_DW_GRP(dw, phy) (_ICL_COMBOPHY(phy) + \ + _ICL_PORT_TX_GRP + 4 * (dw)) +#define _ICL_PORT_TX_DW_LN(dw, ln, phy) (_ICL_COMBOPHY(phy) + \ + _ICL_PORT_TX_LN(ln) + 4 * (dw)) + +#define ICL_PORT_TX_DW2_AUX(phy) _MMIO(_ICL_PORT_TX_DW_AUX(2, phy)) +#define ICL_PORT_TX_DW2_GRP(phy) _MMIO(_ICL_PORT_TX_DW_GRP(2, phy)) +#define ICL_PORT_TX_DW2_LN(ln, phy) _MMIO(_ICL_PORT_TX_DW_LN(2, ln, phy)) +#define SWING_SEL_UPPER(x) (((x) >> 3) << 15) +#define SWING_SEL_UPPER_MASK (1 << 15) +#define SWING_SEL_LOWER(x) (((x) & 0x7) << 11) +#define SWING_SEL_LOWER_MASK (0x7 << 11) +#define FRC_LATENCY_OPTIM_MASK (0x7 << 8) +#define FRC_LATENCY_OPTIM_VAL(x) ((x) << 8) +#define RCOMP_SCALAR(x) ((x) << 0) +#define RCOMP_SCALAR_MASK (0xFF << 0) + +#define ICL_PORT_TX_DW4_AUX(phy) _MMIO(_ICL_PORT_TX_DW_AUX(4, phy)) +#define ICL_PORT_TX_DW4_GRP(phy) _MMIO(_ICL_PORT_TX_DW_GRP(4, phy)) +#define ICL_PORT_TX_DW4_LN(ln, phy) _MMIO(_ICL_PORT_TX_DW_LN(4, ln, phy)) +#define LOADGEN_SELECT (1 << 31) +#define POST_CURSOR_1(x) ((x) << 12) +#define POST_CURSOR_1_MASK (0x3F << 12) +#define POST_CURSOR_2(x) ((x) << 6) +#define POST_CURSOR_2_MASK (0x3F << 6) +#define CURSOR_COEFF(x) ((x) << 0) +#define CURSOR_COEFF_MASK (0x3F << 0) + +#define ICL_PORT_TX_DW5_AUX(phy) _MMIO(_ICL_PORT_TX_DW_AUX(5, phy)) +#define ICL_PORT_TX_DW5_GRP(phy) _MMIO(_ICL_PORT_TX_DW_GRP(5, phy)) +#define ICL_PORT_TX_DW5_LN(ln, phy) _MMIO(_ICL_PORT_TX_DW_LN(5, ln, phy)) +#define TX_TRAINING_EN (1 << 31) +#define TAP2_DISABLE (1 << 30) +#define TAP3_DISABLE (1 << 29) +#define SCALING_MODE_SEL(x) ((x) << 18) +#define SCALING_MODE_SEL_MASK (0x7 << 18) +#define RTERM_SELECT(x) ((x) << 3) +#define RTERM_SELECT_MASK (0x7 << 3) + +#define ICL_PORT_TX_DW7_AUX(phy) _MMIO(_ICL_PORT_TX_DW_AUX(7, phy)) +#define ICL_PORT_TX_DW7_GRP(phy) _MMIO(_ICL_PORT_TX_DW_GRP(7, phy)) +#define ICL_PORT_TX_DW7_LN(ln, phy) _MMIO(_ICL_PORT_TX_DW_LN(7, ln, phy)) +#define N_SCALAR(x) ((x) << 24) +#define N_SCALAR_MASK (0x7F << 24) + +#define ICL_PORT_TX_DW8_AUX(phy) _MMIO(_ICL_PORT_TX_DW_AUX(8, phy)) +#define ICL_PORT_TX_DW8_GRP(phy) _MMIO(_ICL_PORT_TX_DW_GRP(8, phy)) +#define ICL_PORT_TX_DW8_LN(ln, phy) _MMIO(_ICL_PORT_TX_DW_LN(8, ln, phy)) +#define ICL_PORT_TX_DW8_ODCC_CLK_SEL REG_BIT(31) +#define ICL_PORT_TX_DW8_ODCC_CLK_DIV_SEL_MASK REG_GENMASK(30, 29) +#define ICL_PORT_TX_DW8_ODCC_CLK_DIV_SEL_DIV2 REG_FIELD_PREP(ICL_PORT_TX_DW8_ODCC_CLK_DIV_SEL_MASK, 0x1) + +#define _ICL_DPHY_CHKN_REG 0x194 +#define ICL_DPHY_CHKN(port) _MMIO(_ICL_COMBOPHY(port) + _ICL_DPHY_CHKN_REG) +#define ICL_DPHY_CHKN_AFE_OVER_PPI_STRAP REG_BIT(7) + +#endif /* __INTEL_COMBO_PHY_REGS__ */ diff --git a/drivers/gpu/drm/i915/display/intel_crt.h b/drivers/gpu/drm/i915/display/intel_crt.h index 6c5c44600cbd..c6071efd93ce 100644 --- a/drivers/gpu/drm/i915/display/intel_crt.h +++ b/drivers/gpu/drm/i915/display/intel_crt.h @@ -6,7 +6,7 @@ #ifndef __INTEL_CRT_H__ #define __INTEL_CRT_H__ -#include "i915_reg.h" +#include "i915_reg_defs.h" enum pipe; struct drm_encoder; diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index 16c3ca66d9f0..08ee3e17ee5c 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -12,6 +12,7 @@ #include #include +#include "i915_irq.h" #include "i915_vgpu.h" #include "i9xx_plane.h" #include "icl_dsi.h" diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index 16d34685d83f..2ade8fdd9bdd 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -51,16 +51,16 @@ static u32 intel_cursor_position(const struct intel_plane_state *plane_state) u32 pos = 0; if (x < 0) { - pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT; + pos |= CURSOR_POS_X_SIGN; x = -x; } - pos |= x << CURSOR_X_SHIFT; + pos |= CURSOR_POS_X(x); if (y < 0) { - pos |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT; + pos |= CURSOR_POS_Y_SIGN; y = -y; } - pos |= y << CURSOR_Y_SHIFT; + pos |= CURSOR_POS_Y(y); return pos; } @@ -180,7 +180,7 @@ static u32 i845_cursor_ctl_crtc(const struct intel_crtc_state *crtc_state) u32 cntl = 0; if (crtc_state->gamma_enable) - cntl |= CURSOR_GAMMA_ENABLE; + cntl |= CURSOR_PIPE_GAMMA_ENABLE; return cntl; } @@ -264,7 +264,7 @@ static void i845_cursor_update_arm(struct intel_plane *plane, cntl = plane_state->ctl | i845_cursor_ctl_crtc(crtc_state); - size = (height << 12) | width; + size = CURSOR_HEIGHT(height) | CURSOR_WIDTH(width); base = intel_cursor_base(plane_state); pos = intel_cursor_position(plane_state); @@ -280,7 +280,7 @@ static void i845_cursor_update_arm(struct intel_plane *plane, plane->cursor.cntl != cntl) { intel_de_write_fw(dev_priv, CURCNTR(PIPE_A), 0); intel_de_write_fw(dev_priv, CURBASE(PIPE_A), base); - intel_de_write_fw(dev_priv, CURSIZE, size); + intel_de_write_fw(dev_priv, CURSIZE(PIPE_A), size); intel_de_write_fw(dev_priv, CURPOS(PIPE_A), pos); intel_de_write_fw(dev_priv, CURCNTR(PIPE_A), cntl); @@ -340,13 +340,13 @@ static u32 i9xx_cursor_ctl_crtc(const struct intel_crtc_state *crtc_state) return cntl; if (crtc_state->gamma_enable) - cntl = MCURSOR_GAMMA_ENABLE; + cntl = MCURSOR_PIPE_GAMMA_ENABLE; if (crtc_state->csc_enable) cntl |= MCURSOR_PIPE_CSC_ENABLE; if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv)) - cntl |= MCURSOR_PIPE_SELECT(crtc->pipe); + cntl |= MCURSOR_PIPE_SEL(crtc->pipe); return cntl; } @@ -502,7 +502,7 @@ static void i9xx_cursor_update_arm(struct intel_plane *plane, i9xx_cursor_ctl_crtc(crtc_state); if (width != height) - fbc_ctl = CUR_FBC_CTL_EN | (height - 1); + fbc_ctl = CUR_FBC_EN | CUR_FBC_HEIGHT(height - 1); base = intel_cursor_base(plane_state); pos = intel_cursor_position(plane_state); @@ -586,13 +586,12 @@ static bool i9xx_cursor_get_hw_state(struct intel_plane *plane, val = intel_de_read(dev_priv, CURCNTR(plane->pipe)); - ret = val & MCURSOR_MODE; + ret = val & MCURSOR_MODE_MASK; if (DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv)) *pipe = plane->pipe; else - *pipe = (val & MCURSOR_PIPE_SELECT_MASK) >> - MCURSOR_PIPE_SELECT_SHIFT; + *pipe = REG_FIELD_GET(MCURSOR_PIPE_SEL_MASK, val); intel_display_power_put(dev_priv, power_domain, wakeref); diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index cab505277595..354b08d6f81d 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -32,6 +32,7 @@ #include "intel_audio.h" #include "intel_backlight.h" #include "intel_combo_phy.h" +#include "intel_combo_phy_regs.h" #include "intel_connector.h" #include "intel_crtc.h" #include "intel_ddi.h" @@ -56,6 +57,7 @@ #include "intel_snps_phy.h" #include "intel_sprite.h" #include "intel_tc.h" +#include "intel_tc_phy_regs.h" #include "intel_vdsc.h" #include "intel_vrr.h" #include "skl_scaler.h" @@ -2287,116 +2289,6 @@ static void intel_ddi_mso_configure(const struct intel_crtc_state *crtc_state) OVERLAP_PIXELS_MASK, dss1); } -static void dg2_ddi_pre_enable_dp(struct intel_atomic_state *state, - struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state) -{ - struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - struct intel_digital_port *dig_port = enc_to_dig_port(encoder); - bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST); - - intel_dp_set_link_params(intel_dp, crtc_state->port_clock, - crtc_state->lane_count); - - /* - * We only configure what the register value will be here. Actual - * enabling happens during link training farther down. - */ - intel_ddi_init_dp_buf_reg(encoder, crtc_state); - - /* - * 1. Enable Power Wells - * - * This was handled at the beginning of intel_atomic_commit_tail(), - * before we called down into this function. - */ - - /* 2. Enable Panel Power if PPS is required */ - intel_pps_on(intel_dp); - - /* - * 3. Enable the port PLL. - */ - intel_ddi_enable_clock(encoder, crtc_state); - - /* 4. Enable IO power */ - if (!intel_tc_port_in_tbt_alt_mode(dig_port)) - dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv, - dig_port->ddi_io_power_domain); - - /* - * 5. The rest of the below are substeps under the bspec's "Enable and - * Train Display Port" step. Note that steps that are specific to - * MST will be handled by intel_mst_pre_enable_dp() before/after it - * calls into this function. Also intel_mst_pre_enable_dp() only calls - * us when active_mst_links==0, so any steps designated for "single - * stream or multi-stream master transcoder" can just be performed - * unconditionally here. - */ - - /* - * 5.a Configure Transcoder Clock Select to direct the Port clock to the - * Transcoder. - */ - intel_ddi_enable_pipe_clock(encoder, crtc_state); - - /* 5.b Configure transcoder for DP 2.0 128b/132b */ - intel_ddi_config_transcoder_dp2(encoder, crtc_state); - - /* - * 5.c Configure TRANS_DDI_FUNC_CTL DDI Select, DDI Mode Select & MST - * Transport Select - */ - intel_ddi_config_transcoder_func(encoder, crtc_state); - - /* - * 5.d Configure & enable DP_TP_CTL with link training pattern 1 - * selected - * - * This will be handled by the intel_dp_start_link_train() farther - * down this function. - */ - - /* 5.e Configure voltage swing and related IO settings */ - encoder->set_signal_levels(encoder, crtc_state); - - if (!is_mst) - intel_dp_set_power(intel_dp, DP_SET_POWER_D0); - - intel_dp_configure_protocol_converter(intel_dp, crtc_state); - intel_dp_sink_set_decompression_state(intel_dp, crtc_state, true); - /* - * DDI FEC: "anticipates enabling FEC encoding sets the FEC_READY bit - * in the FEC_CONFIGURATION register to 1 before initiating link - * training - */ - intel_dp_sink_set_fec_ready(intel_dp, crtc_state); - intel_dp_check_frl_training(intel_dp); - intel_dp_pcon_dsc_configure(intel_dp, crtc_state); - - /* - * 5.h Follow DisplayPort specification training sequence (see notes for - * failure handling) - * 5.i If DisplayPort multi-stream - Set DP_TP_CTL link training to Idle - * Pattern, wait for 5 idle patterns (DP_TP_STATUS Min_Idles_Sent) - * (timeout after 800 us) - */ - intel_dp_start_link_train(intel_dp, crtc_state); - - /* 5.j Set DP_TP_CTL link training to Normal */ - if (!is_trans_port_sync_mode(crtc_state)) - intel_dp_stop_link_train(intel_dp, crtc_state); - - /* 5.k Configure and enable FEC if needed */ - intel_ddi_enable_fec(encoder, crtc_state); - - intel_dsc_dp_pps_write(encoder, crtc_state); - - intel_dsc_enable(crtc_state); -} - static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state, struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state, @@ -2470,6 +2362,9 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state, */ intel_ddi_enable_pipe_clock(encoder, crtc_state); + if (HAS_DP20(dev_priv)) + intel_ddi_config_transcoder_dp2(encoder, crtc_state); + /* * 7.b Configure TRANS_DDI_FUNC_CTL DDI Select, DDI Mode Select & MST * Transport Select @@ -2530,9 +2425,6 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state, intel_ddi_enable_fec(encoder, crtc_state); intel_dsc_dp_pps_write(encoder, crtc_state); - - if (!crtc_state->bigjoiner) - intel_dsc_enable(crtc_state); } static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state, @@ -2598,9 +2490,6 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state, intel_ddi_enable_pipe_clock(encoder, crtc_state); intel_dsc_dp_pps_write(encoder, crtc_state); - - if (!crtc_state->bigjoiner) - intel_dsc_enable(crtc_state); } static void intel_ddi_pre_enable_dp(struct intel_atomic_state *state, @@ -2610,9 +2499,7 @@ static void intel_ddi_pre_enable_dp(struct intel_atomic_state *state, { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - if (IS_DG2(dev_priv)) - dg2_ddi_pre_enable_dp(state, encoder, crtc_state, conn_state); - else if (DISPLAY_VER(dev_priv) >= 12) + if (DISPLAY_VER(dev_priv) >= 12) tgl_ddi_pre_enable_dp(state, encoder, crtc_state, conn_state); else hsw_ddi_pre_enable_dp(state, encoder, crtc_state, conn_state); @@ -2620,11 +2507,8 @@ static void intel_ddi_pre_enable_dp(struct intel_atomic_state *state, /* MST will call a setting of MSA after an allocating of Virtual Channel * from MST encoder pre_enable callback. */ - if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) { + if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) intel_ddi_set_dp_msa(crtc_state, conn_state); - - intel_dp_set_m_n(crtc_state, M1_N1); - } } static void intel_ddi_pre_enable_hdmi(struct intel_atomic_state *state, @@ -3471,7 +3355,11 @@ static void intel_ddi_read_func_ctl(struct intel_encoder *encoder, pipe_config->output_types |= BIT(INTEL_OUTPUT_DP); pipe_config->lane_count = ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1; - intel_dp_get_m_n(crtc, pipe_config); + + intel_cpu_transcoder_get_m1_n1(crtc, cpu_transcoder, + &pipe_config->dp_m_n); + intel_cpu_transcoder_get_m2_n2(crtc, cpu_transcoder, + &pipe_config->dp_m2_n2); if (DISPLAY_VER(dev_priv) >= 11) { i915_reg_t dp_tp_ctl = dp_tp_ctl_reg(encoder, pipe_config); @@ -3508,7 +3396,8 @@ static void intel_ddi_read_func_ctl(struct intel_encoder *encoder, pipe_config->mst_master_transcoder = REG_FIELD_GET(TRANS_DDI_MST_TRANSPORT_SELECT_MASK, temp); - intel_dp_get_m_n(crtc, pipe_config); + intel_cpu_transcoder_get_m1_n1(crtc, cpu_transcoder, + &pipe_config->dp_m_n); pipe_config->infoframes.enable |= intel_hdmi_infoframes_enabled(encoder, pipe_config); @@ -3797,8 +3686,8 @@ static bool m_n_equal(const struct intel_link_m_n *m_n_1, const struct intel_link_m_n *m_n_2) { return m_n_1->tu == m_n_2->tu && - m_n_1->gmch_m == m_n_2->gmch_m && - m_n_1->gmch_n == m_n_2->gmch_n && + m_n_1->data_m == m_n_2->data_m && + m_n_1->data_n == m_n_2->data_n && m_n_1->link_m == m_n_2->link_m && m_n_1->link_n == m_n_2->link_n; } diff --git a/drivers/gpu/drm/i915/display/intel_ddi.h b/drivers/gpu/drm/i915/display/intel_ddi.h index c2fea6562917..d39076facdce 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.h +++ b/drivers/gpu/drm/i915/display/intel_ddi.h @@ -6,7 +6,7 @@ #ifndef __INTEL_DDI_H__ #define __INTEL_DDI_H__ -#include "i915_reg.h" +#include "i915_reg_defs.h" struct drm_connector_state; struct drm_i915_private; diff --git a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c index e2dfb93a82bd..0c32210bf503 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c +++ b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c @@ -985,15 +985,15 @@ static const struct intel_ddi_buf_trans adlp_dkl_phy_trans_dp_hbr2_hbr3 = { }; static const union intel_ddi_buf_trans_entry _dg2_snps_trans[] = { - { .snps = { 26, 0, 0 } }, /* VS 0, pre-emph 0 */ - { .snps = { 33, 0, 6 } }, /* VS 0, pre-emph 1 */ - { .snps = { 38, 0, 12 } }, /* VS 0, pre-emph 2 */ - { .snps = { 43, 0, 19 } }, /* VS 0, pre-emph 3 */ - { .snps = { 39, 0, 0 } }, /* VS 1, pre-emph 0 */ - { .snps = { 44, 0, 8 } }, /* VS 1, pre-emph 1 */ - { .snps = { 47, 0, 15 } }, /* VS 1, pre-emph 2 */ - { .snps = { 52, 0, 0 } }, /* VS 2, pre-emph 0 */ - { .snps = { 51, 0, 10 } }, /* VS 2, pre-emph 1 */ + { .snps = { 25, 0, 0 } }, /* VS 0, pre-emph 0 */ + { .snps = { 32, 0, 6 } }, /* VS 0, pre-emph 1 */ + { .snps = { 35, 0, 10 } }, /* VS 0, pre-emph 2 */ + { .snps = { 43, 0, 17 } }, /* VS 0, pre-emph 3 */ + { .snps = { 35, 0, 0 } }, /* VS 1, pre-emph 0 */ + { .snps = { 45, 0, 8 } }, /* VS 1, pre-emph 1 */ + { .snps = { 48, 0, 14 } }, /* VS 1, pre-emph 2 */ + { .snps = { 47, 0, 0 } }, /* VS 2, pre-emph 0 */ + { .snps = { 55, 0, 7 } }, /* VS 2, pre-emph 1 */ { .snps = { 62, 0, 0 } }, /* VS 3, pre-emph 0 */ }; @@ -1005,21 +1005,21 @@ static const struct intel_ddi_buf_trans dg2_snps_trans = { static const union intel_ddi_buf_trans_entry _dg2_snps_trans_uhbr[] = { { .snps = { 62, 0, 0 } }, /* preset 0 */ - { .snps = { 56, 0, 6 } }, /* preset 1 */ - { .snps = { 51, 0, 11 } }, /* preset 2 */ - { .snps = { 48, 0, 14 } }, /* preset 3 */ - { .snps = { 43, 0, 19 } }, /* preset 4 */ + { .snps = { 55, 0, 7 } }, /* preset 1 */ + { .snps = { 50, 0, 12 } }, /* preset 2 */ + { .snps = { 44, 0, 18 } }, /* preset 3 */ + { .snps = { 35, 0, 21 } }, /* preset 4 */ { .snps = { 59, 3, 0 } }, /* preset 5 */ { .snps = { 53, 3, 6 } }, /* preset 6 */ - { .snps = { 49, 3, 10 } }, /* preset 7 */ - { .snps = { 45, 3, 14 } }, /* preset 8 */ - { .snps = { 42, 3, 17 } }, /* preset 9 */ + { .snps = { 48, 3, 11 } }, /* preset 7 */ + { .snps = { 42, 5, 15 } }, /* preset 8 */ + { .snps = { 37, 5, 20 } }, /* preset 9 */ { .snps = { 56, 6, 0 } }, /* preset 10 */ - { .snps = { 50, 6, 6 } }, /* preset 11 */ - { .snps = { 47, 6, 9 } }, /* preset 12 */ - { .snps = { 42, 6, 14 } }, /* preset 13 */ - { .snps = { 46, 8, 8 } }, /* preset 14 */ - { .snps = { 56, 3, 3 } }, /* preset 15 */ + { .snps = { 48, 7, 7 } }, /* preset 11 */ + { .snps = { 45, 7, 10 } }, /* preset 12 */ + { .snps = { 39, 8, 15 } }, /* preset 13 */ + { .snps = { 48, 14, 0 } }, /* preset 14 */ + { .snps = { 45, 4, 4 } }, /* preset 15 */ }; static const struct intel_ddi_buf_trans dg2_snps_trans_uhbr = { diff --git a/drivers/gpu/drm/i915/display/intel_de.h b/drivers/gpu/drm/i915/display/intel_de.h index 9d8c177aa228..9c104f65e4c8 100644 --- a/drivers/gpu/drm/i915/display/intel_de.h +++ b/drivers/gpu/drm/i915/display/intel_de.h @@ -7,7 +7,6 @@ #define __INTEL_DE_H__ #include "i915_drv.h" -#include "i915_reg.h" #include "i915_trace.h" #include "intel_uncore.h" diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 7d558217ca16..7f512f9e9e5c 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -118,9 +118,6 @@ static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_state); static void intel_set_pipe_src_size(const struct intel_crtc_state *crtc_state); -static void intel_cpu_transcoder_set_m_n(const struct intel_crtc_state *crtc_state, - const struct intel_link_m_n *m_n, - const struct intel_link_m_n *m2_n2); static void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state); static void ilk_set_pipeconf(const struct intel_crtc_state *crtc_state); static void hsw_set_transconf(const struct intel_crtc_state *crtc_state); @@ -353,16 +350,10 @@ static bool pipe_scanline_is_moving(struct drm_i915_private *dev_priv, { i915_reg_t reg = PIPEDSL(pipe); u32 line1, line2; - u32 line_mask; - if (DISPLAY_VER(dev_priv) == 2) - line_mask = DSL_LINEMASK_GEN2; - else - line_mask = DSL_LINEMASK_GEN3; - - line1 = intel_de_read(dev_priv, reg) & line_mask; + line1 = intel_de_read(dev_priv, reg) & PIPEDSL_LINE_MASK; msleep(5); - line2 = intel_de_read(dev_priv, reg) & line_mask; + line2 = intel_de_read(dev_priv, reg) & PIPEDSL_LINE_MASK; return line1 != line2; } @@ -397,13 +388,11 @@ intel_wait_for_pipe_off(const struct intel_crtc_state *old_crtc_state) if (DISPLAY_VER(dev_priv) >= 4) { enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder; - i915_reg_t reg = PIPECONF(cpu_transcoder); /* Wait for the Pipe State to go off */ - if (intel_de_wait_for_clear(dev_priv, reg, - I965_PIPECONF_ACTIVE, 100)) - drm_WARN(&dev_priv->drm, 1, - "pipe_off wait timed out\n"); + if (intel_de_wait_for_clear(dev_priv, PIPECONF(cpu_transcoder), + PIPECONF_STATE_ENABLE, 100)) + drm_WARN(&dev_priv->drm, 1, "pipe_off wait timed out\n"); } else { intel_wait_for_pipe_scanline_stopped(crtc); } @@ -1118,8 +1107,8 @@ void hsw_enable_ips(const struct intel_crtc_state *crtc_state) drm_WARN_ON(dev, !(crtc_state->active_planes & ~BIT(PLANE_CURSOR))); if (IS_BROADWELL(dev_priv)) { - drm_WARN_ON(dev, sandybridge_pcode_write(dev_priv, DISPLAY_IPS_CONTROL, - IPS_ENABLE | IPS_PCODE_CONTROL)); + drm_WARN_ON(dev, snb_pcode_write(dev_priv, DISPLAY_IPS_CONTROL, + IPS_ENABLE | IPS_PCODE_CONTROL)); /* Quoting Art Runyan: "its not safe to expect any particular * value in IPS_CTL bit 31 after enabling IPS through the * mailbox." Moreover, the mailbox may return a bogus state, @@ -1149,7 +1138,7 @@ void hsw_disable_ips(const struct intel_crtc_state *crtc_state) if (IS_BROADWELL(dev_priv)) { drm_WARN_ON(dev, - sandybridge_pcode_write(dev_priv, DISPLAY_IPS_CONTROL, 0)); + snb_pcode_write(dev_priv, DISPLAY_IPS_CONTROL, 0)); /* * Wait for PCODE to finish disabling IPS. The BSpec specified * 42ms timeout value leads to occasional timeouts so use 100ms @@ -1369,7 +1358,8 @@ static void intel_crtc_enable_flip_done(struct intel_atomic_state *state, for_each_new_intel_plane_in_state(state, plane, plane_state, i) { if (plane->enable_flip_done && plane->pipe == crtc->pipe && - update_planes & BIT(plane->id)) + update_planes & BIT(plane->id) && + plane_state->do_async_flip) plane->enable_flip_done(plane); } } @@ -1387,7 +1377,8 @@ static void intel_crtc_disable_flip_done(struct intel_atomic_state *state, for_each_new_intel_plane_in_state(state, plane, plane_state, i) { if (plane->disable_flip_done && plane->pipe == crtc->pipe && - update_planes & BIT(plane->id)) + update_planes & BIT(plane->id) && + plane_state->do_async_flip) plane->disable_flip_done(plane); } } @@ -1817,6 +1808,26 @@ static void intel_disable_primary_plane(const struct intel_crtc_state *crtc_stat plane->disable_arm(plane, crtc_state); } +static void ilk_configure_cpu_transcoder(const struct intel_crtc_state *crtc_state) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; + + if (crtc_state->has_pch_encoder) { + intel_cpu_transcoder_set_m1_n1(crtc, cpu_transcoder, + &crtc_state->fdi_m_n); + } else if (intel_crtc_has_dp_encoder(crtc_state)) { + intel_cpu_transcoder_set_m1_n1(crtc, cpu_transcoder, + &crtc_state->dp_m_n); + intel_cpu_transcoder_set_m2_n2(crtc, cpu_transcoder, + &crtc_state->dp_m2_n2); + } + + intel_set_transcoder_timings(crtc_state); + + ilk_set_pipeconf(crtc_state); +} + static void ilk_crtc_enable(struct intel_atomic_state *state, struct intel_crtc *crtc) { @@ -1841,27 +1852,16 @@ static void ilk_crtc_enable(struct intel_atomic_state *state, intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false); intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, false); - if (intel_crtc_has_dp_encoder(new_crtc_state)) - intel_dp_set_m_n(new_crtc_state, M1_N1); + ilk_configure_cpu_transcoder(new_crtc_state); - intel_set_transcoder_timings(new_crtc_state); intel_set_pipe_src_size(new_crtc_state); - if (new_crtc_state->has_pch_encoder) - intel_cpu_transcoder_set_m_n(new_crtc_state, - &new_crtc_state->fdi_m_n, NULL); - - ilk_set_pipeconf(new_crtc_state); - crtc->active = true; intel_encoders_pre_enable(state, crtc); if (new_crtc_state->has_pch_encoder) { - /* Note: FDI PLL enabling _must_ be done before we enable the - * cpu pipes, hence this is separate from all the other fdi/pch - * enabling. */ - ilk_fdi_pll_enable(new_crtc_state); + ilk_pch_pre_enable(state, crtc); } else { assert_fdi_tx_disabled(dev_priv, pipe); assert_fdi_rx_disabled(dev_priv, pipe); @@ -1974,7 +1974,6 @@ static void hsw_set_frame_start_delay(const struct intel_crtc_state *crtc_state) static void icl_ddi_bigjoiner_pre_enable(struct intel_atomic_state *state, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(state->base.dev); struct intel_crtc_state *master_crtc_state; struct intel_crtc *master_crtc; struct drm_connector_state *conn_state; @@ -2004,12 +2003,33 @@ static void icl_ddi_bigjoiner_pre_enable(struct intel_atomic_state *state, if (crtc_state->bigjoiner_slave) intel_encoders_pre_enable(state, master_crtc); +} - /* need to enable VDSC, which we skipped in pre-enable */ - intel_dsc_enable(crtc_state); +static void hsw_configure_cpu_transcoder(const struct intel_crtc_state *crtc_state) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; - if (DISPLAY_VER(dev_priv) >= 13) - intel_uncompressed_joiner_enable(crtc_state); + if (crtc_state->has_pch_encoder) { + intel_cpu_transcoder_set_m1_n1(crtc, cpu_transcoder, + &crtc_state->fdi_m_n); + } else if (intel_crtc_has_dp_encoder(crtc_state)) { + intel_cpu_transcoder_set_m1_n1(crtc, cpu_transcoder, + &crtc_state->dp_m_n); + intel_cpu_transcoder_set_m2_n2(crtc, cpu_transcoder, + &crtc_state->dp_m2_n2); + } + + intel_set_transcoder_timings(crtc_state); + + if (cpu_transcoder != TRANSCODER_EDP) + intel_de_write(dev_priv, PIPE_MULT(cpu_transcoder), + crtc_state->pixel_multiplier - 1); + + hsw_set_frame_start_delay(crtc_state); + + hsw_set_transconf(crtc_state); } static void hsw_crtc_enable(struct intel_atomic_state *state, @@ -2036,25 +2056,17 @@ static void hsw_crtc_enable(struct intel_atomic_state *state, icl_ddi_bigjoiner_pre_enable(state, new_crtc_state); } + intel_dsc_enable(new_crtc_state); + + if (DISPLAY_VER(dev_priv) >= 13) + intel_uncompressed_joiner_enable(new_crtc_state); + intel_set_pipe_src_size(new_crtc_state); if (DISPLAY_VER(dev_priv) >= 9 || IS_BROADWELL(dev_priv)) bdw_set_pipemisc(new_crtc_state); - if (!new_crtc_state->bigjoiner_slave && !transcoder_is_dsi(cpu_transcoder)) { - intel_set_transcoder_timings(new_crtc_state); - - if (cpu_transcoder != TRANSCODER_EDP) - intel_de_write(dev_priv, PIPE_MULT(cpu_transcoder), - new_crtc_state->pixel_multiplier - 1); - - if (new_crtc_state->has_pch_encoder) - intel_cpu_transcoder_set_m_n(new_crtc_state, - &new_crtc_state->fdi_m_n, NULL); - - hsw_set_frame_start_delay(new_crtc_state); - - hsw_set_transconf(new_crtc_state); - } + if (!new_crtc_state->bigjoiner_slave && !transcoder_is_dsi(cpu_transcoder)) + hsw_configure_cpu_transcoder(new_crtc_state); crtc->active = true; @@ -2441,6 +2453,23 @@ static void modeset_put_crtc_power_domains(struct intel_crtc *crtc, domains); } +static void i9xx_configure_cpu_transcoder(const struct intel_crtc_state *crtc_state) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; + + if (intel_crtc_has_dp_encoder(crtc_state)) { + intel_cpu_transcoder_set_m1_n1(crtc, cpu_transcoder, + &crtc_state->dp_m_n); + intel_cpu_transcoder_set_m2_n2(crtc, cpu_transcoder, + &crtc_state->dp_m2_n2); + } + + intel_set_transcoder_timings(crtc_state); + + i9xx_set_pipeconf(crtc_state); +} + static void valleyview_crtc_enable(struct intel_atomic_state *state, struct intel_crtc *crtc) { @@ -2452,10 +2481,8 @@ static void valleyview_crtc_enable(struct intel_atomic_state *state, if (drm_WARN_ON(&dev_priv->drm, crtc->active)) return; - if (intel_crtc_has_dp_encoder(new_crtc_state)) - intel_dp_set_m_n(new_crtc_state, M1_N1); + i9xx_configure_cpu_transcoder(new_crtc_state); - intel_set_transcoder_timings(new_crtc_state); intel_set_pipe_src_size(new_crtc_state); if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) { @@ -2463,8 +2490,6 @@ static void valleyview_crtc_enable(struct intel_atomic_state *state, intel_de_write(dev_priv, CHV_CANVAS(pipe), 0); } - i9xx_set_pipeconf(new_crtc_state); - crtc->active = true; intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); @@ -2504,14 +2529,10 @@ static void i9xx_crtc_enable(struct intel_atomic_state *state, if (drm_WARN_ON(&dev_priv->drm, crtc->active)) return; - if (intel_crtc_has_dp_encoder(new_crtc_state)) - intel_dp_set_m_n(new_crtc_state, M1_N1); + i9xx_configure_cpu_transcoder(new_crtc_state); - intel_set_transcoder_timings(new_crtc_state); intel_set_pipe_src_size(new_crtc_state); - i9xx_set_pipeconf(new_crtc_state); - crtc->active = true; if (DISPLAY_VER(dev_priv) != 2) @@ -3085,7 +3106,7 @@ intel_link_compute_m_n(u16 bits_per_pixel, int nlanes, m_n->tu = 64; compute_m_n(data_clock, link_clock * nlanes * 8, - &m_n->gmch_m, &m_n->gmch_n, + &m_n->data_m, &m_n->data_n, constant_n); compute_m_n(pixel_clock, link_clock, @@ -3116,99 +3137,66 @@ static void intel_panel_sanitize_ssc(struct drm_i915_private *dev_priv) } } -static void intel_pch_transcoder_set_m_n(const struct intel_crtc_state *crtc_state, - const struct intel_link_m_n *m_n) +void intel_zero_m_n(struct intel_link_m_n *m_n) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - enum pipe pipe = crtc->pipe; - - intel_de_write(dev_priv, PCH_TRANS_DATA_M1(pipe), - TU_SIZE(m_n->tu) | m_n->gmch_m); - intel_de_write(dev_priv, PCH_TRANS_DATA_N1(pipe), m_n->gmch_n); - intel_de_write(dev_priv, PCH_TRANS_LINK_M1(pipe), m_n->link_m); - intel_de_write(dev_priv, PCH_TRANS_LINK_N1(pipe), m_n->link_n); + /* corresponds to 0 register value */ + memset(m_n, 0, sizeof(*m_n)); + m_n->tu = 1; } -static bool transcoder_has_m2_n2(struct drm_i915_private *dev_priv, - enum transcoder transcoder) +void intel_set_m_n(struct drm_i915_private *i915, + const struct intel_link_m_n *m_n, + i915_reg_t data_m_reg, i915_reg_t data_n_reg, + i915_reg_t link_m_reg, i915_reg_t link_n_reg) +{ + intel_de_write(i915, data_m_reg, TU_SIZE(m_n->tu) | m_n->data_m); + intel_de_write(i915, data_n_reg, m_n->data_n); + intel_de_write(i915, link_m_reg, m_n->link_m); + /* + * On BDW+ writing LINK_N arms the double buffered update + * of all the M/N registers, so it must be written last. + */ + intel_de_write(i915, link_n_reg, m_n->link_n); +} + +bool intel_cpu_transcoder_has_m2_n2(struct drm_i915_private *dev_priv, + enum transcoder transcoder) { if (IS_HASWELL(dev_priv)) return transcoder == TRANSCODER_EDP; - /* - * Strictly speaking some registers are available before - * gen7, but we only support DRRS on gen7+ - */ - return DISPLAY_VER(dev_priv) == 7 || IS_CHERRYVIEW(dev_priv); + return IS_DISPLAY_VER(dev_priv, 5, 7) || IS_CHERRYVIEW(dev_priv); } -static void intel_cpu_transcoder_set_m_n(const struct intel_crtc_state *crtc_state, - const struct intel_link_m_n *m_n, - const struct intel_link_m_n *m2_n2) +void intel_cpu_transcoder_set_m1_n1(struct intel_crtc *crtc, + enum transcoder transcoder, + const struct intel_link_m_n *m_n) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; - enum transcoder transcoder = crtc_state->cpu_transcoder; - if (DISPLAY_VER(dev_priv) >= 5) { - intel_de_write(dev_priv, PIPE_DATA_M1(transcoder), - TU_SIZE(m_n->tu) | m_n->gmch_m); - intel_de_write(dev_priv, PIPE_DATA_N1(transcoder), - m_n->gmch_n); - intel_de_write(dev_priv, PIPE_LINK_M1(transcoder), - m_n->link_m); - intel_de_write(dev_priv, PIPE_LINK_N1(transcoder), - m_n->link_n); - /* - * M2_N2 registers are set only if DRRS is supported - * (to make sure the registers are not unnecessarily accessed). - */ - if (m2_n2 && crtc_state->has_drrs && - transcoder_has_m2_n2(dev_priv, transcoder)) { - intel_de_write(dev_priv, PIPE_DATA_M2(transcoder), - TU_SIZE(m2_n2->tu) | m2_n2->gmch_m); - intel_de_write(dev_priv, PIPE_DATA_N2(transcoder), - m2_n2->gmch_n); - intel_de_write(dev_priv, PIPE_LINK_M2(transcoder), - m2_n2->link_m); - intel_de_write(dev_priv, PIPE_LINK_N2(transcoder), - m2_n2->link_n); - } - } else { - intel_de_write(dev_priv, PIPE_DATA_M_G4X(pipe), - TU_SIZE(m_n->tu) | m_n->gmch_m); - intel_de_write(dev_priv, PIPE_DATA_N_G4X(pipe), m_n->gmch_n); - intel_de_write(dev_priv, PIPE_LINK_M_G4X(pipe), m_n->link_m); - intel_de_write(dev_priv, PIPE_LINK_N_G4X(pipe), m_n->link_n); - } + if (DISPLAY_VER(dev_priv) >= 5) + intel_set_m_n(dev_priv, m_n, + PIPE_DATA_M1(transcoder), PIPE_DATA_N1(transcoder), + PIPE_LINK_M1(transcoder), PIPE_LINK_N1(transcoder)); + else + intel_set_m_n(dev_priv, m_n, + PIPE_DATA_M_G4X(pipe), PIPE_DATA_N_G4X(pipe), + PIPE_LINK_M_G4X(pipe), PIPE_LINK_N_G4X(pipe)); } -void intel_dp_set_m_n(const struct intel_crtc_state *crtc_state, enum link_m_n_set m_n) +void intel_cpu_transcoder_set_m2_n2(struct intel_crtc *crtc, + enum transcoder transcoder, + const struct intel_link_m_n *m_n) { - const struct intel_link_m_n *dp_m_n, *dp_m2_n2 = NULL; - struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - if (m_n == M1_N1) { - dp_m_n = &crtc_state->dp_m_n; - dp_m2_n2 = &crtc_state->dp_m2_n2; - } else if (m_n == M2_N2) { - - /* - * M2_N2 registers are not supported. Hence m2_n2 divider value - * needs to be programmed into M1_N1. - */ - dp_m_n = &crtc_state->dp_m2_n2; - } else { - drm_err(&i915->drm, "Unsupported divider value\n"); + if (!intel_cpu_transcoder_has_m2_n2(dev_priv, transcoder)) return; - } - if (crtc_state->has_pch_encoder) - intel_pch_transcoder_set_m_n(crtc_state, &crtc_state->dp_m_n); - else - intel_cpu_transcoder_set_m_n(crtc_state, dp_m_n, dp_m2_n2); + intel_set_m_n(dev_priv, m_n, + PIPE_DATA_M2(transcoder), PIPE_DATA_N2(transcoder), + PIPE_LINK_M2(transcoder), PIPE_LINK_N2(transcoder)); } static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_state) @@ -3279,7 +3267,8 @@ static void intel_set_pipe_src_size(const struct intel_crtc_state *crtc_state) * always be the user's requested size. */ intel_de_write(dev_priv, PIPESRC(pipe), - ((crtc_state->pipe_src_w - 1) << 16) | (crtc_state->pipe_src_h - 1)); + PIPESRC_WIDTH(crtc_state->pipe_src_w - 1) | + PIPESRC_HEIGHT(crtc_state->pipe_src_h - 1)); } static bool intel_pipe_is_interlaced(const struct intel_crtc_state *crtc_state) @@ -3350,8 +3339,8 @@ static void intel_get_pipe_src_size(struct intel_crtc *crtc, u32 tmp; tmp = intel_de_read(dev_priv, PIPESRC(crtc->pipe)); - pipe_config->pipe_src_h = (tmp & 0xffff) + 1; - pipe_config->pipe_src_w = ((tmp >> 16) & 0xffff) + 1; + pipe_config->pipe_src_w = REG_FIELD_GET(PIPESRC_WIDTH_MASK, tmp) + 1; + pipe_config->pipe_src_h = REG_FIELD_GET(PIPESRC_HEIGHT_MASK, tmp) + 1; } static void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state) @@ -3379,13 +3368,13 @@ static void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state) switch (crtc_state->pipe_bpp) { case 18: - pipeconf |= PIPECONF_6BPC; + pipeconf |= PIPECONF_BPC_6; break; case 24: - pipeconf |= PIPECONF_8BPC; + pipeconf |= PIPECONF_BPC_8; break; case 30: - pipeconf |= PIPECONF_10BPC; + pipeconf |= PIPECONF_BPC_10; break; default: /* Case prevented by intel_choose_pipe_bpp_dither. */ @@ -3400,7 +3389,7 @@ static void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state) else pipeconf |= PIPECONF_INTERLACE_W_SYNC_SHIFT; } else { - pipeconf |= PIPECONF_PROGRESSIVE; + pipeconf |= PIPECONF_INTERLACE_PROGRESSIVE; } if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) && @@ -3543,11 +3532,11 @@ static void i9xx_get_pipe_color_config(struct intel_crtc_state *crtc_state) tmp = intel_de_read(dev_priv, DSPCNTR(i9xx_plane)); - if (tmp & DISPPLANE_GAMMA_ENABLE) + if (tmp & DISP_PIPE_GAMMA_ENABLE) crtc_state->gamma_enable = true; if (!HAS_GMCH(dev_priv) && - tmp & DISPPLANE_PIPE_CSC_ENABLE) + tmp & DISP_PIPE_CSC_ENABLE) crtc_state->csc_enable = true; } @@ -3578,16 +3567,17 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, if (IS_G4X(dev_priv) || IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { switch (tmp & PIPECONF_BPC_MASK) { - case PIPECONF_6BPC: + case PIPECONF_BPC_6: pipe_config->pipe_bpp = 18; break; - case PIPECONF_8BPC: + case PIPECONF_BPC_8: pipe_config->pipe_bpp = 24; break; - case PIPECONF_10BPC: + case PIPECONF_BPC_10: pipe_config->pipe_bpp = 30; break; default: + MISSING_CASE(tmp); break; } } @@ -3596,8 +3586,7 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, (tmp & PIPECONF_COLOR_RANGE_SELECT)) pipe_config->limited_color_range = true; - pipe_config->gamma_mode = (tmp & PIPECONF_GAMMA_MODE_MASK_I9XX) >> - PIPECONF_GAMMA_MODE_SHIFT; + pipe_config->gamma_mode = REG_FIELD_GET(PIPECONF_GAMMA_MODE_MASK_I9XX, tmp); if (IS_CHERRYVIEW(dev_priv)) pipe_config->cgm_mode = intel_de_read(dev_priv, @@ -3684,16 +3673,16 @@ static void ilk_set_pipeconf(const struct intel_crtc_state *crtc_state) switch (crtc_state->pipe_bpp) { case 18: - val |= PIPECONF_6BPC; + val |= PIPECONF_BPC_6; break; case 24: - val |= PIPECONF_8BPC; + val |= PIPECONF_BPC_8; break; case 30: - val |= PIPECONF_10BPC; + val |= PIPECONF_BPC_10; break; case 36: - val |= PIPECONF_12BPC; + val |= PIPECONF_BPC_12; break; default: /* Case prevented by intel_choose_pipe_bpp_dither. */ @@ -3701,12 +3690,12 @@ static void ilk_set_pipeconf(const struct intel_crtc_state *crtc_state) } if (crtc_state->dither) - val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP); + val |= PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP; if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) - val |= PIPECONF_INTERLACED_ILK; + val |= PIPECONF_INTERLACE_IF_ID_ILK; else - val |= PIPECONF_PROGRESSIVE; + val |= PIPECONF_INTERLACE_PF_PD_ILK; /* * This would end up with an odd purple hue over @@ -3738,12 +3727,12 @@ static void hsw_set_transconf(const struct intel_crtc_state *crtc_state) u32 val = 0; if (IS_HASWELL(dev_priv) && crtc_state->dither) - val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP); + val |= PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP; if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) - val |= PIPECONF_INTERLACED_ILK; + val |= PIPECONF_INTERLACE_IF_ID_ILK; else - val |= PIPECONF_PROGRESSIVE; + val |= PIPECONF_INTERLACE_PF_PD_ILK; if (IS_HASWELL(dev_priv) && crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB) @@ -3765,18 +3754,18 @@ static void bdw_set_pipemisc(const struct intel_crtc_state *crtc_state) switch (crtc_state->pipe_bpp) { case 18: - val |= PIPEMISC_6_BPC; + val |= PIPEMISC_BPC_6; break; case 24: - val |= PIPEMISC_8_BPC; + val |= PIPEMISC_BPC_8; break; case 30: - val |= PIPEMISC_10_BPC; + val |= PIPEMISC_BPC_10; break; case 36: /* Port output 12BPC defined for ADLP+ */ if (DISPLAY_VER(dev_priv) > 12) - val |= PIPEMISC_12_BPC_ADLP; + val |= PIPEMISC_BPC_12_ADLP; break; default: MISSING_CASE(crtc_state->pipe_bpp); @@ -3812,7 +3801,7 @@ static void bdw_set_pipemisc(const struct intel_crtc_state *crtc_state) } intel_de_rmw(dev_priv, PIPE_MISC2(crtc->pipe), - PIPE_MISC2_UNDERRUN_BUBBLE_COUNTER_MASK, + PIPE_MISC2_BUBBLE_COUNTER_MASK, scaler_in_use ? PIPE_MISC2_BUBBLE_COUNTER_SCALER_EN : PIPE_MISC2_BUBBLE_COUNTER_SCALER_DIS); } @@ -3828,11 +3817,11 @@ int bdw_get_pipemisc_bpp(struct intel_crtc *crtc) tmp = intel_de_read(dev_priv, PIPEMISC(crtc->pipe)); switch (tmp & PIPEMISC_BPC_MASK) { - case PIPEMISC_6_BPC: + case PIPEMISC_BPC_6: return 18; - case PIPEMISC_8_BPC: + case PIPEMISC_BPC_8: return 24; - case PIPEMISC_10_BPC: + case PIPEMISC_BPC_10: return 30; /* * PORT OUTPUT 12 BPC defined for ADLP+. @@ -3844,7 +3833,7 @@ int bdw_get_pipemisc_bpp(struct intel_crtc *crtc) * on older platforms, need to find a workaround for 12 BPC * MIPI DSI HW readout. */ - case PIPEMISC_12_BPC_ADLP: + case PIPEMISC_BPC_12_ADLP: if (DISPLAY_VER(dev_priv) > 12) return 36; fallthrough; @@ -3865,83 +3854,47 @@ int ilk_get_lanes_required(int target_clock, int link_bw, int bpp) return DIV_ROUND_UP(bps, link_bw * 8); } -static void intel_pch_transcoder_get_m_n(struct intel_crtc *crtc, - struct intel_link_m_n *m_n) +void intel_get_m_n(struct drm_i915_private *i915, + struct intel_link_m_n *m_n, + i915_reg_t data_m_reg, i915_reg_t data_n_reg, + i915_reg_t link_m_reg, i915_reg_t link_n_reg) { - struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); - enum pipe pipe = crtc->pipe; - - m_n->link_m = intel_de_read(dev_priv, PCH_TRANS_LINK_M1(pipe)); - m_n->link_n = intel_de_read(dev_priv, PCH_TRANS_LINK_N1(pipe)); - m_n->gmch_m = intel_de_read(dev_priv, PCH_TRANS_DATA_M1(pipe)) - & ~TU_SIZE_MASK; - m_n->gmch_n = intel_de_read(dev_priv, PCH_TRANS_DATA_N1(pipe)); - m_n->tu = ((intel_de_read(dev_priv, PCH_TRANS_DATA_M1(pipe)) - & TU_SIZE_MASK) >> TU_SIZE_SHIFT) + 1; + m_n->link_m = intel_de_read(i915, link_m_reg) & DATA_LINK_M_N_MASK; + m_n->link_n = intel_de_read(i915, link_n_reg) & DATA_LINK_M_N_MASK; + m_n->data_m = intel_de_read(i915, data_m_reg) & DATA_LINK_M_N_MASK; + m_n->data_n = intel_de_read(i915, data_n_reg) & DATA_LINK_M_N_MASK; + m_n->tu = REG_FIELD_GET(TU_SIZE_MASK, intel_de_read(i915, data_m_reg)) + 1; } -static void intel_cpu_transcoder_get_m_n(struct intel_crtc *crtc, - enum transcoder transcoder, - struct intel_link_m_n *m_n, - struct intel_link_m_n *m2_n2) +void intel_cpu_transcoder_get_m1_n1(struct intel_crtc *crtc, + enum transcoder transcoder, + struct intel_link_m_n *m_n) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; - if (DISPLAY_VER(dev_priv) >= 5) { - m_n->link_m = intel_de_read(dev_priv, - PIPE_LINK_M1(transcoder)); - m_n->link_n = intel_de_read(dev_priv, - PIPE_LINK_N1(transcoder)); - m_n->gmch_m = intel_de_read(dev_priv, - PIPE_DATA_M1(transcoder)) - & ~TU_SIZE_MASK; - m_n->gmch_n = intel_de_read(dev_priv, - PIPE_DATA_N1(transcoder)); - m_n->tu = ((intel_de_read(dev_priv, PIPE_DATA_M1(transcoder)) - & TU_SIZE_MASK) >> TU_SIZE_SHIFT) + 1; - - if (m2_n2 && transcoder_has_m2_n2(dev_priv, transcoder)) { - m2_n2->link_m = intel_de_read(dev_priv, - PIPE_LINK_M2(transcoder)); - m2_n2->link_n = intel_de_read(dev_priv, - PIPE_LINK_N2(transcoder)); - m2_n2->gmch_m = intel_de_read(dev_priv, - PIPE_DATA_M2(transcoder)) - & ~TU_SIZE_MASK; - m2_n2->gmch_n = intel_de_read(dev_priv, - PIPE_DATA_N2(transcoder)); - m2_n2->tu = ((intel_de_read(dev_priv, PIPE_DATA_M2(transcoder)) - & TU_SIZE_MASK) >> TU_SIZE_SHIFT) + 1; - } - } else { - m_n->link_m = intel_de_read(dev_priv, PIPE_LINK_M_G4X(pipe)); - m_n->link_n = intel_de_read(dev_priv, PIPE_LINK_N_G4X(pipe)); - m_n->gmch_m = intel_de_read(dev_priv, PIPE_DATA_M_G4X(pipe)) - & ~TU_SIZE_MASK; - m_n->gmch_n = intel_de_read(dev_priv, PIPE_DATA_N_G4X(pipe)); - m_n->tu = ((intel_de_read(dev_priv, PIPE_DATA_M_G4X(pipe)) - & TU_SIZE_MASK) >> TU_SIZE_SHIFT) + 1; - } -} - -void intel_dp_get_m_n(struct intel_crtc *crtc, - struct intel_crtc_state *pipe_config) -{ - if (pipe_config->has_pch_encoder) - intel_pch_transcoder_get_m_n(crtc, &pipe_config->dp_m_n); + if (DISPLAY_VER(dev_priv) >= 5) + intel_get_m_n(dev_priv, m_n, + PIPE_DATA_M1(transcoder), PIPE_DATA_N1(transcoder), + PIPE_LINK_M1(transcoder), PIPE_LINK_N1(transcoder)); else - intel_cpu_transcoder_get_m_n(crtc, pipe_config->cpu_transcoder, - &pipe_config->dp_m_n, - &pipe_config->dp_m2_n2); + intel_get_m_n(dev_priv, m_n, + PIPE_DATA_M_G4X(pipe), PIPE_DATA_N_G4X(pipe), + PIPE_LINK_M_G4X(pipe), PIPE_LINK_N_G4X(pipe)); } -void ilk_get_fdi_m_n_config(struct intel_crtc *crtc, - struct intel_crtc_state *pipe_config) +void intel_cpu_transcoder_get_m2_n2(struct intel_crtc *crtc, + enum transcoder transcoder, + struct intel_link_m_n *m_n) { - intel_cpu_transcoder_get_m_n(crtc, pipe_config->cpu_transcoder, - &pipe_config->fdi_m_n, NULL); + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + + if (!intel_cpu_transcoder_has_m2_n2(dev_priv, transcoder)) + return; + + intel_get_m_n(dev_priv, m_n, + PIPE_DATA_M2(transcoder), PIPE_DATA_N2(transcoder), + PIPE_LINK_M2(transcoder), PIPE_LINK_N2(transcoder)); } static void ilk_get_pfit_pos_size(struct intel_crtc_state *crtc_state, @@ -4037,16 +3990,16 @@ static bool ilk_get_pipe_config(struct intel_crtc *crtc, goto out; switch (tmp & PIPECONF_BPC_MASK) { - case PIPECONF_6BPC: + case PIPECONF_BPC_6: pipe_config->pipe_bpp = 18; break; - case PIPECONF_8BPC: + case PIPECONF_BPC_8: pipe_config->pipe_bpp = 24; break; - case PIPECONF_10BPC: + case PIPECONF_BPC_10: pipe_config->pipe_bpp = 30; break; - case PIPECONF_12BPC: + case PIPECONF_BPC_12: pipe_config->pipe_bpp = 36; break; default: @@ -4066,8 +4019,7 @@ static bool ilk_get_pipe_config(struct intel_crtc *crtc, break; } - pipe_config->gamma_mode = (tmp & PIPECONF_GAMMA_MODE_MASK_ILK) >> - PIPECONF_GAMMA_MODE_SHIFT; + pipe_config->gamma_mode = REG_FIELD_GET(PIPECONF_GAMMA_MODE_MASK_ILK, tmp); pipe_config->csc_mode = intel_de_read(dev_priv, PIPE_CSC_MODE(crtc->pipe)); @@ -4380,13 +4332,13 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc, active = true; } + if (!active) + goto out; + intel_dsc_get_config(pipe_config); if (DISPLAY_VER(dev_priv) >= 13 && !pipe_config->dsc.compression_enable) intel_uncompressed_joiner_get_config(pipe_config); - if (!active) - goto out; - if (!transcoder_is_dsi(pipe_config->cpu_transcoder) || DISPLAY_VER(dev_priv) >= 11) intel_get_transcoder_timings(crtc, pipe_config); @@ -4908,6 +4860,28 @@ static bool needs_scaling(const struct intel_plane_state *state) return (src_w != dst_w || src_h != dst_h); } +static bool intel_plane_do_async_flip(struct intel_plane *plane, + const struct intel_crtc_state *old_crtc_state, + const struct intel_crtc_state *new_crtc_state) +{ + struct drm_i915_private *i915 = to_i915(plane->base.dev); + + if (!plane->async_flip) + return false; + + if (!new_crtc_state->uapi.async_flip) + return false; + + /* + * In platforms after DISPLAY13, we might need to override + * first async flip in order to change watermark levels + * as part of optimization. + * So for those, we are checking if this is a first async flip. + * For platforms earlier than DISPLAY13 we always do async flip. + */ + return DISPLAY_VER(i915) < 13 || old_crtc_state->uapi.async_flip; +} + int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_state, struct intel_crtc_state *new_crtc_state, const struct intel_plane_state *old_plane_state, @@ -5027,6 +5001,9 @@ int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_stat needs_scaling(new_plane_state)))) new_crtc_state->disable_lp_wm = true; + if (intel_plane_do_async_flip(plane, old_crtc_state, new_crtc_state)) + new_plane_state->do_async_flip = true; + return 0; } @@ -5491,9 +5468,9 @@ intel_dump_m_n_config(const struct intel_crtc_state *pipe_config, struct drm_i915_private *i915 = to_i915(pipe_config->uapi.crtc->dev); drm_dbg_kms(&i915->drm, - "%s: lanes: %i; gmch_m: %u, gmch_n: %u, link_m: %u, link_n: %u, tu: %u\n", + "%s: lanes: %i; data_m: %u, data_n: %u, link_m: %u, link_n: %u, tu: %u\n", id, lane_count, - m_n->gmch_m, m_n->gmch_n, + m_n->data_m, m_n->data_n, m_n->link_m, m_n->link_n, m_n->tu); } @@ -5658,11 +5635,11 @@ static void intel_dump_pipe_config(const struct intel_crtc_state *pipe_config, if (intel_crtc_has_dp_encoder(pipe_config)) { intel_dump_m_n_config(pipe_config, "dp m_n", - pipe_config->lane_count, &pipe_config->dp_m_n); - if (pipe_config->has_drrs) - intel_dump_m_n_config(pipe_config, "dp m2_n2", - pipe_config->lane_count, - &pipe_config->dp_m2_n2); + pipe_config->lane_count, + &pipe_config->dp_m_n); + intel_dump_m_n_config(pipe_config, "dp m2_n2", + pipe_config->lane_count, + &pipe_config->dp_m2_n2); } drm_dbg_kms(&dev_priv->drm, @@ -6189,8 +6166,8 @@ intel_compare_link_m_n(const struct intel_link_m_n *m_n, bool exact) { return m_n->tu == m2_n2->tu && - intel_compare_m_n(m_n->gmch_m, m_n->gmch_n, - m2_n2->gmch_m, m2_n2->gmch_n, exact) && + intel_compare_m_n(m_n->data_m, m_n->data_n, + m2_n2->data_m, m2_n2->data_n, exact) && intel_compare_m_n(m_n->link_m, m_n->link_n, m2_n2->link_m, m2_n2->link_n, exact); } @@ -6389,16 +6366,16 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, &pipe_config->name,\ !fastset)) { \ pipe_config_mismatch(fastset, crtc, __stringify(name), \ - "(expected tu %i gmch %i/%i link %i/%i, " \ - "found tu %i, gmch %i/%i link %i/%i)", \ + "(expected tu %i data %i/%i link %i/%i, " \ + "found tu %i, data %i/%i link %i/%i)", \ current_config->name.tu, \ - current_config->name.gmch_m, \ - current_config->name.gmch_n, \ + current_config->name.data_m, \ + current_config->name.data_n, \ current_config->name.link_m, \ current_config->name.link_n, \ pipe_config->name.tu, \ - pipe_config->name.gmch_m, \ - pipe_config->name.gmch_n, \ + pipe_config->name.data_m, \ + pipe_config->name.data_n, \ pipe_config->name.link_m, \ pipe_config->name.link_n); \ ret = false; \ @@ -6416,22 +6393,22 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, !intel_compare_link_m_n(¤t_config->alt_name, \ &pipe_config->name, !fastset)) { \ pipe_config_mismatch(fastset, crtc, __stringify(name), \ - "(expected tu %i gmch %i/%i link %i/%i, " \ - "or tu %i gmch %i/%i link %i/%i, " \ - "found tu %i, gmch %i/%i link %i/%i)", \ + "(expected tu %i data %i/%i link %i/%i, " \ + "or tu %i data %i/%i link %i/%i, " \ + "found tu %i, data %i/%i link %i/%i)", \ current_config->name.tu, \ - current_config->name.gmch_m, \ - current_config->name.gmch_n, \ + current_config->name.data_m, \ + current_config->name.data_n, \ current_config->name.link_m, \ current_config->name.link_n, \ current_config->alt_name.tu, \ - current_config->alt_name.gmch_m, \ - current_config->alt_name.gmch_n, \ + current_config->alt_name.data_m, \ + current_config->alt_name.data_n, \ current_config->alt_name.link_m, \ current_config->alt_name.link_n, \ pipe_config->name.tu, \ - pipe_config->name.gmch_m, \ - pipe_config->name.gmch_n, \ + pipe_config->name.data_m, \ + pipe_config->name.data_n, \ pipe_config->name.link_m, \ pipe_config->name.link_n); \ ret = false; \ @@ -6510,13 +6487,12 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, PIPE_CONF_CHECK_I(lane_count); PIPE_CONF_CHECK_X(lane_lat_optim_mask); - if (DISPLAY_VER(dev_priv) < 8) { - PIPE_CONF_CHECK_M_N(dp_m_n); - - if (current_config->has_drrs) - PIPE_CONF_CHECK_M_N(dp_m2_n2); - } else + if (DISPLAY_VER(dev_priv) >= 9 || IS_BROADWELL(dev_priv)) { PIPE_CONF_CHECK_M_N_ALT(dp_m_n, dp_m2_n2); + } else { + PIPE_CONF_CHECK_M_N(dp_m_n); + PIPE_CONF_CHECK_M_N(dp_m2_n2); + } PIPE_CONF_CHECK_X(output_types); @@ -7600,6 +7576,7 @@ static int intel_atomic_check_bigjoiner(struct intel_atomic_state *state, struct intel_crtc_state *old_crtc_state, struct intel_crtc_state *new_crtc_state) { + struct drm_i915_private *i915 = to_i915(state->base.dev); struct intel_crtc_state *slave_crtc_state, *master_crtc_state; struct intel_crtc *slave_crtc, *master_crtc; @@ -7617,9 +7594,10 @@ static int intel_atomic_check_bigjoiner(struct intel_atomic_state *state, slave_crtc = intel_dsc_get_bigjoiner_secondary(crtc); if (!slave_crtc) { - DRM_DEBUG_KMS("[CRTC:%d:%s] Big joiner configuration requires " - "CRTC + 1 to be used, doesn't exist\n", - crtc->base.base.id, crtc->base.name); + drm_dbg_kms(&i915->drm, + "[CRTC:%d:%s] Big joiner configuration requires " + "CRTC + 1 to be used, doesn't exist\n", + crtc->base.base.id, crtc->base.name); return -EINVAL; } @@ -7633,16 +7611,18 @@ static int intel_atomic_check_bigjoiner(struct intel_atomic_state *state, if (slave_crtc_state->uapi.enable) goto claimed; - DRM_DEBUG_KMS("[CRTC:%d:%s] Used as slave for big joiner\n", - slave_crtc->base.base.id, slave_crtc->base.name); + drm_dbg_kms(&i915->drm, + "[CRTC:%d:%s] Used as slave for big joiner\n", + slave_crtc->base.base.id, slave_crtc->base.name); return copy_bigjoiner_crtc_state(slave_crtc_state, new_crtc_state); claimed: - DRM_DEBUG_KMS("[CRTC:%d:%s] Slave is enabled as normal CRTC, but " - "[CRTC:%d:%s] claiming this CRTC for bigjoiner.\n", - slave_crtc->base.base.id, slave_crtc->base.name, - master_crtc->base.base.id, master_crtc->base.name); + drm_dbg_kms(&i915->drm, + "[CRTC:%d:%s] Slave is enabled as normal CRTC, but " + "[CRTC:%d:%s] claiming this CRTC for bigjoiner.\n", + slave_crtc->base.base.id, slave_crtc->base.name, + master_crtc->base.base.id, master_crtc->base.name); return -EINVAL; } @@ -9478,7 +9458,7 @@ void intel_modeset_init_hw(struct drm_i915_private *i915) cdclk_state = to_intel_cdclk_state(i915->cdclk.obj.state); intel_update_cdclk(i915); - intel_dump_cdclk_config(&i915->cdclk.hw, "Current CDCLK"); + intel_cdclk_dump_config(i915, &i915->cdclk.hw, "Current CDCLK"); cdclk_state->logical = cdclk_state->actual = i915->cdclk.hw; } @@ -9980,8 +9960,7 @@ void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe) udelay(150); /* wait for warmup */ } - intel_de_write(dev_priv, PIPECONF(pipe), - PIPECONF_ENABLE | PIPECONF_PROGRESSIVE); + intel_de_write(dev_priv, PIPECONF(pipe), PIPECONF_ENABLE); intel_de_posting_read(dev_priv, PIPECONF(pipe)); intel_wait_for_pipe_scanline_moving(crtc); @@ -9995,18 +9974,15 @@ void i830_disable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe) pipe_name(pipe)); drm_WARN_ON(&dev_priv->drm, - intel_de_read(dev_priv, DSPCNTR(PLANE_A)) & - DISPLAY_PLANE_ENABLE); + intel_de_read(dev_priv, DSPCNTR(PLANE_A)) & DISP_ENABLE); drm_WARN_ON(&dev_priv->drm, - intel_de_read(dev_priv, DSPCNTR(PLANE_B)) & - DISPLAY_PLANE_ENABLE); + intel_de_read(dev_priv, DSPCNTR(PLANE_B)) & DISP_ENABLE); drm_WARN_ON(&dev_priv->drm, - intel_de_read(dev_priv, DSPCNTR(PLANE_C)) & - DISPLAY_PLANE_ENABLE); + intel_de_read(dev_priv, DSPCNTR(PLANE_C)) & DISP_ENABLE); drm_WARN_ON(&dev_priv->drm, - intel_de_read(dev_priv, CURCNTR(PIPE_A)) & MCURSOR_MODE); + intel_de_read(dev_priv, CURCNTR(PIPE_A)) & MCURSOR_MODE_MASK); drm_WARN_ON(&dev_priv->drm, - intel_de_read(dev_priv, CURCNTR(PIPE_B)) & MCURSOR_MODE); + intel_de_read(dev_priv, CURCNTR(PIPE_B)) & MCURSOR_MODE_MASK); intel_de_write(dev_priv, PIPECONF(pipe), 0); intel_de_posting_read(dev_priv, PIPECONF(pipe)); @@ -10673,6 +10649,7 @@ intel_modeset_setup_hw_state(struct drm_device *dev, vlv_wm_sanitize(dev_priv); } else if (DISPLAY_VER(dev_priv) >= 9) { skl_wm_get_hw_state(dev_priv); + skl_wm_sanitize(dev_priv); } else if (HAS_PCH_SPLIT(dev_priv)) { ilk_wm_get_hw_state(dev_priv); } @@ -10688,6 +10665,8 @@ intel_modeset_setup_hw_state(struct drm_device *dev, } intel_display_power_put(dev_priv, POWER_DOMAIN_INIT, wakeref); + + intel_power_domains_sanitize_state(dev_priv); } void intel_display_resume(struct drm_device *dev) diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index b61b75248ded..457738aeee3e 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -27,7 +27,8 @@ #include -enum link_m_n_set; +#include "i915_reg_defs.h" + enum drm_scaling_filter; struct dpll; struct drm_connector; @@ -317,8 +318,8 @@ enum aux_ch { /* Used by dp and fdi links */ struct intel_link_m_n { u32 tu; - u32 gmch_m; - u32 gmch_n; + u32 data_m; + u32 data_n; u32 link_m; u32 link_n; }; @@ -605,12 +606,29 @@ bool intel_fuzzy_clock_check(int clock1, int clock2); void intel_display_prepare_reset(struct drm_i915_private *dev_priv); void intel_display_finish_reset(struct drm_i915_private *dev_priv); -void intel_dp_get_m_n(struct intel_crtc *crtc, - struct intel_crtc_state *pipe_config); -void intel_dp_set_m_n(const struct intel_crtc_state *crtc_state, - enum link_m_n_set m_n); -void ilk_get_fdi_m_n_config(struct intel_crtc *crtc, - struct intel_crtc_state *pipe_config); +void intel_zero_m_n(struct intel_link_m_n *m_n); +void intel_set_m_n(struct drm_i915_private *i915, + const struct intel_link_m_n *m_n, + i915_reg_t data_m_reg, i915_reg_t data_n_reg, + i915_reg_t link_m_reg, i915_reg_t link_n_reg); +void intel_get_m_n(struct drm_i915_private *i915, + struct intel_link_m_n *m_n, + i915_reg_t data_m_reg, i915_reg_t data_n_reg, + i915_reg_t link_m_reg, i915_reg_t link_n_reg); +bool intel_cpu_transcoder_has_m2_n2(struct drm_i915_private *dev_priv, + enum transcoder transcoder); +void intel_cpu_transcoder_set_m1_n1(struct intel_crtc *crtc, + enum transcoder cpu_transcoder, + const struct intel_link_m_n *m_n); +void intel_cpu_transcoder_set_m2_n2(struct intel_crtc *crtc, + enum transcoder cpu_transcoder, + const struct intel_link_m_n *m_n); +void intel_cpu_transcoder_get_m1_n1(struct intel_crtc *crtc, + enum transcoder cpu_transcoder, + struct intel_link_m_n *m_n); +void intel_cpu_transcoder_get_m2_n2(struct intel_crtc *crtc, + enum transcoder cpu_transcoder, + struct intel_link_m_n *m_n); void i9xx_crtc_clock_get(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config); int intel_dotclock_calculate(int link_freq, const struct intel_link_m_n *m_n); diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index 572445299b04..f4de004d470f 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -2402,6 +2402,9 @@ void intel_connector_debugfs_add(struct intel_connector *intel_connector) */ void intel_crtc_debugfs_add(struct drm_crtc *crtc) { - if (crtc->debugfs_entry) - crtc_updates_add(crtc); + if (!crtc->debugfs_entry) + return; + + crtc_updates_add(crtc); + intel_fbc_crtc_debugfs_add(to_intel_crtc(crtc)); } diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index 05babdcf5f2e..d2102cc17bb4 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -7,6 +7,7 @@ #include "i915_irq.h" #include "intel_cdclk.h" #include "intel_combo_phy.h" +#include "intel_combo_phy_regs.h" #include "intel_crt.h" #include "intel_de.h" #include "intel_display_power.h" @@ -682,9 +683,8 @@ static void icl_tc_cold_exit(struct drm_i915_private *i915) int ret, tries = 0; while (1) { - ret = sandybridge_pcode_write_timeout(i915, - ICL_PCODE_EXIT_TCCOLD, - 0, 250, 1); + ret = snb_pcode_write_timeout(i915, ICL_PCODE_EXIT_TCCOLD, 0, + 250, 1); if (ret != -EAGAIN || ++tries == 3) break; msleep(1); @@ -4052,8 +4052,7 @@ tgl_tc_cold_request(struct drm_i915_private *i915, bool block) * Spec states that we should timeout the request after 200us * but the function below will timeout after 500us */ - ret = sandybridge_pcode_read(i915, TGL_PCODE_TCCOLD, &low_val, - &high_val); + ret = snb_pcode_read(i915, TGL_PCODE_TCCOLD, &low_val, &high_val); if (ret == 0) { if (block && (low_val & TGL_PCODE_EXIT_TCCOLD_DATA_L_EXIT_FAILED)) @@ -5468,8 +5467,7 @@ static u32 hsw_read_dcomp(struct drm_i915_private *dev_priv) static void hsw_write_dcomp(struct drm_i915_private *dev_priv, u32 val) { if (IS_HASWELL(dev_priv)) { - if (sandybridge_pcode_write(dev_priv, - GEN6_PCODE_WRITE_D_COMP, val)) + if (snb_pcode_write(dev_priv, GEN6_PCODE_WRITE_D_COMP, val)) drm_dbg_kms(&dev_priv->drm, "Failed to write to D_COMP\n"); } else { @@ -5582,7 +5580,7 @@ static void hsw_restore_lcpll(struct drm_i915_private *dev_priv) intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL); intel_update_cdclk(dev_priv); - intel_dump_cdclk_config(&dev_priv->cdclk.hw, "Current CDCLK"); + intel_cdclk_dump_config(dev_priv, &dev_priv->cdclk.hw, "Current CDCLK"); } /* @@ -6215,6 +6213,37 @@ void intel_power_domains_driver_remove(struct drm_i915_private *i915) intel_runtime_pm_put(&i915->runtime_pm, wakeref); } +/** + * intel_power_domains_sanitize_state - sanitize power domains state + * @i915: i915 device instance + * + * Sanitize the power domains state during driver loading and system resume. + * The function will disable all display power wells that BIOS has enabled + * without a user for it (any user for a power well has taken a reference + * on it by the time this function is called, after the state of all the + * pipe, encoder, etc. HW resources have been sanitized). + */ +void intel_power_domains_sanitize_state(struct drm_i915_private *i915) +{ + struct i915_power_domains *power_domains = &i915->power_domains; + struct i915_power_well *power_well; + + mutex_lock(&power_domains->lock); + + for_each_power_well_reverse(i915, power_well) { + if (power_well->desc->always_on || power_well->count || + !power_well->desc->ops->is_enabled(i915, power_well)) + continue; + + drm_dbg_kms(&i915->drm, + "BIOS left unused %s power well enabled, disabling it\n", + power_well->desc->name); + intel_power_well_disable(i915, power_well); + } + + mutex_unlock(&power_domains->lock); +} + /** * intel_power_domains_enable - enable toggling of display power wells * @i915: i915 device instance diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h b/drivers/gpu/drm/i915/display/intel_display_power.h index 686d18eaa24c..f6d0e6e73c6d 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.h +++ b/drivers/gpu/drm/i915/display/intel_display_power.h @@ -7,7 +7,6 @@ #define __INTEL_DISPLAY_POWER_H__ #include "intel_runtime_pm.h" -#include "i915_reg.h" enum dpio_channel; enum dpio_phy; @@ -219,6 +218,7 @@ void intel_power_domains_disable(struct drm_i915_private *dev_priv); void intel_power_domains_suspend(struct drm_i915_private *dev_priv, enum i915_drm_suspend_mode); void intel_power_domains_resume(struct drm_i915_private *dev_priv); +void intel_power_domains_sanitize_state(struct drm_i915_private *dev_priv); void intel_display_power_suspend_late(struct drm_i915_private *i915); void intel_display_power_resume_early(struct drm_i915_private *i915); diff --git a/drivers/gpu/drm/i915/display/intel_display_trace.h b/drivers/gpu/drm/i915/display/intel_display_trace.h index 4043e1276383..f05f0f9b5103 100644 --- a/drivers/gpu/drm/i915/display/intel_display_trace.h +++ b/drivers/gpu/drm/i915/display/intel_display_trace.h @@ -13,6 +13,7 @@ #include #include "i915_drv.h" +#include "i915_irq.h" #include "intel_crtc.h" #include "intel_display_types.h" diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 41e3dd25a78f..60e15226a8cb 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -634,6 +634,9 @@ struct intel_plane_state { struct intel_fb_view view; + /* Indicates if async flip is required */ + bool do_async_flip; + /* Plane pxp decryption state */ bool decrypt; @@ -1442,25 +1445,6 @@ struct intel_hdmi { }; struct intel_dp_mst_encoder; -/* - * enum link_m_n_set: - * When platform provides two set of M_N registers for dp, we can - * program them and switch between them incase of DRRS. - * But When only one such register is provided, we have to program the - * required divider value on that registers itself based on the DRRS state. - * - * M1_N1 : Program dp_m_n on M1_N1 registers - * dp_m2_n2 on M2_N2 registers (If supported) - * - * M2_N2 : Program dp_m2_n2 on M1_N1 registers - * M2_N2 registers are not supported - */ - -enum link_m_n_set { - /* Sets the m1_n1 and m2_n2 */ - M1_N1 = 0, - M2_N2 -}; struct intel_dp_compliance_data { unsigned long edid; diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index a69b28d65a9b..7616a3906b9e 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -43,9 +43,9 @@ __stringify(major) "_" \ __stringify(minor) ".bin" -#define GEN12_DMC_MAX_FW_SIZE ICL_DMC_MAX_FW_SIZE +#define DISPLAY_VER13_DMC_MAX_FW_SIZE 0x20000 -#define GEN13_DMC_MAX_FW_SIZE 0x20000 +#define DISPLAY_VER12_DMC_MAX_FW_SIZE ICL_DMC_MAX_FW_SIZE #define ADLP_DMC_PATH DMC_PATH(adlp, 2, 14) #define ADLP_DMC_VERSION_REQUIRED DMC_VERSION(2, 14) @@ -684,23 +684,23 @@ void intel_dmc_ucode_init(struct drm_i915_private *dev_priv) if (IS_ALDERLAKE_P(dev_priv)) { dmc->fw_path = ADLP_DMC_PATH; dmc->required_version = ADLP_DMC_VERSION_REQUIRED; - dmc->max_fw_size = GEN13_DMC_MAX_FW_SIZE; + dmc->max_fw_size = DISPLAY_VER13_DMC_MAX_FW_SIZE; } else if (IS_ALDERLAKE_S(dev_priv)) { dmc->fw_path = ADLS_DMC_PATH; dmc->required_version = ADLS_DMC_VERSION_REQUIRED; - dmc->max_fw_size = GEN12_DMC_MAX_FW_SIZE; + dmc->max_fw_size = DISPLAY_VER12_DMC_MAX_FW_SIZE; } else if (IS_DG1(dev_priv)) { dmc->fw_path = DG1_DMC_PATH; dmc->required_version = DG1_DMC_VERSION_REQUIRED; - dmc->max_fw_size = GEN12_DMC_MAX_FW_SIZE; + dmc->max_fw_size = DISPLAY_VER12_DMC_MAX_FW_SIZE; } else if (IS_ROCKETLAKE(dev_priv)) { dmc->fw_path = RKL_DMC_PATH; dmc->required_version = RKL_DMC_VERSION_REQUIRED; - dmc->max_fw_size = GEN12_DMC_MAX_FW_SIZE; + dmc->max_fw_size = DISPLAY_VER12_DMC_MAX_FW_SIZE; } else if (DISPLAY_VER(dev_priv) >= 12) { dmc->fw_path = TGL_DMC_PATH; dmc->required_version = TGL_DMC_VERSION_REQUIRED; - dmc->max_fw_size = GEN12_DMC_MAX_FW_SIZE; + dmc->max_fw_size = DISPLAY_VER12_DMC_MAX_FW_SIZE; } else if (DISPLAY_VER(dev_priv) == 11) { dmc->fw_path = ICL_DMC_PATH; dmc->required_version = ICL_DMC_VERSION_REQUIRED; diff --git a/drivers/gpu/drm/i915/display/intel_dmc.h b/drivers/gpu/drm/i915/display/intel_dmc.h index b20f3441ca60..7c590309a3a9 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.h +++ b/drivers/gpu/drm/i915/display/intel_dmc.h @@ -6,7 +6,7 @@ #ifndef __INTEL_DMC_H__ #define __INTEL_DMC_H__ -#include "i915_reg.h" +#include "i915_reg_defs.h" #include "intel_wakeref.h" #include diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 36ab58c25b64..146b83916005 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -46,6 +46,7 @@ #include "intel_atomic.h" #include "intel_audio.h" #include "intel_backlight.h" +#include "intel_combo_phy_regs.h" #include "intel_connector.h" #include "intel_crtc.h" #include "intel_ddi.h" @@ -72,8 +73,6 @@ #include "intel_vdsc.h" #include "intel_vrr.h" -#define DP_DPRX_ESI_LEN 14 - /* DP DSC throughput values used for slice count calculations KPixels/s */ #define DP_DSC_PEAK_PIXEL_RATE 2720000 #define DP_DSC_MAX_ENC_THROUGHPUT_0 340000 @@ -705,7 +704,7 @@ static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915, i915->max_cdclk_freq * 48 / intel_dp_mode_to_fec_clock(mode_clock); - DRM_DEBUG_KMS("Max big joiner bpp: %u\n", max_bpp_bigjoiner); + drm_dbg_kms(&i915->drm, "Max big joiner bpp: %u\n", max_bpp_bigjoiner); bits_per_pixel = min(bits_per_pixel, max_bpp_bigjoiner); } @@ -1167,14 +1166,13 @@ static bool intel_dp_hdmi_tmds_clock_valid(struct intel_dp *intel_dp, return true; } -static bool intel_dp_hdmi_deep_color_possible(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state, - int bpc) +static bool intel_dp_hdmi_bpc_possible(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state, + int bpc) { - return intel_hdmi_deep_color_possible(crtc_state, bpc, - intel_dp->has_hdmi_sink, - intel_dp_hdmi_ycbcr420(intel_dp, crtc_state)) && + return intel_hdmi_bpc_possible(crtc_state, bpc, intel_dp->has_hdmi_sink, + intel_dp_hdmi_ycbcr420(intel_dp, crtc_state)) && intel_dp_hdmi_tmds_clock_valid(intel_dp, crtc_state, bpc); } @@ -1192,7 +1190,7 @@ static int intel_dp_max_bpp(struct intel_dp *intel_dp, if (intel_dp->dfp.min_tmds_clock) { for (; bpc >= 10; bpc -= 2) { - if (intel_dp_hdmi_deep_color_possible(intel_dp, crtc_state, bpc)) + if (intel_dp_hdmi_bpc_possible(intel_dp, crtc_state, bpc)) break; } } @@ -1897,7 +1895,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, /* FIXME: abstract this better */ if (pipe_config->splitter.enable) - pipe_config->dp_m_n.gmch_m *= pipe_config->splitter.link_count; + pipe_config->dp_m_n.data_m *= pipe_config->splitter.link_count; if (!HAS_DDI(dev_priv)) g4x_dp_set_clock(encoder, pipe_config); @@ -2813,11 +2811,22 @@ intel_dp_configure_mst(struct intel_dp *intel_dp) } static bool -intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *sink_irq_vector) +intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *esi) { - return drm_dp_dpcd_read(&intel_dp->aux, DP_SINK_COUNT_ESI, - sink_irq_vector, DP_DPRX_ESI_LEN) == - DP_DPRX_ESI_LEN; + return drm_dp_dpcd_read(&intel_dp->aux, DP_SINK_COUNT_ESI, esi, 4) == 4; +} + +static bool intel_dp_ack_sink_irq_esi(struct intel_dp *intel_dp, u8 esi[4]) +{ + int retry; + + for (retry = 0; retry < 3; retry++) { + if (drm_dp_dpcd_write(&intel_dp->aux, DP_SINK_COUNT_ESI + 1, + &esi[1], 3) == 3) + return true; + } + + return false; } bool @@ -2909,7 +2918,8 @@ out: } static ssize_t -intel_dp_hdr_metadata_infoframe_sdp_pack(const struct hdmi_drm_infoframe *drm_infoframe, +intel_dp_hdr_metadata_infoframe_sdp_pack(struct drm_i915_private *i915, + const struct hdmi_drm_infoframe *drm_infoframe, struct dp_sdp *sdp, size_t size) { @@ -2925,12 +2935,12 @@ intel_dp_hdr_metadata_infoframe_sdp_pack(const struct hdmi_drm_infoframe *drm_in len = hdmi_drm_infoframe_pack_only(drm_infoframe, buf, sizeof(buf)); if (len < 0) { - DRM_DEBUG_KMS("buffer size is smaller than hdr metadata infoframe\n"); + drm_dbg_kms(&i915->drm, "buffer size is smaller than hdr metadata infoframe\n"); return -ENOSPC; } if (len != infoframe_size) { - DRM_DEBUG_KMS("wrong static hdr metadata size\n"); + drm_dbg_kms(&i915->drm, "wrong static hdr metadata size\n"); return -ENOSPC; } @@ -3003,7 +3013,8 @@ static void intel_write_dp_sdp(struct intel_encoder *encoder, sizeof(sdp)); break; case HDMI_PACKET_TYPE_GAMUT_METADATA: - len = intel_dp_hdr_metadata_infoframe_sdp_pack(&crtc_state->infoframes.drm.drm, + len = intel_dp_hdr_metadata_infoframe_sdp_pack(dev_priv, + &crtc_state->infoframes.drm.drm, &sdp, sizeof(sdp)); break; default: @@ -3411,22 +3422,22 @@ static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp, switch (data->phy_pattern) { case DP_PHY_TEST_PATTERN_NONE: - DRM_DEBUG_KMS("Disable Phy Test Pattern\n"); + drm_dbg_kms(&dev_priv->drm, "Disable Phy Test Pattern\n"); intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), 0x0); break; case DP_PHY_TEST_PATTERN_D10_2: - DRM_DEBUG_KMS("Set D10.2 Phy Test Pattern\n"); + drm_dbg_kms(&dev_priv->drm, "Set D10.2 Phy Test Pattern\n"); intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_D10_2); break; case DP_PHY_TEST_PATTERN_ERROR_COUNT: - DRM_DEBUG_KMS("Set Error Count Phy Test Pattern\n"); + drm_dbg_kms(&dev_priv->drm, "Set Error Count Phy Test Pattern\n"); intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_SCRAMBLED_0); break; case DP_PHY_TEST_PATTERN_PRBS7: - DRM_DEBUG_KMS("Set PRBS7 Phy Test Pattern\n"); + drm_dbg_kms(&dev_priv->drm, "Set PRBS7 Phy Test Pattern\n"); intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_PRBS7); break; @@ -3436,7 +3447,8 @@ static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp, * current firmware of DPR-100 could not set it, so hardcoding * now for complaince test. */ - DRM_DEBUG_KMS("Set 80Bit Custom Phy Test Pattern 0x3e0f83e0 0x0f83e0f8 0x0000f83e\n"); + drm_dbg_kms(&dev_priv->drm, + "Set 80Bit Custom Phy Test Pattern 0x3e0f83e0 0x0f83e0f8 0x0000f83e\n"); pattern_val = 0x3e0f83e0; intel_de_write(dev_priv, DDI_DP_COMP_PAT(pipe, 0), pattern_val); pattern_val = 0x0f83e0f8; @@ -3453,7 +3465,7 @@ static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp, * current firmware of DPR-100 could not set it, so hardcoding * now for complaince test. */ - DRM_DEBUG_KMS("Set HBR2 compliance Phy Test Pattern\n"); + drm_dbg_kms(&dev_priv->drm, "Set HBR2 compliance Phy Test Pattern\n"); pattern_val = 0xFB; intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_HBR2 | @@ -3522,13 +3534,14 @@ intel_dp_autotest_phy_ddi_enable(struct intel_dp *intel_dp, static void intel_dp_process_phy_request(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { + struct drm_i915_private *i915 = dp_to_i915(intel_dp); struct drm_dp_phy_test_params *data = &intel_dp->compliance.test_data.phytest; u8 link_status[DP_LINK_STATUS_SIZE]; if (drm_dp_dpcd_read_phy_link_status(&intel_dp->aux, DP_PHY_DPRX, link_status) < 0) { - DRM_DEBUG_KMS("failed to get link status\n"); + drm_dbg_kms(&i915->drm, "failed to get link status\n"); return; } @@ -3553,11 +3566,12 @@ static void intel_dp_process_phy_request(struct intel_dp *intel_dp, static u8 intel_dp_autotest_phy_pattern(struct intel_dp *intel_dp) { + struct drm_i915_private *i915 = dp_to_i915(intel_dp); struct drm_dp_phy_test_params *data = &intel_dp->compliance.test_data.phytest; if (drm_dp_get_phy_test_pattern(&intel_dp->aux, data)) { - DRM_DEBUG_KMS("DP Phy Test pattern AUX read failure\n"); + drm_dbg_kms(&i915->drm, "DP Phy Test pattern AUX read failure\n"); return DP_TEST_NAK; } @@ -3615,14 +3629,43 @@ update_status: } static void -intel_dp_mst_hpd_irq(struct intel_dp *intel_dp, u8 *esi, bool *handled) +intel_dp_mst_hpd_irq(struct intel_dp *intel_dp, u8 *esi, u8 *ack) { - drm_dp_mst_hpd_irq(&intel_dp->mst_mgr, esi, handled); + bool handled = false; - if (esi[1] & DP_CP_IRQ) { - intel_hdcp_handle_cp_irq(intel_dp->attached_connector); - *handled = true; - } + drm_dp_mst_hpd_irq(&intel_dp->mst_mgr, esi, &handled); + if (handled) + ack[1] |= esi[1] & (DP_DOWN_REP_MSG_RDY | DP_UP_REQ_MSG_RDY); + + if (esi[1] & DP_CP_IRQ) { + intel_hdcp_handle_cp_irq(intel_dp->attached_connector); + ack[1] |= DP_CP_IRQ; + } +} + +static bool intel_dp_mst_link_status(struct intel_dp *intel_dp) +{ + struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; + struct drm_i915_private *i915 = to_i915(encoder->base.dev); + u8 link_status[DP_LINK_STATUS_SIZE] = {}; + const size_t esi_link_status_size = DP_LINK_STATUS_SIZE - 2; + + if (drm_dp_dpcd_read(&intel_dp->aux, DP_LANE0_1_STATUS_ESI, link_status, + esi_link_status_size) != esi_link_status_size) { + drm_err(&i915->drm, + "[ENCODER:%d:%s] Failed to read link status\n", + encoder->base.base.id, encoder->base.name); + return false; + } + + if (!drm_dp_channel_eq_ok(link_status, intel_dp->lane_count)) { + drm_dbg_kms(&i915->drm, + "[ENCODER:%d:%s] channel EQ not ok, retraining\n", + encoder->base.base.id, encoder->base.name); + return false; + } + + return true; } /** @@ -3647,20 +3690,8 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp) drm_WARN_ON_ONCE(&i915->drm, intel_dp->active_mst_links < 0); for (;;) { - /* - * The +2 is because DP_DPRX_ESI_LEN is 14, but we then - * pass in "esi+10" to drm_dp_channel_eq_ok(), which - * takes a 6-byte array. So we actually need 16 bytes - * here. - * - * Somebody who knows what the limits actually are - * should check this, but for now this is at least - * harmless and avoids a valid compiler warning about - * using more of the array than we have allocated. - */ - u8 esi[DP_DPRX_ESI_LEN+2] = {}; - bool handled; - int retry; + u8 esi[4] = {}; + u8 ack[4] = {}; if (!intel_dp_get_sink_irq_esi(intel_dp, esi)) { drm_dbg_kms(&i915->drm, @@ -3670,30 +3701,22 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp) break; } - /* check link status - esi[10] = 0x200c */ + drm_dbg_kms(&i915->drm, "DPRX ESI: %4ph\n", esi); + if (intel_dp->active_mst_links > 0 && link_ok && - !drm_dp_channel_eq_ok(&esi[10], intel_dp->lane_count)) { - drm_dbg_kms(&i915->drm, - "channel EQ not ok, retraining\n"); - link_ok = false; + esi[3] & LINK_STATUS_CHANGED) { + if (!intel_dp_mst_link_status(intel_dp)) + link_ok = false; + ack[3] |= LINK_STATUS_CHANGED; } - drm_dbg_kms(&i915->drm, "got esi %3ph\n", esi); + intel_dp_mst_hpd_irq(intel_dp, esi, ack); - intel_dp_mst_hpd_irq(intel_dp, esi, &handled); - - if (!handled) + if (!memchr_inv(ack, 0, sizeof(ack))) break; - for (retry = 0; retry < 3; retry++) { - int wret; - - wret = drm_dp_dpcd_write(&intel_dp->aux, - DP_SINK_COUNT_ESI+1, - &esi[1], 3); - if (wret == 3) - break; - } + if (!intel_dp_ack_sink_irq_esi(intel_dp, ack)) + drm_dbg_kms(&i915->drm, "Failed to ack ESI\n"); } return link_ok; @@ -4974,6 +4997,14 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, mutex_lock(&dev->mode_config.mutex); edid = drm_get_edid(connector, &intel_dp->aux.ddc); + if (!edid) { + /* Fallback to EDID from ACPI OpRegion, if any */ + edid = intel_opregion_get_edid(intel_connector); + if (edid) + drm_dbg_kms(&dev_priv->drm, + "[CONNECTOR:%d:%s] Using OpRegion EDID\n", + connector->base.id, connector->name); + } if (edid) { if (drm_add_edid_modes(connector, edid)) { drm_connector_update_edid_property(connector, edid); @@ -5048,8 +5079,8 @@ static void intel_dp_modeset_retry_work_fn(struct work_struct *work) intel_connector = container_of(work, typeof(*intel_connector), modeset_retry_work); connector = &intel_connector->base; - DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, - connector->name); + drm_dbg_kms(connector->dev, "[CONNECTOR:%d:%s]\n", connector->base.id, + connector->name); /* Grab the locks before changing connector property*/ mutex_lock(&connector->dev->mode_config.mutex); diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index b64145a3869a..d457e17bdc57 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -8,8 +8,6 @@ #include -#include "i915_reg.h" - enum intel_output_format; enum pipe; enum port; diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux.c b/drivers/gpu/drm/i915/display/intel_dp_aux.c index 5fbb767fcd63..2bc119374555 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_aux.c +++ b/drivers/gpu/drm/i915/display/intel_dp_aux.c @@ -10,7 +10,7 @@ #include "intel_pps.h" #include "intel_tc.h" -u32 intel_dp_pack_aux(const u8 *src, int src_bytes) +static u32 intel_dp_aux_pack(const u8 *src, int src_bytes) { int i; u32 v = 0; @@ -22,7 +22,7 @@ u32 intel_dp_pack_aux(const u8 *src, int src_bytes) return v; } -static void intel_dp_unpack_aux(u32 src, u8 *dst, int dst_bytes) +static void intel_dp_aux_unpack(u32 src, u8 *dst, int dst_bytes) { int i; @@ -267,7 +267,7 @@ intel_dp_aux_xfer(struct intel_dp *intel_dp, for (i = 0; i < send_bytes; i += 4) intel_uncore_write(uncore, ch_data[i >> 2], - intel_dp_pack_aux(send + i, + intel_dp_aux_pack(send + i, send_bytes - i)); /* Send the command and wait for it to complete */ @@ -352,7 +352,7 @@ done: recv_bytes = recv_size; for (i = 0; i < recv_bytes; i += 4) - intel_dp_unpack_aux(intel_uncore_read(uncore, ch_data[i >> 2]), + intel_dp_aux_unpack(intel_uncore_read(uncore, ch_data[i >> 2]), recv + i, recv_bytes - i); ret = recv_bytes; diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux.h b/drivers/gpu/drm/i915/display/intel_dp_aux.h index 4afbe76217b9..738577537bc7 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_aux.h +++ b/drivers/gpu/drm/i915/display/intel_dp_aux.h @@ -6,12 +6,8 @@ #ifndef __INTEL_DP_AUX_H__ #define __INTEL_DP_AUX_H__ -#include - struct intel_dp; -u32 intel_dp_pack_aux(const u8 *src, int src_bytes); - void intel_dp_aux_fini(struct intel_dp *intel_dp); void intel_dp_aux_init(struct intel_dp *intel_dp); diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index b8bc7d397c81..6b6eab507d30 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -522,8 +522,6 @@ static void intel_mst_pre_enable_dp(struct intel_atomic_state *state, intel_ddi_enable_pipe_clock(encoder, pipe_config); intel_ddi_set_dp_msa(pipe_config, conn_state); - - intel_dp_set_m_n(pipe_config, M1_N1); } static void intel_mst_enable_dp(struct intel_atomic_state *state, diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c index fc8fda77483a..6723c3de5a80 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c @@ -28,6 +28,7 @@ #include "intel_dpll_mgr.h" #include "intel_pch_refclk.h" #include "intel_tc.h" +#include "intel_tc_phy_regs.h" /** * DOC: Display PLLs @@ -49,6 +50,41 @@ * commit phase. */ +/* platform specific hooks for managing DPLLs */ +struct intel_shared_dpll_funcs { + /* + * Hook for enabling the pll, called from intel_enable_shared_dpll() if + * the pll is not already enabled. + */ + void (*enable)(struct drm_i915_private *i915, + struct intel_shared_dpll *pll); + + /* + * Hook for disabling the pll, called from intel_disable_shared_dpll() + * only when it is safe to disable the pll, i.e., there are no more + * tracked users for it. + */ + void (*disable)(struct drm_i915_private *i915, + struct intel_shared_dpll *pll); + + /* + * Hook for reading the values currently programmed to the DPLL + * registers. This is used for initial hw state readout and state + * verification after a mode set. + */ + bool (*get_hw_state)(struct drm_i915_private *i915, + struct intel_shared_dpll *pll, + struct intel_dpll_hw_state *hw_state); + + /* + * Hook for calculating the pll's output frequency based on its passed + * in state. + */ + int (*get_freq)(struct drm_i915_private *i915, + const struct intel_shared_dpll *pll, + const struct intel_dpll_hw_state *pll_state); +}; + struct intel_dpll_mgr { const struct dpll_info *dpll_info; diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.h b/drivers/gpu/drm/i915/display/intel_dpll_mgr.h index ef2889753807..91fe181462b2 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.h +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.h @@ -44,6 +44,7 @@ struct intel_crtc; struct intel_crtc_state; struct intel_encoder; struct intel_shared_dpll; +struct intel_shared_dpll_funcs; /** * enum intel_dpll_id - possible DPLL ids @@ -251,51 +252,6 @@ struct intel_shared_dpll_state { struct intel_dpll_hw_state hw_state; }; -/** - * struct intel_shared_dpll_funcs - platform specific hooks for managing DPLLs - */ -struct intel_shared_dpll_funcs { - /** - * @enable: - * - * Hook for enabling the pll, called from intel_enable_shared_dpll() - * if the pll is not already enabled. - */ - void (*enable)(struct drm_i915_private *dev_priv, - struct intel_shared_dpll *pll); - - /** - * @disable: - * - * Hook for disabling the pll, called from intel_disable_shared_dpll() - * only when it is safe to disable the pll, i.e., there are no more - * tracked users for it. - */ - void (*disable)(struct drm_i915_private *dev_priv, - struct intel_shared_dpll *pll); - - /** - * @get_hw_state: - * - * Hook for reading the values currently programmed to the DPLL - * registers. This is used for initial hw state readout and state - * verification after a mode set. - */ - bool (*get_hw_state)(struct drm_i915_private *dev_priv, - struct intel_shared_dpll *pll, - struct intel_dpll_hw_state *hw_state); - - /** - * @get_freq: - * - * Hook for calculating the pll's output frequency based on its - * passed in state. - */ - int (*get_freq)(struct drm_i915_private *i915, - const struct intel_shared_dpll *pll, - const struct intel_dpll_hw_state *pll_state); -}; - /** * struct dpll_info - display PLL platform specific info */ diff --git a/drivers/gpu/drm/i915/display/intel_drrs.c b/drivers/gpu/drm/i915/display/intel_drrs.c index c1439fcb5a95..fa715b8ea310 100644 --- a/drivers/gpu/drm/i915/display/intel_drrs.c +++ b/drivers/gpu/drm/i915/display/intel_drrs.c @@ -47,17 +47,13 @@ * requested by userspace. */ -void -intel_drrs_compute_config(struct intel_dp *intel_dp, - struct intel_crtc_state *pipe_config, - int output_bpp, bool constant_n) +static bool can_enable_drrs(struct intel_connector *connector, + const struct intel_crtc_state *pipe_config) { - struct intel_connector *intel_connector = intel_dp->attached_connector; - struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - int pixel_clock; + const struct drm_i915_private *i915 = to_i915(connector->base.dev); if (pipe_config->vrr.enable) - return; + return false; /* * DRRS and PSR can't be enable together, so giving preference to PSR @@ -66,15 +62,30 @@ intel_drrs_compute_config(struct intel_dp *intel_dp, * after intel_psr_compute_config(). */ if (pipe_config->has_psr) - return; + return false; - if (!intel_connector->panel.downclock_mode || - dev_priv->drrs.type != SEAMLESS_DRRS_SUPPORT) + return connector->panel.downclock_mode && + i915->drrs.type == SEAMLESS_DRRS_SUPPORT; +} + +void +intel_drrs_compute_config(struct intel_dp *intel_dp, + struct intel_crtc_state *pipe_config, + int output_bpp, bool constant_n) +{ + struct intel_connector *connector = intel_dp->attached_connector; + struct drm_i915_private *i915 = to_i915(connector->base.dev); + int pixel_clock; + + if (!can_enable_drrs(connector, pipe_config)) { + if (intel_cpu_transcoder_has_m2_n2(i915, pipe_config->cpu_transcoder)) + intel_zero_m_n(&pipe_config->dp_m2_n2); return; + } pipe_config->has_drrs = true; - pixel_clock = intel_connector->panel.downclock_mode->clock; + pixel_clock = connector->panel.downclock_mode->clock; if (pipe_config->splitter.enable) pixel_clock /= pipe_config->splitter.link_count; @@ -84,7 +95,42 @@ intel_drrs_compute_config(struct intel_dp *intel_dp, /* FIXME: abstract this better */ if (pipe_config->splitter.enable) - pipe_config->dp_m2_n2.gmch_m *= pipe_config->splitter.link_count; + pipe_config->dp_m2_n2.data_m *= pipe_config->splitter.link_count; +} + +static void +intel_drrs_set_refresh_rate_pipeconf(const struct intel_crtc_state *crtc_state, + enum drrs_refresh_rate_type refresh_type) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; + u32 val, bit; + + if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) + bit = PIPECONF_EDP_RR_MODE_SWITCH_VLV; + else + bit = PIPECONF_EDP_RR_MODE_SWITCH; + + val = intel_de_read(dev_priv, PIPECONF(cpu_transcoder)); + + if (refresh_type == DRRS_LOW_RR) + val |= bit; + else + val &= ~bit; + + intel_de_write(dev_priv, PIPECONF(cpu_transcoder), val); +} + +static void +intel_drrs_set_refresh_rate_m_n(const struct intel_crtc_state *crtc_state, + enum drrs_refresh_rate_type refresh_type) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + + intel_cpu_transcoder_set_m1_n1(crtc, crtc_state->cpu_transcoder, + refresh_type == DRRS_LOW_RR ? + &crtc_state->dp_m2_n2 : &crtc_state->dp_m_n); } static void intel_drrs_set_state(struct drm_i915_private *dev_priv, @@ -120,37 +166,10 @@ static void intel_drrs_set_state(struct drm_i915_private *dev_priv, return; } - if (DISPLAY_VER(dev_priv) >= 8 && !IS_CHERRYVIEW(dev_priv)) { - switch (refresh_type) { - case DRRS_HIGH_RR: - intel_dp_set_m_n(crtc_state, M1_N1); - break; - case DRRS_LOW_RR: - intel_dp_set_m_n(crtc_state, M2_N2); - break; - case DRRS_MAX_RR: - default: - drm_err(&dev_priv->drm, - "Unsupported refreshrate type\n"); - } - } else if (DISPLAY_VER(dev_priv) > 6) { - i915_reg_t reg = PIPECONF(crtc_state->cpu_transcoder); - u32 val; - - val = intel_de_read(dev_priv, reg); - if (refresh_type == DRRS_LOW_RR) { - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) - val |= PIPECONF_EDP_RR_MODE_SWITCH_VLV; - else - val |= PIPECONF_EDP_RR_MODE_SWITCH; - } else { - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) - val &= ~PIPECONF_EDP_RR_MODE_SWITCH_VLV; - else - val &= ~PIPECONF_EDP_RR_MODE_SWITCH; - } - intel_de_write(dev_priv, reg, val); - } + if (DISPLAY_VER(dev_priv) >= 8 && !IS_CHERRYVIEW(dev_priv)) + intel_drrs_set_refresh_rate_m_n(crtc_state, refresh_type); + else if (DISPLAY_VER(dev_priv) > 6) + intel_drrs_set_refresh_rate_pipeconf(crtc_state, refresh_type); dev_priv->drrs.refresh_rate_type = refresh_type; @@ -405,6 +424,7 @@ intel_drrs_init(struct intel_connector *connector, struct drm_display_mode *fixed_mode) { struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_encoder *encoder = connector->encoder; struct drm_display_mode *downclock_mode = NULL; INIT_DELAYED_WORK(&dev_priv->drrs.work, intel_drrs_downclock_work); @@ -416,6 +436,13 @@ intel_drrs_init(struct intel_connector *connector, return NULL; } + if ((DISPLAY_VER(dev_priv) < 8 && !HAS_GMCH(dev_priv)) && + encoder->port != PORT_A) { + drm_dbg_kms(&dev_priv->drm, + "DRRS only supported on eDP port A\n"); + return NULL; + } + if (dev_priv->vbt.drrs_type != SEAMLESS_DRRS_SUPPORT) { drm_dbg_kms(&dev_priv->drm, "VBT doesn't support DRRS\n"); return NULL; diff --git a/drivers/gpu/drm/i915/display/intel_dsb.h b/drivers/gpu/drm/i915/display/intel_dsb.h index 654a11f24b80..6cb9c580cdca 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.h +++ b/drivers/gpu/drm/i915/display/intel_dsb.h @@ -8,7 +8,7 @@ #include -#include "i915_reg.h" +#include "i915_reg_defs.h" struct intel_crtc_state; struct i915_vma; diff --git a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c index 0da91849efde..a85574c413e8 100644 --- a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c +++ b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c @@ -39,6 +39,7 @@ #include