Merge tag 'drm-intel-next-2022-02-08' of git://anongit.freedesktop.org/drm/drm-intel into drm-next

Cross-subsystem Changes:
------------------------

dma-buf:
- dma-buf-map: Rename to iosys-map (Lucas)

Core Changes:
-------------

drm:
- Always include the debugfs_entry in drm_crtc (Ville)
- Add orientation quirk for GPD Win Max (Anisse)

Driver Changes:
---------------

gvt:
- Constify some pointers. (Rikard Falkeborn)
- Use list_entry to access list members. (Guenter Roeck)
- Fix cmd parser error for Passmark9. (Zhenyu Wang)

i915:
- Various clean-ups including headers and removing unused and unnecessary stuff\
 (Jani, Hans, Andy, Ville)
- Cleaning up on our registers definitions i915_reg.h (Matt)
- More multi-FBC refactoring (Ville)
- Baytrail backlight fix (Hans)
- DG1 OPROM read through SPI controller (Clint)
- ADL-N platform enabling (Tejas)
- Fix slab-out-of-bounds access (Jani)
- Add opregion mailbox #5 support for possible EDID override (Anisse)
- Fix possible NULL dereferences (Harish)
- Updates and fixes around display voltage swing values (Clint, Jose)
- Fix RPM wekeref on PXP code (Juston)
- Many register definitions clean-up, including planes registers (Ville)
- More conversion towards display version over the old gen (Madhumitha, Ville)
- DP MST ESI handling improvements (Jani)
- drm device based logging conversions (Jani)
- Prevent divide by zero (Dan)
- Introduce ilk_pch_pre_enable for complete modeset abstraction (Ville)
- Async flip optimization for DG2 (Stanislav)
- Multiple DSC and bigjoiner fixes and improvements (Ville)
- Fix ADL-P TypeC Phy ready status readout (Imre)
- Fix up DP DFP 4:2:0 handling more display related fixes (Ville)
- Display M/N cleanup (Ville)
- Switch to use VGA definitions from video/vga.h (Jani)
- Fixes and improvements to abstract CPU architecture (Lucas)
- Disable unsused power wells left enabled by BIOS (Imre)
- Allow !join_mbus cases for adlp+ dbuf configuration (Ville)
- Populate pipe dbuf slices more accurately during readout (Ville)
- Workaround broken BIOS DBUF configuration on TGL/RKL (Ville)
- Fix trailing semicolon (Lucas)

Signed-off-by: Dave Airlie <airlied@redhat.com>

From: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/YgKFLmCgpv4vQEa1@intel.com
This commit is contained in:
Dave Airlie
2022-02-11 14:13:36 +10:00
273 changed files with 6342 additions and 5855 deletions

View File

@@ -502,6 +502,15 @@ pcim_iomap()
Not using these wrappers may make drivers unusable on certain platforms with Not using these wrappers may make drivers unusable on certain platforms with
stricter rules for mapping I/O memory. 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 Public Functions Provided
========================= =========================

View File

@@ -128,15 +128,6 @@ Kernel Functions and Structures Reference
.. kernel-doc:: include/linux/dma-buf.h .. kernel-doc:: include/linux/dma-buf.h
:internal: :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 Reservation Objects
------------------- -------------------

View File

@@ -222,7 +222,7 @@ Convert drivers to use drm_fbdev_generic_setup()
Most drivers can use drm_fbdev_generic_setup(). Driver have to implement Most drivers can use drm_fbdev_generic_setup(). Driver have to implement
atomic modesetting and GEM vmap support. Historically, generic fbdev emulation atomic modesetting and GEM vmap support. Historically, generic fbdev emulation
expected the framebuffer in system memory or system-like memory. By employing 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. as well.
Contact: Maintainer of the driver you plan to convert 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 A number of callback functions in drm_fbdev_fb_ops could benefit from
being rewritten without dependencies on the fbdev module. Some of the 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. raw pointers.
Contact: Thomas Zimmermann <tzimmermann@suse.de>, Daniel Vetter Contact: Thomas Zimmermann <tzimmermann@suse.de>, Daniel Vetter
@@ -434,19 +434,19 @@ Contact: Emil Velikov, respective driver maintainers
Level: Intermediate 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 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. 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. * Memory managers should use struct iosys_map for dma-buf-imported buffers.
* TTM might benefit from using struct dma_buf_map internally. * TTM might benefit from using struct iosys_map internally.
* Framebuffer copying and blitting helpers should operate on struct dma_buf_map. * Framebuffer copying and blitting helpers should operate on struct iosys_map.
Contact: Thomas Zimmermann <tzimmermann@suse.de>, Christian König, Daniel Vetter Contact: Thomas Zimmermann <tzimmermann@suse.de>, Christian König, Daniel Vetter

View File

@@ -5734,7 +5734,7 @@ T: git git://anongit.freedesktop.org/drm/drm-misc
F: Documentation/driver-api/dma-buf.rst F: Documentation/driver-api/dma-buf.rst
F: drivers/dma-buf/ F: drivers/dma-buf/
F: include/linux/*fence.h F: include/linux/*fence.h
F: include/linux/dma-buf* F: include/linux/dma-buf.h
F: include/linux/dma-resv.h F: include/linux/dma-resv.h
K: \bdma_(?:buf|fence|resv)\b K: \bdma_(?:buf|fence|resv)\b
@@ -10050,6 +10050,13 @@ F: include/linux/iova.h
F: include/linux/of_iommu.h F: include/linux/of_iommu.h
F: include/uapi/linux/iommu.h F: include/uapi/linux/iommu.h
IOSYS-MAP HELPERS
M: Thomas Zimmermann <tzimmermann@suse.de>
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 IO_URING
M: Jens Axboe <axboe@kernel.dk> M: Jens Axboe <axboe@kernel.dk>
R: Pavel Begunkov <asml.silence@gmail.com> R: Pavel Begunkov <asml.silence@gmail.com>

View File

@@ -555,6 +555,7 @@ static const struct pci_device_id intel_early_ids[] __initconst = {
INTEL_RKL_IDS(&gen11_early_ops), INTEL_RKL_IDS(&gen11_early_ops),
INTEL_ADLS_IDS(&gen11_early_ops), INTEL_ADLS_IDS(&gen11_early_ops),
INTEL_ADLP_IDS(&gen11_early_ops), INTEL_ADLP_IDS(&gen11_early_ops),
INTEL_ADLN_IDS(&gen11_early_ops),
INTEL_RPLS_IDS(&gen11_early_ops), INTEL_RPLS_IDS(&gen11_early_ops),
}; };

View File

@@ -1047,8 +1047,8 @@ EXPORT_SYMBOL_NS_GPL(dma_buf_move_notify, DMA_BUF);
* *
* Interfaces:: * Interfaces::
* *
* void \*dma_buf_vmap(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 dma_buf_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 * 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 * 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. * 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; int ret = 0;
dma_buf_map_clear(map); iosys_map_clear(map);
if (WARN_ON(!dmabuf)) if (WARN_ON(!dmabuf))
return -EINVAL; return -EINVAL;
@@ -1276,12 +1276,12 @@ int dma_buf_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map)
mutex_lock(&dmabuf->lock); mutex_lock(&dmabuf->lock);
if (dmabuf->vmapping_counter) { if (dmabuf->vmapping_counter) {
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; *map = dmabuf->vmap_ptr;
goto out_unlock; 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); ret = dmabuf->ops->vmap(dmabuf, &ptr);
if (WARN_ON_ONCE(ret)) if (WARN_ON_ONCE(ret))
@@ -1303,20 +1303,20 @@ EXPORT_SYMBOL_NS_GPL(dma_buf_vmap, DMA_BUF);
* @dmabuf: [in] buffer to vunmap * @dmabuf: [in] buffer to vunmap
* @map: [in] vmap pointer 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)) if (WARN_ON(!dmabuf))
return; 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(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); mutex_lock(&dmabuf->lock);
if (--dmabuf->vmapping_counter == 0) { if (--dmabuf->vmapping_counter == 0) {
if (dmabuf->ops->vunmap) if (dmabuf->ops->vunmap)
dmabuf->ops->vunmap(dmabuf, map); dmabuf->ops->vunmap(dmabuf, map);
dma_buf_map_clear(&dmabuf->vmap_ptr); iosys_map_clear(&dmabuf->vmap_ptr);
} }
mutex_unlock(&dmabuf->lock); mutex_unlock(&dmabuf->lock);
} }

View File

@@ -202,7 +202,7 @@ static void *cma_heap_do_vmap(struct cma_heap_buffer *buffer)
return vaddr; 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; struct cma_heap_buffer *buffer = dmabuf->priv;
void *vaddr; void *vaddr;
@@ -211,7 +211,7 @@ static int cma_heap_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map)
mutex_lock(&buffer->lock); mutex_lock(&buffer->lock);
if (buffer->vmap_cnt) { if (buffer->vmap_cnt) {
buffer->vmap_cnt++; buffer->vmap_cnt++;
dma_buf_map_set_vaddr(map, buffer->vaddr); iosys_map_set_vaddr(map, buffer->vaddr);
goto out; goto out;
} }
@@ -222,14 +222,14 @@ static int cma_heap_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map)
} }
buffer->vaddr = vaddr; buffer->vaddr = vaddr;
buffer->vmap_cnt++; buffer->vmap_cnt++;
dma_buf_map_set_vaddr(map, buffer->vaddr); iosys_map_set_vaddr(map, buffer->vaddr);
out: out:
mutex_unlock(&buffer->lock); mutex_unlock(&buffer->lock);
return ret; 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; 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; buffer->vaddr = NULL;
} }
mutex_unlock(&buffer->lock); mutex_unlock(&buffer->lock);
dma_buf_map_clear(map); iosys_map_clear(map);
} }
static void cma_heap_dma_buf_release(struct dma_buf *dmabuf) static void cma_heap_dma_buf_release(struct dma_buf *dmabuf)

View File

@@ -241,7 +241,7 @@ static void *system_heap_do_vmap(struct system_heap_buffer *buffer)
return vaddr; 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; struct system_heap_buffer *buffer = dmabuf->priv;
void *vaddr; void *vaddr;
@@ -250,7 +250,7 @@ static int system_heap_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map)
mutex_lock(&buffer->lock); mutex_lock(&buffer->lock);
if (buffer->vmap_cnt) { if (buffer->vmap_cnt) {
buffer->vmap_cnt++; buffer->vmap_cnt++;
dma_buf_map_set_vaddr(map, buffer->vaddr); iosys_map_set_vaddr(map, buffer->vaddr);
goto out; goto out;
} }
@@ -262,14 +262,14 @@ static int system_heap_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map)
buffer->vaddr = vaddr; buffer->vaddr = vaddr;
buffer->vmap_cnt++; buffer->vmap_cnt++;
dma_buf_map_set_vaddr(map, buffer->vaddr); iosys_map_set_vaddr(map, buffer->vaddr);
out: out:
mutex_unlock(&buffer->lock); mutex_unlock(&buffer->lock);
return ret; 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; 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; buffer->vaddr = NULL;
} }
mutex_unlock(&buffer->lock); mutex_unlock(&buffer->lock);
dma_buf_map_clear(map); iosys_map_clear(map);
} }
static void system_heap_dma_buf_release(struct dma_buf *dmabuf) static void system_heap_dma_buf_release(struct dma_buf *dmabuf)

View File

@@ -107,7 +107,7 @@ struct ast_cursor_plane {
struct { struct {
struct drm_gem_vram_object *gbo; struct drm_gem_vram_object *gbo;
struct dma_buf_map map; struct iosys_map map;
u64 off; u64 off;
} hwc[AST_DEFAULT_HWC_NUM]; } hwc[AST_DEFAULT_HWC_NUM];

View File

@@ -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_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(new_state);
struct drm_framebuffer *fb = new_state->fb; struct drm_framebuffer *fb = new_state->fb;
struct ast_private *ast = to_ast_private(plane->dev); 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; ast_cursor_plane->hwc[ast_cursor_plane->next_hwc_index].map;
u64 dst_off = u64 dst_off =
ast_cursor_plane->hwc[ast_cursor_plane->next_hwc_index].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; unsigned int offset_x, offset_y;
u16 x, y; u16 x, y;
u8 x_offset, y_offset; 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); struct ast_cursor_plane *ast_cursor_plane = to_ast_cursor_plane(plane);
size_t i; size_t i;
struct drm_gem_vram_object *gbo; 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) { for (i = 0; i < ARRAY_SIZE(ast_cursor_plane->hwc); ++i) {
gbo = ast_cursor_plane->hwc[i].gbo; 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; struct drm_plane *cursor_plane = &ast_cursor_plane->base;
size_t size, i; size_t size, i;
struct drm_gem_vram_object *gbo; struct drm_gem_vram_object *gbo;
struct dma_buf_map map; struct iosys_map map;
int ret; int ret;
s64 off; s64 off;

View File

@@ -28,10 +28,10 @@
* Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com> * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
*/ */
#include <linux/dma-buf-map.h> #include <linux/cc_platform.h>
#include <linux/export.h> #include <linux/export.h>
#include <linux/highmem.h> #include <linux/highmem.h>
#include <linux/cc_platform.h> #include <linux/iosys-map.h>
#include <xen/xen.h> #include <xen/xen.h>
#include <drm/drm_cache.h> #include <drm/drm_cache.h>
@@ -214,14 +214,14 @@ bool drm_need_swiotlb(int dma_bits)
} }
EXPORT_SYMBOL(drm_need_swiotlb); EXPORT_SYMBOL(drm_need_swiotlb);
static void memcpy_fallback(struct dma_buf_map *dst, static void memcpy_fallback(struct iosys_map *dst,
const struct dma_buf_map *src, const struct iosys_map *src,
unsigned long len) unsigned long len)
{ {
if (!dst->is_iomem && !src->is_iomem) { if (!dst->is_iomem && !src->is_iomem) {
memcpy(dst->vaddr, src->vaddr, len); memcpy(dst->vaddr, src->vaddr, len);
} else if (!src->is_iomem) { } 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) { } else if (!dst->is_iomem) {
memcpy_fromio(dst->vaddr, src->vaddr_iomem, len); memcpy_fromio(dst->vaddr, src->vaddr_iomem, len);
} else { } 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, * 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. * and if no such beast is available, falls back to a normal memcpy.
*/ */
void drm_memcpy_from_wc(struct dma_buf_map *dst, void drm_memcpy_from_wc(struct iosys_map *dst,
const struct dma_buf_map *src, const struct iosys_map *src,
unsigned long len) unsigned long len)
{ {
if (WARN_ON(in_interrupt())) { if (WARN_ON(in_interrupt())) {
@@ -343,8 +343,8 @@ void drm_memcpy_init_early(void)
static_branch_enable(&has_movntdqa); static_branch_enable(&has_movntdqa);
} }
#else #else
void drm_memcpy_from_wc(struct dma_buf_map *dst, void drm_memcpy_from_wc(struct iosys_map *dst,
const struct dma_buf_map *src, const struct iosys_map *src,
unsigned long len) unsigned long len)
{ {
WARN_ON(in_interrupt()); WARN_ON(in_interrupt());

View File

@@ -3,7 +3,7 @@
* Copyright 2018 Noralf Trønnes * Copyright 2018 Noralf Trønnes
*/ */
#include <linux/dma-buf-map.h> #include <linux/iosys-map.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/mutex.h> #include <linux/mutex.h>
@@ -309,9 +309,10 @@ err_delete:
* 0 on success, or a negative errno code otherwise. * 0 on success, or a negative errno code otherwise.
*/ */
int 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; int ret;
/* /*
@@ -342,7 +343,7 @@ EXPORT_SYMBOL(drm_client_buffer_vmap);
*/ */
void drm_client_buffer_vunmap(struct drm_client_buffer *buffer) 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); drm_gem_vunmap(buffer->gem, map);
} }

View File

@@ -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, static void drm_fb_helper_damage_blit_real(struct drm_fb_helper *fb_helper,
struct drm_clip_rect *clip, struct drm_clip_rect *clip,
struct dma_buf_map *dst) struct iosys_map *dst)
{ {
struct drm_framebuffer *fb = fb_helper->fb; struct drm_framebuffer *fb = fb_helper->fb;
unsigned int cpp = fb->format->cpp[0]; 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; size_t len = (clip->x2 - clip->x1) * cpp;
unsigned int y; 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++) { for (y = clip->y1; y < clip->y2; y++) {
dma_buf_map_memcpy_to(dst, src, len); iosys_map_memcpy_to(dst, src, len);
dma_buf_map_incr(dst, fb->pitches[0]); iosys_map_incr(dst, fb->pitches[0]);
src += 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_clip_rect *clip)
{ {
struct drm_client_buffer *buffer = fb_helper->buffer; struct drm_client_buffer *buffer = fb_helper->buffer;
struct dma_buf_map map, dst; struct iosys_map map, dst;
int ret; int ret;
/* /*
@@ -2322,7 +2322,7 @@ static int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper,
struct drm_framebuffer *fb; struct drm_framebuffer *fb;
struct fb_info *fbi; struct fb_info *fbi;
u32 format; u32 format;
struct dma_buf_map map; struct iosys_map map;
int ret; int ret;
drm_dbg_kms(dev, "surface width(%d), height(%d) and bpp(%d)\n", drm_dbg_kms(dev, "surface width(%d), height(%d) and bpp(%d)\n",

View File

@@ -36,7 +36,7 @@
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/shmem_fs.h> #include <linux/shmem_fs.h>
#include <linux/dma-buf.h> #include <linux/dma-buf.h>
#include <linux/dma-buf-map.h> #include <linux/iosys-map.h>
#include <linux/mem_encrypt.h> #include <linux/mem_encrypt.h>
#include <linux/pagevec.h> #include <linux/pagevec.h>
@@ -1165,7 +1165,7 @@ void drm_gem_unpin(struct drm_gem_object *obj)
obj->funcs->unpin(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; 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); ret = obj->funcs->vmap(obj, map);
if (ret) if (ret)
return ret; return ret;
else if (dma_buf_map_is_null(map)) else if (iosys_map_is_null(map))
return -ENOMEM; return -ENOMEM;
return 0; return 0;
} }
EXPORT_SYMBOL(drm_gem_vmap); 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; return;
if (obj->funcs->vunmap) if (obj->funcs->vunmap)
obj->funcs->vunmap(obj, map); obj->funcs->vunmap(obj, map);
/* Always set the mapping to NULL. Callers may rely on this. */ /* 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); EXPORT_SYMBOL(drm_gem_vunmap);

View File

@@ -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) void drm_gem_cma_free(struct drm_gem_cma_object *cma_obj)
{ {
struct drm_gem_object *gem_obj = &cma_obj->base; 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 (gem_obj->import_attach) {
if (cma_obj->vaddr) if (cma_obj->vaddr)
@@ -480,9 +480,10 @@ EXPORT_SYMBOL_GPL(drm_gem_cma_prime_import_sg_table);
* Returns: * Returns:
* 0 on success, or a negative error code otherwise. * 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; 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_cma_object *cma_obj;
struct drm_gem_object *obj; struct drm_gem_object *obj;
struct dma_buf_map map; struct iosys_map map;
int ret; int ret;
ret = dma_buf_vmap(attach->dmabuf, &map); ret = dma_buf_vmap(attach->dmabuf, &map);

View File

@@ -321,7 +321,7 @@ EXPORT_SYMBOL_GPL(drm_gem_fb_create_with_dirty);
* @data: returns the data address for each BO, can be NULL * @data: returns the data address for each BO, can be NULL
* *
* This function maps all buffer objects of the given framebuffer into * 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 * mapping operation fails for one of the BOs, the function unmaps the
* already established mappings automatically. * 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. * 0 on success, or a negative errno code otherwise.
*/ */
int drm_gem_fb_vmap(struct drm_framebuffer *fb, int drm_gem_fb_vmap(struct drm_framebuffer *fb,
struct dma_buf_map map[static DRM_FORMAT_MAX_PLANES], struct iosys_map map[static DRM_FORMAT_MAX_PLANES],
struct dma_buf_map data[DRM_FORMAT_MAX_PLANES]) struct iosys_map data[DRM_FORMAT_MAX_PLANES])
{ {
struct drm_gem_object *obj; struct drm_gem_object *obj;
unsigned int i; 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) { for (i = 0; i < DRM_FORMAT_MAX_PLANES; ++i) {
obj = drm_gem_fb_get_obj(fb, i); obj = drm_gem_fb_get_obj(fb, i);
if (!obj) { if (!obj) {
dma_buf_map_clear(&map[i]); iosys_map_clear(&map[i]);
continue; continue;
} }
ret = drm_gem_vmap(obj, &map[i]); ret = drm_gem_vmap(obj, &map[i]);
@@ -356,9 +356,9 @@ int drm_gem_fb_vmap(struct drm_framebuffer *fb,
if (data) { if (data) {
for (i = 0; i < DRM_FORMAT_MAX_PLANES; ++i) { for (i = 0; i < DRM_FORMAT_MAX_PLANES; ++i) {
memcpy(&data[i], &map[i], sizeof(data[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; 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. * See drm_gem_fb_vmap() for more information.
*/ */
void drm_gem_fb_vunmap(struct drm_framebuffer *fb, 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; unsigned int i = DRM_FORMAT_MAX_PLANES;
struct drm_gem_object *obj; 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); obj = drm_gem_fb_get_obj(fb, i);
if (!obj) if (!obj)
continue; continue;
if (dma_buf_map_is_null(&map[i])) if (iosys_map_is_null(&map[i]))
continue; continue;
drm_gem_vunmap(obj, &map[i]); drm_gem_vunmap(obj, &map[i]);
} }

View File

@@ -286,13 +286,14 @@ void drm_gem_shmem_unpin(struct drm_gem_shmem_object *shmem)
} }
EXPORT_SYMBOL(drm_gem_shmem_unpin); 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; struct drm_gem_object *obj = &shmem->base;
int ret = 0; int ret = 0;
if (shmem->vmap_use_count++ > 0) { if (shmem->vmap_use_count++ > 0) {
dma_buf_map_set_vaddr(map, shmem->vaddr); iosys_map_set_vaddr(map, shmem->vaddr);
return 0; return 0;
} }
@@ -319,7 +320,7 @@ static int drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem, struct
if (!shmem->vaddr) if (!shmem->vaddr)
ret = -ENOMEM; ret = -ENOMEM;
else else
dma_buf_map_set_vaddr(map, shmem->vaddr); iosys_map_set_vaddr(map, shmem->vaddr);
} }
if (ret) { if (ret) {
@@ -353,7 +354,8 @@ err_zero_use:
* Returns: * Returns:
* 0 on success or a negative error code on failure. * 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; 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); EXPORT_SYMBOL(drm_gem_shmem_vmap);
static void drm_gem_shmem_vunmap_locked(struct drm_gem_shmem_object *shmem, 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; 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 * This function hides the differences between dma-buf imported and natively
* allocated objects. * 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); mutex_lock(&shmem->vmap_lock);
drm_gem_shmem_vunmap_locked(shmem, map); drm_gem_shmem_vunmap_locked(shmem, map);

View File

@@ -61,7 +61,7 @@ EXPORT_SYMBOL(drm_gem_ttm_print_info);
* 0 on success, or a negative errno code otherwise. * 0 on success, or a negative errno code otherwise.
*/ */
int drm_gem_ttm_vmap(struct drm_gem_object *gem, 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); 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. * &drm_gem_object_funcs.vmap callback.
*/ */
void drm_gem_ttm_vunmap(struct drm_gem_object *gem, 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); struct ttm_buffer_object *bo = drm_gem_ttm_of_gem(gem);

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include <linux/dma-buf-map.h> #include <linux/iosys-map.h>
#include <linux/module.h> #include <linux/module.h>
#include <drm/drm_debugfs.h> #include <drm/drm_debugfs.h>
@@ -116,7 +116,7 @@ static void drm_gem_vram_cleanup(struct drm_gem_vram_object *gbo)
*/ */
WARN_ON(gbo->vmap_use_count); 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); 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); EXPORT_SYMBOL(drm_gem_vram_unpin);
static int drm_gem_vram_kmap_locked(struct drm_gem_vram_object *gbo, static int drm_gem_vram_kmap_locked(struct drm_gem_vram_object *gbo,
struct dma_buf_map *map) struct iosys_map *map)
{ {
int ret; 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 * page mapping might still be around. Only vmap if the there's
* no mapping present. * 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); ret = ttm_bo_vmap(&gbo->bo, &gbo->map);
if (ret) if (ret)
return ret; return ret;
@@ -391,14 +391,14 @@ out:
} }
static void drm_gem_vram_kunmap_locked(struct drm_gem_vram_object *gbo, 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; struct drm_device *dev = gbo->bo.base.dev;
if (drm_WARN_ON_ONCE(dev, !gbo->vmap_use_count)) if (drm_WARN_ON_ONCE(dev, !gbo->vmap_use_count))
return; 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 */ return; /* BUG: map not mapped from this BO */
if (--gbo->vmap_use_count > 0) if (--gbo->vmap_use_count > 0)
@@ -428,7 +428,7 @@ static void drm_gem_vram_kunmap_locked(struct drm_gem_vram_object *gbo,
* Returns: * Returns:
* 0 on success, or a negative error code otherwise. * 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; 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 * 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. * 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; int ret;
@@ -567,7 +568,7 @@ static void drm_gem_vram_bo_driver_move_notify(struct drm_gem_vram_object *gbo)
return; return;
ttm_bo_vunmap(bo, &gbo->map); 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, 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: * Returns:
* 0 on success, or a negative error code otherwise. * 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); 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 * @gem: The GEM object to unmap
* @map: Kernel virtual address where the VRAM GEM object was mapped * @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); struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem);

View File

@@ -33,7 +33,7 @@
struct dentry; struct dentry;
struct dma_buf; struct dma_buf;
struct dma_buf_map; struct iosys_map;
struct drm_connector; struct drm_connector;
struct drm_crtc; struct drm_crtc;
struct drm_framebuffer; 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); int drm_gem_pin(struct drm_gem_object *obj);
void drm_gem_unpin(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); int drm_gem_vmap(struct drm_gem_object *obj, struct iosys_map *map);
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);
int drm_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev, int drm_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev,
u32 handle); u32 handle);

View File

@@ -201,8 +201,8 @@ int mipi_dbi_buf_copy(void *dst, struct drm_framebuffer *fb,
struct drm_rect *clip, bool swap) struct drm_rect *clip, bool swap)
{ {
struct drm_gem_object *gem = drm_gem_fb_get_obj(fb, 0); struct drm_gem_object *gem = drm_gem_fb_get_obj(fb, 0);
struct dma_buf_map map[DRM_FORMAT_MAX_PLANES]; struct iosys_map map[DRM_FORMAT_MAX_PLANES];
struct dma_buf_map data[DRM_FORMAT_MAX_PLANES]; struct iosys_map data[DRM_FORMAT_MAX_PLANES];
void *src; void *src;
int ret; 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) static void mipi_dbi_fb_dirty(struct drm_framebuffer *fb, struct drm_rect *rect)
{ {
struct dma_buf_map map[DRM_FORMAT_MAX_PLANES]; struct iosys_map map[DRM_FORMAT_MAX_PLANES];
struct dma_buf_map data[DRM_FORMAT_MAX_PLANES]; struct iosys_map data[DRM_FORMAT_MAX_PLANES];
struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(fb->dev); struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(fb->dev);
unsigned int height = rect->y2 - rect->y1; unsigned int height = rect->y2 - rect->y1;
unsigned int width = rect->x2 - rect->x1; unsigned int width = rect->x2 - rect->x1;

View File

@@ -180,6 +180,12 @@ static const struct dmi_system_id orientation_data[] = {
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MicroPC"), DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MicroPC"),
}, },
.driver_data = (void *)&lcd720x1280_rightside_up, .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 * GPD Pocket, note that the the DMI data is less generic then
* it seems, devices with a board-vendor of "AMI Corporation" * it seems, devices with a board-vendor of "AMI Corporation"

View File

@@ -674,7 +674,7 @@ EXPORT_SYMBOL(drm_gem_unmap_dma_buf);
* *
* Returns 0 on success or a negative errno code otherwise. * 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; 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 * 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. * &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; struct drm_gem_object *obj = dma_buf->priv;

View File

@@ -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); 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); 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 drm_gem_object *etnaviv_gem_prime_import_sg_table(struct drm_device *dev,
struct dma_buf_attachment *attach, struct sg_table *sg); struct dma_buf_attachment *attach, struct sg_table *sg);
int etnaviv_gem_prime_pin(struct drm_gem_object *obj); int etnaviv_gem_prime_pin(struct drm_gem_object *obj);

View File

@@ -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); 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; void *vaddr;
vaddr = etnaviv_gem_vmap(obj); vaddr = etnaviv_gem_vmap(obj);
if (!vaddr) if (!vaddr)
return -ENOMEM; return -ENOMEM;
dma_buf_map_set_vaddr(map, vaddr); iosys_map_set_vaddr(map, vaddr);
return 0; 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) 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) if (etnaviv_obj->vaddr)
dma_buf_vunmap(etnaviv_obj->base.import_attach->dmabuf, &map); 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) static void *etnaviv_gem_prime_vmap_impl(struct etnaviv_gem_object *etnaviv_obj)
{ {
struct dma_buf_map map; struct iosys_map map;
int ret; int ret;
lockdep_assert_held(&etnaviv_obj->lock); lockdep_assert_held(&etnaviv_obj->lock);

View File

@@ -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; struct dma_buf_attachment *import_attach = fb->obj[0]->import_attach;
u8 compression = gdrm->compression; u8 compression = gdrm->compression;
struct dma_buf_map map[DRM_FORMAT_MAX_PLANES]; struct iosys_map map[DRM_FORMAT_MAX_PLANES];
struct dma_buf_map map_data[DRM_FORMAT_MAX_PLANES]; struct iosys_map map_data[DRM_FORMAT_MAX_PLANES];
void *vaddr, *buf; void *vaddr, *buf;
size_t pitch, len; size_t pitch, len;
int ret = 0; int ret = 0;

View File

@@ -19,7 +19,7 @@
#include "hyperv_drm.h" #include "hyperv_drm.h"
static int hyperv_blit_to_vram_rect(struct drm_framebuffer *fb, 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 drm_rect *rect)
{ {
struct hyperv_drm_device *hv = to_hv(fb->dev); 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; 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 = { struct drm_rect fullscreen = {
.x1 = 0, .x1 = 0,

View File

@@ -32,8 +32,9 @@ subdir-ccflags-y += -I$(srctree)/$(src)
# core driver code # core driver code
i915-y += i915_driver.o \ i915-y += i915_driver.o \
i915_config.o \ i915_config.o \
i915_irq.o \
i915_getparam.o \ i915_getparam.o \
i915_ioctl.o \
i915_irq.o \
i915_mitigations.o \ i915_mitigations.o \
i915_module.o \ i915_module.o \
i915_params.o \ i915_params.o \

View File

@@ -18,6 +18,7 @@
#include "intel_fifo_underrun.h" #include "intel_fifo_underrun.h"
#include "intel_hdmi.h" #include "intel_hdmi.h"
#include "intel_hotplug.h" #include "intel_hotplug.h"
#include "intel_pch_display.h"
#include "intel_pps.h" #include "intel_pps.h"
#include "vlv_sideband.h" #include "vlv_sideband.h"
@@ -333,6 +334,21 @@ static bool intel_dp_get_hw_state(struct intel_encoder *encoder,
return ret; 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, static void intel_dp_get_config(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config) struct intel_crtc_state *pipe_config)
{ {
@@ -384,7 +400,7 @@ static void intel_dp_get_config(struct intel_encoder *encoder,
pipe_config->lane_count = pipe_config->lane_count =
((tmp & DP_PORT_WIDTH_MASK) >> DP_PORT_WIDTH_SHIFT) + 1; ((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 (port == PORT_A) {
if ((intel_de_read(dev_priv, DP_A) & DP_PLL_FREQ_MASK) == DP_PLL_FREQ_162MHZ) if ((intel_de_read(dev_priv, DP_A) & DP_PLL_FREQ_MASK) == DP_PLL_FREQ_162MHZ)

View File

@@ -8,7 +8,7 @@
#include <linux/types.h> #include <linux/types.h>
#include "i915_reg.h" #include "i915_reg_defs.h"
enum port; enum port;
struct drm_i915_private; struct drm_i915_private;

View File

@@ -125,7 +125,7 @@ static struct intel_fbc *i9xx_plane_fbc(struct drm_i915_private *dev_priv,
enum i9xx_plane_id i9xx_plane) enum i9xx_plane_id i9xx_plane)
{ {
if (i9xx_plane_has_fbc(dev_priv, i9xx_plane)) if (i9xx_plane_has_fbc(dev_priv, i9xx_plane))
return dev_priv->fbc; return dev_priv->fbc[INTEL_FBC_A];
else else
return NULL; 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; unsigned int rotation = plane_state->hw.rotation;
u32 dspcntr; u32 dspcntr;
dspcntr = DISPLAY_PLANE_ENABLE; dspcntr = DISP_ENABLE;
if (IS_G4X(dev_priv) || IS_IRONLAKE(dev_priv) || if (IS_G4X(dev_priv) || IS_IRONLAKE(dev_priv) ||
IS_SANDYBRIDGE(dev_priv) || IS_IVYBRIDGE(dev_priv)) IS_SANDYBRIDGE(dev_priv) || IS_IVYBRIDGE(dev_priv))
dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE; dspcntr |= DISP_TRICKLE_FEED_DISABLE;
switch (fb->format->format) { switch (fb->format->format) {
case DRM_FORMAT_C8: case DRM_FORMAT_C8:
dspcntr |= DISPPLANE_8BPP; dspcntr |= DISP_FORMAT_8BPP;
break; break;
case DRM_FORMAT_XRGB1555: case DRM_FORMAT_XRGB1555:
dspcntr |= DISPPLANE_BGRX555; dspcntr |= DISP_FORMAT_BGRX555;
break; break;
case DRM_FORMAT_ARGB1555: case DRM_FORMAT_ARGB1555:
dspcntr |= DISPPLANE_BGRA555; dspcntr |= DISP_FORMAT_BGRA555;
break; break;
case DRM_FORMAT_RGB565: case DRM_FORMAT_RGB565:
dspcntr |= DISPPLANE_BGRX565; dspcntr |= DISP_FORMAT_BGRX565;
break; break;
case DRM_FORMAT_XRGB8888: case DRM_FORMAT_XRGB8888:
dspcntr |= DISPPLANE_BGRX888; dspcntr |= DISP_FORMAT_BGRX888;
break; break;
case DRM_FORMAT_XBGR8888: case DRM_FORMAT_XBGR8888:
dspcntr |= DISPPLANE_RGBX888; dspcntr |= DISP_FORMAT_RGBX888;
break; break;
case DRM_FORMAT_ARGB8888: case DRM_FORMAT_ARGB8888:
dspcntr |= DISPPLANE_BGRA888; dspcntr |= DISP_FORMAT_BGRA888;
break; break;
case DRM_FORMAT_ABGR8888: case DRM_FORMAT_ABGR8888:
dspcntr |= DISPPLANE_RGBA888; dspcntr |= DISP_FORMAT_RGBA888;
break; break;
case DRM_FORMAT_XRGB2101010: case DRM_FORMAT_XRGB2101010:
dspcntr |= DISPPLANE_BGRX101010; dspcntr |= DISP_FORMAT_BGRX101010;
break; break;
case DRM_FORMAT_XBGR2101010: case DRM_FORMAT_XBGR2101010:
dspcntr |= DISPPLANE_RGBX101010; dspcntr |= DISP_FORMAT_RGBX101010;
break; break;
case DRM_FORMAT_ARGB2101010: case DRM_FORMAT_ARGB2101010:
dspcntr |= DISPPLANE_BGRA101010; dspcntr |= DISP_FORMAT_BGRA101010;
break; break;
case DRM_FORMAT_ABGR2101010: case DRM_FORMAT_ABGR2101010:
dspcntr |= DISPPLANE_RGBA101010; dspcntr |= DISP_FORMAT_RGBA101010;
break; break;
case DRM_FORMAT_XBGR16161616F: case DRM_FORMAT_XBGR16161616F:
dspcntr |= DISPPLANE_RGBX161616; dspcntr |= DISP_FORMAT_RGBX161616;
break; break;
default: default:
MISSING_CASE(fb->format->format); 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 && if (DISPLAY_VER(dev_priv) >= 4 &&
fb->modifier == I915_FORMAT_MOD_X_TILED) fb->modifier == I915_FORMAT_MOD_X_TILED)
dspcntr |= DISPPLANE_TILED; dspcntr |= DISP_TILED;
if (rotation & DRM_MODE_ROTATE_180) if (rotation & DRM_MODE_ROTATE_180)
dspcntr |= DISPPLANE_ROTATE_180; dspcntr |= DISP_ROTATE_180;
if (rotation & DRM_MODE_REFLECT_X) if (rotation & DRM_MODE_REFLECT_X)
dspcntr |= DISPPLANE_MIRROR; dspcntr |= DISP_MIRROR;
return dspcntr; return dspcntr;
} }
@@ -354,13 +354,13 @@ static u32 i9xx_plane_ctl_crtc(const struct intel_crtc_state *crtc_state)
u32 dspcntr = 0; u32 dspcntr = 0;
if (crtc_state->gamma_enable) if (crtc_state->gamma_enable)
dspcntr |= DISPPLANE_GAMMA_ENABLE; dspcntr |= DISP_PIPE_GAMMA_ENABLE;
if (crtc_state->csc_enable) if (crtc_state->csc_enable)
dspcntr |= DISPPLANE_PIPE_CSC_ENABLE; dspcntr |= DISP_PIPE_CSC_ENABLE;
if (DISPLAY_VER(dev_priv) < 5) if (DISPLAY_VER(dev_priv) < 5)
dspcntr |= DISPPLANE_SEL_PIPE(crtc->pipe); dspcntr |= DISP_PIPE_SEL(crtc->pipe);
return dspcntr; return dspcntr;
} }
@@ -437,9 +437,9 @@ static void i9xx_plane_update_noarm(struct intel_plane *plane,
* program whatever is there. * program whatever is there.
*/ */
intel_de_write_fw(dev_priv, DSPPOS(i9xx_plane), 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), 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); 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); int crtc_h = drm_rect_height(&plane_state->uapi.dst);
intel_de_write_fw(dev_priv, PRIMPOS(i9xx_plane), 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), 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); intel_de_write_fw(dev_priv, PRIMCNSTALPHA(i9xx_plane), 0);
} }
if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
intel_de_write_fw(dev_priv, DSPOFFSET(i9xx_plane), 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) { } else if (DISPLAY_VER(dev_priv) >= 4) {
intel_de_write_fw(dev_priv, DSPLINOFF(i9xx_plane), intel_de_write_fw(dev_priv, DSPLINOFF(i9xx_plane),
linear_offset); linear_offset);
intel_de_write_fw(dev_priv, DSPTILEOFF(i9xx_plane), 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; unsigned long irqflags;
if (async_flip) if (async_flip)
dspcntr |= DISPPLANE_ASYNC_FLIP; dspcntr |= DISP_ASYNC_FLIP;
spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
intel_de_write_fw(dev_priv, DSPCNTR(i9xx_plane), dspcntr); 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)); val = intel_de_read(dev_priv, DSPCNTR(i9xx_plane));
ret = val & DISPLAY_PLANE_ENABLE; ret = val & DISP_ENABLE;
if (DISPLAY_VER(dev_priv) >= 5) if (DISPLAY_VER(dev_priv) >= 5)
*pipe = plane->pipe; *pipe = plane->pipe;
else else
*pipe = (val & DISPPLANE_SEL_PIPE_MASK) >> *pipe = REG_FIELD_GET(DISP_PIPE_SEL_MASK, val);
DISPPLANE_SEL_PIPE_SHIFT;
intel_display_power_put(dev_priv, power_domain, wakeref); intel_display_power_put(dev_priv, power_domain, wakeref);
@@ -958,32 +957,32 @@ fail:
static int i9xx_format_to_fourcc(int format) static int i9xx_format_to_fourcc(int format)
{ {
switch (format) { switch (format) {
case DISPPLANE_8BPP: case DISP_FORMAT_8BPP:
return DRM_FORMAT_C8; return DRM_FORMAT_C8;
case DISPPLANE_BGRA555: case DISP_FORMAT_BGRA555:
return DRM_FORMAT_ARGB1555; return DRM_FORMAT_ARGB1555;
case DISPPLANE_BGRX555: case DISP_FORMAT_BGRX555:
return DRM_FORMAT_XRGB1555; return DRM_FORMAT_XRGB1555;
case DISPPLANE_BGRX565: case DISP_FORMAT_BGRX565:
return DRM_FORMAT_RGB565; return DRM_FORMAT_RGB565;
default: default:
case DISPPLANE_BGRX888: case DISP_FORMAT_BGRX888:
return DRM_FORMAT_XRGB8888; return DRM_FORMAT_XRGB8888;
case DISPPLANE_RGBX888: case DISP_FORMAT_RGBX888:
return DRM_FORMAT_XBGR8888; return DRM_FORMAT_XBGR8888;
case DISPPLANE_BGRA888: case DISP_FORMAT_BGRA888:
return DRM_FORMAT_ARGB8888; return DRM_FORMAT_ARGB8888;
case DISPPLANE_RGBA888: case DISP_FORMAT_RGBA888:
return DRM_FORMAT_ABGR8888; return DRM_FORMAT_ABGR8888;
case DISPPLANE_BGRX101010: case DISP_FORMAT_BGRX101010:
return DRM_FORMAT_XRGB2101010; return DRM_FORMAT_XRGB2101010;
case DISPPLANE_RGBX101010: case DISP_FORMAT_RGBX101010:
return DRM_FORMAT_XBGR2101010; return DRM_FORMAT_XBGR2101010;
case DISPPLANE_BGRA101010: case DISP_FORMAT_BGRA101010:
return DRM_FORMAT_ARGB2101010; return DRM_FORMAT_ARGB2101010;
case DISPPLANE_RGBA101010: case DISP_FORMAT_RGBA101010:
return DRM_FORMAT_ABGR2101010; return DRM_FORMAT_ABGR2101010;
case DISPPLANE_RGBX161616: case DISP_FORMAT_RGBX161616:
return DRM_FORMAT_XBGR16161616F; 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)); val = intel_de_read(dev_priv, DSPCNTR(i9xx_plane));
if (DISPLAY_VER(dev_priv) >= 4) { if (DISPLAY_VER(dev_priv) >= 4) {
if (val & DISPPLANE_TILED) { if (val & DISP_TILED) {
plane_config->tiling = I915_TILING_X; plane_config->tiling = I915_TILING_X;
fb->modifier = I915_FORMAT_MOD_X_TILED; fb->modifier = I915_FORMAT_MOD_X_TILED;
} }
if (val & DISPPLANE_ROTATE_180) if (val & DISP_ROTATE_180)
plane_config->rotation = DRM_MODE_ROTATE_180; plane_config->rotation = DRM_MODE_ROTATE_180;
} }
if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B && if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B &&
val & DISPPLANE_MIRROR) val & DISP_MIRROR)
plane_config->rotation |= DRM_MODE_REFLECT_X; 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); fourcc = i9xx_format_to_fourcc(pixel_format);
fb->format = drm_format_info(fourcc); fb->format = drm_format_info(fourcc);
if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
offset = intel_de_read(dev_priv, DSPOFFSET(i9xx_plane)); 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) { } else if (DISPLAY_VER(dev_priv) >= 4) {
if (plane_config->tiling) if (plane_config->tiling)
offset = intel_de_read(dev_priv, offset = intel_de_read(dev_priv,
@@ -1048,15 +1047,15 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
else else
offset = intel_de_read(dev_priv, offset = intel_de_read(dev_priv,
DSPLINOFF(i9xx_plane)); 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 { } else {
base = intel_de_read(dev_priv, DSPADDR(i9xx_plane)); base = intel_de_read(dev_priv, DSPADDR(i9xx_plane));
} }
plane_config->base = base; plane_config->base = base;
val = intel_de_read(dev_priv, PIPESRC(pipe)); val = intel_de_read(dev_priv, PIPESRC(pipe));
fb->width = ((val >> 16) & 0xfff) + 1; fb->width = REG_FIELD_GET(PIPESRC_WIDTH_MASK, val) + 1;
fb->height = ((val >> 0) & 0xfff) + 1; fb->height = REG_FIELD_GET(PIPESRC_HEIGHT_MASK, val) + 1;
val = intel_de_read(dev_priv, DSPSTRIDE(i9xx_plane)); val = intel_de_read(dev_priv, DSPSTRIDE(i9xx_plane));
fb->pitches[0] = val & 0xffffffc0; fb->pitches[0] = val & 0xffffffc0;

View File

@@ -32,6 +32,7 @@
#include "intel_atomic.h" #include "intel_atomic.h"
#include "intel_backlight.h" #include "intel_backlight.h"
#include "intel_combo_phy.h" #include "intel_combo_phy.h"
#include "intel_combo_phy_regs.h"
#include "intel_connector.h" #include "intel_connector.h"
#include "intel_crtc.h" #include "intel_crtc.h"
#include "intel_ddi.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 */ /* wait for transcoder to be enabled */
if (intel_de_wait_for_set(dev_priv, PIPECONF(dsi_trans), if (intel_de_wait_for_set(dev_priv, PIPECONF(dsi_trans),
I965_PIPECONF_ACTIVE, 10)) PIPECONF_STATE_ENABLE, 10))
drm_err(&dev_priv->drm, drm_err(&dev_priv->drm,
"DSI transcoder not enabled\n"); "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_dsi_pps_write(encoder, pipe_config);
intel_dsc_enable(pipe_config);
/* step6c: configure transcoder timings */ /* step6c: configure transcoder timings */
gen11_dsi_set_transcoder_timings(encoder, pipe_config); 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 */ /* wait for transcoder to be disabled */
if (intel_de_wait_for_clear(dev_priv, PIPECONF(dsi_trans), if (intel_de_wait_for_clear(dev_priv, PIPECONF(dsi_trans),
I965_PIPECONF_ACTIVE, 50)) PIPECONF_STATE_ENABLE, 50))
drm_err(&dev_priv->drm, drm_err(&dev_priv->drm,
"DSI trancoder not disabled\n"); "DSI trancoder not disabled\n");
} }

View File

@@ -34,6 +34,8 @@
#include <drm/drm_fourcc.h> #include <drm/drm_fourcc.h>
#include <drm/drm_plane_helper.h> #include <drm/drm_plane_helper.h>
#include "i915_drv.h"
#include "i915_reg.h"
#include "intel_atomic.h" #include "intel_atomic.h"
#include "intel_cdclk.h" #include "intel_cdclk.h"
#include "intel_display_types.h" #include "intel_display_types.h"

View File

@@ -109,6 +109,7 @@ intel_plane_duplicate_state(struct drm_plane *plane)
intel_state->ggtt_vma = NULL; intel_state->ggtt_vma = NULL;
intel_state->dpt_vma = NULL; intel_state->dpt_vma = NULL;
intel_state->flags = 0; intel_state->flags = 0;
intel_state->do_async_flip = false;
/* add reference to fb */ /* add reference to fb */
if (intel_state->hw.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); 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); plane->async_flip(plane, crtc_state, plane_state, true);
else else
plane->update_arm(plane, crtc_state, plane_state); 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, int min_scale, int max_scale,
bool can_position) 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_framebuffer *fb = plane_state->hw.fb;
struct drm_rect *src = &plane_state->uapi.src; struct drm_rect *src = &plane_state->uapi.src;
struct drm_rect *dst = &plane_state->uapi.dst; 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); hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale); vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
if (hscale < 0 || vscale < 0) { 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("src: ", src, true);
drm_rect_debug_print("dst: ", dst, false); drm_rect_debug_print("dst: ", dst, false);
return -ERANGE; 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 && if (!can_position && plane_state->uapi.visible &&
!drm_rect_equals(dst, &clip)) { !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("dst: ", dst, false);
drm_rect_debug_print("clip: ", &clip, false); drm_rect_debug_print("clip: ", &clip, false);
return -EINVAL; return -EINVAL;

View File

@@ -16,6 +16,7 @@ struct intel_crtc;
struct intel_crtc_state; struct intel_crtc_state;
struct intel_plane; struct intel_plane;
struct intel_plane_state; struct intel_plane_state;
enum plane_id;
unsigned int intel_adjusted_rate(const struct drm_rect *src, unsigned int intel_adjusted_rate(const struct drm_rect *src,
const struct drm_rect *dst, const struct drm_rect *dst,

View File

@@ -13,6 +13,7 @@
#include "intel_dp_aux_backlight.h" #include "intel_dp_aux_backlight.h"
#include "intel_dsi_dcs_backlight.h" #include "intel_dsi_dcs_backlight.h"
#include "intel_panel.h" #include "intel_panel.h"
#include "intel_pci_config.h"
/** /**
* scale - scale values from one range to another * 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_connector *connector = to_intel_connector(old_conn_state->connector);
struct intel_panel *panel = &connector->panel; struct intel_panel *panel = &connector->panel;
intel_backlight_set_pwm_level(old_conn_state, level);
panel->backlight.pwm_state.enabled = false; panel->backlight.pwm_state.enabled = false;
pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state); pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state);
} }

View File

@@ -32,6 +32,7 @@
#include "display/intel_gmbus.h" #include "display/intel_gmbus.h"
#include "i915_drv.h" #include "i915_drv.h"
#include "i915_reg.h"
#define _INTEL_BIOS_PRIVATE #define _INTEL_BIOS_PRIVATE
#include "intel_vbt_defs.h" #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 : i915->vbt.psr.idle_frames = psr_table->idle_frames < 0 ? 0 :
psr_table->idle_frames > 15 ? 15 : psr_table->idle_frames; 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 * New psr options 0=500us, 1=100us, 2=2500us, 3=0us
* Old decimal value is wake up time in multiples of 100 us. * 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; 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) static void parse_ddi_ports(struct drm_i915_private *i915)
{ {
struct intel_bios_encoder_data *devdata; struct intel_bios_encoder_data *devdata;
if (!HAS_DDI(i915) && !IS_CHERRYVIEW(i915)) if (!has_ddi_port_info(i915))
return;
if (i915->vbt.version < 155)
return; return;
list_for_each_entry(devdata, &i915->vbt.display_devices, node) 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; 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) static struct vbt_header *oprom_get_vbt(struct drm_i915_private *i915)
{ {
struct pci_dev *pdev = to_pci_dev(i915->drm.dev); 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); pci_unmap_rom(pdev, oprom);
drm_dbg_kms(&i915->drm, "Found valid VBT in PCI ROM\n");
return vbt; return vbt;
err_free_vbt: err_free_vbt:
@@ -2418,17 +2460,23 @@ void intel_bios_init(struct drm_i915_private *i915)
init_vbt_defaults(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) { if (!vbt) {
oprom_vbt = oprom_get_vbt(i915); oprom_vbt = oprom_get_vbt(i915);
if (!oprom_vbt)
goto out;
vbt = oprom_vbt; vbt = oprom_vbt;
drm_dbg_kms(&i915->drm, "Found valid VBT in PCI ROM\n");
} }
if (!vbt)
goto out;
bdb = get_bdb_header(vbt); bdb = get_bdb_header(vbt);
i915->vbt.version = bdb->version; 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) bool intel_bios_is_port_present(struct drm_i915_private *i915, enum port port)
{ {
const struct intel_bios_encoder_data *devdata; if (WARN_ON(!has_ddi_port_info(i915)))
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 (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 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) bool intel_bios_is_port_edp(struct drm_i915_private *i915, enum port port)
{ {
const struct intel_bios_encoder_data *devdata; const struct intel_bios_encoder_data *devdata =
const struct child_device_config *child; intel_bios_encoder_data_lookup(i915, port);
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,
};
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); 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;
} }
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) != const struct child_device_config *child = &devdata->child;
(DEVICE_TYPE_DP_DUAL_MODE & DEVICE_TYPE_DP_DUAL_MODE_BITS))
if (!intel_bios_encoder_supports_dp(devdata) ||
!intel_bios_encoder_supports_hdmi(devdata))
return false; return false;
if (dvo_port_type(child->dvo_port) == DVO_PORT_DPA) 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, bool intel_bios_is_port_dp_dual_mode(struct drm_i915_private *i915,
enum port port) enum port port)
{ {
static const struct { const struct intel_bios_encoder_data *devdata =
u16 dp, hdmi; intel_bios_encoder_data_lookup(i915, port);
} 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;
if (HAS_DDI(i915)) { return devdata && intel_bios_encoder_supports_dp_dual_mode(devdata);
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;
} }
/** /**

View File

@@ -5,6 +5,7 @@
#include <drm/drm_atomic_state_helper.h> #include <drm/drm_atomic_state_helper.h>
#include "i915_reg.h"
#include "intel_atomic.h" #include "intel_atomic.h"
#include "intel_bw.h" #include "intel_bw.h"
#include "intel_cdclk.h" #include "intel_cdclk.h"
@@ -75,8 +76,7 @@ static int icl_pcode_read_qgv_point_info(struct drm_i915_private *dev_priv,
u16 dclk; u16 dclk;
int ret; int ret;
ret = sandybridge_pcode_read(dev_priv, ret = snb_pcode_read(dev_priv, ICL_PCODE_MEM_SUBSYSYSTEM_INFO |
ICL_PCODE_MEM_SUBSYSYSTEM_INFO |
ICL_PCODE_MEM_SS_READ_QGV_POINT_INFO(point), ICL_PCODE_MEM_SS_READ_QGV_POINT_INFO(point),
&val, &val2); &val, &val2);
if (ret) if (ret)
@@ -102,10 +102,8 @@ static int adls_pcode_read_psf_gv_point_info(struct drm_i915_private *dev_priv,
int ret; int ret;
int i; int i;
ret = sandybridge_pcode_read(dev_priv, ret = snb_pcode_read(dev_priv, ICL_PCODE_MEM_SUBSYSYSTEM_INFO |
ICL_PCODE_MEM_SUBSYSYSTEM_INFO | ADL_PCODE_MEM_SS_READ_PSF_GV_INFO, &val, NULL);
ADL_PCODE_MEM_SS_READ_PSF_GV_INFO,
&val, NULL);
if (ret) if (ret)
return ret; return ret;

View File

@@ -31,6 +31,7 @@
#include "intel_crtc.h" #include "intel_crtc.h"
#include "intel_de.h" #include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_pci_config.h"
#include "intel_pcode.h" #include "intel_pcode.h"
#include "intel_psr.h" #include "intel_psr.h"
#include "vlv_sideband.h" #include "vlv_sideband.h"
@@ -63,6 +64,17 @@
* dividers can be programmed correctly. * 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, void intel_cdclk_get_cdclk(struct drm_i915_private *dev_priv,
struct intel_cdclk_config *cdclk_config) 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")) "trying to change cdclk frequency with cdclk not enabled\n"))
return; return;
ret = sandybridge_pcode_write(dev_priv, ret = snb_pcode_write(dev_priv, BDW_PCODE_DISPLAY_FREQ_CHANGE_REQ, 0x0);
BDW_PCODE_DISPLAY_FREQ_CHANGE_REQ, 0x0);
if (ret) { if (ret) {
drm_err(&dev_priv->drm, drm_err(&dev_priv->drm,
"failed to inform pcode about cdclk change\n"); "failed to inform pcode about cdclk change\n");
@@ -822,7 +833,7 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
LCPLL_CD_SOURCE_FCLK_DONE) == 0, 1)) LCPLL_CD_SOURCE_FCLK_DONE) == 0, 1))
drm_err(&dev_priv->drm, "Switching back to LCPLL failed\n"); drm_err(&dev_priv->drm, "Switching back to LCPLL failed\n");
sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ, snb_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ,
cdclk_config->voltage_level); cdclk_config->voltage_level);
intel_de_write(dev_priv, CDCLK_FREQ, intel_de_write(dev_priv, CDCLK_FREQ,
@@ -1126,7 +1137,7 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,
intel_de_posting_read(dev_priv, CDCLK_CTL); intel_de_posting_read(dev_priv, CDCLK_CTL);
/* inform PCU of the change */ /* inform PCU of the change */
sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL, snb_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL,
cdclk_config->voltage_level); cdclk_config->voltage_level);
intel_update_cdclk(dev_priv); intel_update_cdclk(dev_priv);
@@ -1145,7 +1156,7 @@ static void skl_sanitize_cdclk(struct drm_i915_private *dev_priv)
goto sanitize; goto sanitize;
intel_update_cdclk(dev_priv); 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 ? */ /* Is PLL enabled and locked ? */
if (dev_priv->cdclk.hw.vco == 0 || 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 */ /* Timeout 200us */
if (intel_de_wait_for_set(dev_priv, BXT_DE_PLL_ENABLE, if (intel_de_wait_for_set(dev_priv, BXT_DE_PLL_ENABLE,
BXT_DE_PLL_LOCK | BXT_DE_PLL_FREQ_REQ_ACK, 1)) 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; val &= ~BXT_DE_PLL_FREQ_REQ;
intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, val); 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 * BSpec requires us to wait up to 150usec, but that leads to
* timeouts; the 2ms used here is based on experiment. * timeouts; the 2ms used here is based on experiment.
*/ */
ret = sandybridge_pcode_write_timeout(dev_priv, ret = snb_pcode_write_timeout(dev_priv,
HSW_PCODE_DE_WRITE_FREQ_REQ, HSW_PCODE_DE_WRITE_FREQ_REQ,
0x80000000, 150, 2); 0x80000000, 150, 2);
if (ret) { if (ret) {
drm_err(&dev_priv->drm, drm_err(&dev_priv->drm,
"Failed to inform PCU about cdclk change (err %d, freq %d)\n", "Failed to inform PCU about cdclk change (err %d, freq %d)\n",
@@ -1769,7 +1779,7 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
intel_crtc_wait_for_next_vblank(intel_crtc_for_pipe(dev_priv, pipe)); intel_crtc_wait_for_next_vblank(intel_crtc_for_pipe(dev_priv, pipe));
if (DISPLAY_VER(dev_priv) >= 11) { if (DISPLAY_VER(dev_priv) >= 11) {
ret = sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL, ret = snb_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL,
cdclk_config->voltage_level); cdclk_config->voltage_level);
} else { } else {
/* /*
@@ -1778,7 +1788,7 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
* FIXME: Waiting for the request completion could be delayed * FIXME: Waiting for the request completion could be delayed
* until the next PCODE request based on BSpec. * until the next PCODE request based on BSpec.
*/ */
ret = sandybridge_pcode_write_timeout(dev_priv, ret = snb_pcode_write_timeout(dev_priv,
HSW_PCODE_DE_WRITE_FREQ_REQ, HSW_PCODE_DE_WRITE_FREQ_REQ,
cdclk_config->voltage_level, cdclk_config->voltage_level,
150, 2); 150, 2);
@@ -1807,7 +1817,7 @@ static void bxt_sanitize_cdclk(struct drm_i915_private *dev_priv)
int cdclk, clock, vco; int cdclk, clock, vco;
intel_update_cdclk(dev_priv); 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 || if (dev_priv->cdclk.hw.vco == 0 ||
dev_priv->cdclk.hw.cdclk == dev_priv->cdclk.hw.bypass) dev_priv->cdclk.hw.cdclk == dev_priv->cdclk.hw.bypass)
@@ -2047,10 +2057,11 @@ static bool intel_cdclk_changed(const struct intel_cdclk_config *a,
a->voltage_level != b->voltage_level; 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) const char *context)
{ {
DRM_DEBUG_DRIVER("%s %d kHz, VCO %d kHz, ref %d kHz, bypass %d kHz, voltage level %d\n", 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, context, cdclk_config->cdclk, cdclk_config->vco,
cdclk_config->ref, cdclk_config->bypass, cdclk_config->ref, cdclk_config->bypass,
cdclk_config->voltage_level); 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)) if (drm_WARN_ON_ONCE(&dev_priv->drm, !dev_priv->cdclk_funcs->set_cdclk))
return; 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) { for_each_intel_encoder_with_psr(&dev_priv->drm, encoder) {
struct intel_dp *intel_dp = enc_to_intel_dp(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, if (drm_WARN(&dev_priv->drm,
intel_cdclk_changed(&dev_priv->cdclk.hw, cdclk_config), intel_cdclk_changed(&dev_priv->cdclk.hw, cdclk_config),
"cdclk state doesn't match!\n")) { "cdclk state doesn't match!\n")) {
intel_dump_cdclk_config(&dev_priv->cdclk.hw, "[hw state]"); intel_cdclk_dump_config(dev_priv, &dev_priv->cdclk.hw, "[hw state]");
intel_dump_cdclk_config(cdclk_config, "[sw state]"); intel_cdclk_dump_config(dev_priv, cdclk_config, "[sw state]");
} }
} }

View File

@@ -8,7 +8,6 @@
#include <linux/types.h> #include <linux/types.h>
#include "i915_drv.h"
#include "intel_display.h" #include "intel_display.h"
#include "intel_global_state.h" #include "intel_global_state.h"
@@ -16,6 +15,11 @@ struct drm_i915_private;
struct intel_atomic_state; struct intel_atomic_state;
struct intel_crtc_state; struct intel_crtc_state;
struct intel_cdclk_config {
unsigned int cdclk, vco, ref, bypass;
u8 voltage_level;
};
struct intel_cdclk_state { struct intel_cdclk_state {
struct intel_global_state base; 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); const struct intel_cdclk_config *b);
void intel_set_cdclk_pre_plane_update(struct intel_atomic_state *state); 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_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); const char *context);
int intel_modeset_calc_cdclk(struct intel_atomic_state *state); int intel_modeset_calc_cdclk(struct intel_atomic_state *state);
void intel_cdclk_get_cdclk(struct drm_i915_private *dev_priv, void intel_cdclk_get_cdclk(struct drm_i915_private *dev_priv,

View File

@@ -4,6 +4,7 @@
*/ */
#include "intel_combo_phy.h" #include "intel_combo_phy.h"
#include "intel_combo_phy_regs.h"
#include "intel_de.h" #include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"

View File

@@ -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__ */

View File

@@ -6,7 +6,7 @@
#ifndef __INTEL_CRT_H__ #ifndef __INTEL_CRT_H__
#define __INTEL_CRT_H__ #define __INTEL_CRT_H__
#include "i915_reg.h" #include "i915_reg_defs.h"
enum pipe; enum pipe;
struct drm_encoder; struct drm_encoder;

View File

@@ -12,6 +12,7 @@
#include <drm/drm_plane_helper.h> #include <drm/drm_plane_helper.h>
#include <drm/drm_vblank_work.h> #include <drm/drm_vblank_work.h>
#include "i915_irq.h"
#include "i915_vgpu.h" #include "i915_vgpu.h"
#include "i9xx_plane.h" #include "i9xx_plane.h"
#include "icl_dsi.h" #include "icl_dsi.h"

View File

@@ -51,16 +51,16 @@ static u32 intel_cursor_position(const struct intel_plane_state *plane_state)
u32 pos = 0; u32 pos = 0;
if (x < 0) { if (x < 0) {
pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT; pos |= CURSOR_POS_X_SIGN;
x = -x; x = -x;
} }
pos |= x << CURSOR_X_SHIFT; pos |= CURSOR_POS_X(x);
if (y < 0) { if (y < 0) {
pos |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT; pos |= CURSOR_POS_Y_SIGN;
y = -y; y = -y;
} }
pos |= y << CURSOR_Y_SHIFT; pos |= CURSOR_POS_Y(y);
return pos; return pos;
} }
@@ -180,7 +180,7 @@ static u32 i845_cursor_ctl_crtc(const struct intel_crtc_state *crtc_state)
u32 cntl = 0; u32 cntl = 0;
if (crtc_state->gamma_enable) if (crtc_state->gamma_enable)
cntl |= CURSOR_GAMMA_ENABLE; cntl |= CURSOR_PIPE_GAMMA_ENABLE;
return cntl; return cntl;
} }
@@ -264,7 +264,7 @@ static void i845_cursor_update_arm(struct intel_plane *plane,
cntl = plane_state->ctl | cntl = plane_state->ctl |
i845_cursor_ctl_crtc(crtc_state); i845_cursor_ctl_crtc(crtc_state);
size = (height << 12) | width; size = CURSOR_HEIGHT(height) | CURSOR_WIDTH(width);
base = intel_cursor_base(plane_state); base = intel_cursor_base(plane_state);
pos = intel_cursor_position(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) { plane->cursor.cntl != cntl) {
intel_de_write_fw(dev_priv, CURCNTR(PIPE_A), 0); 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, 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, CURPOS(PIPE_A), pos);
intel_de_write_fw(dev_priv, CURCNTR(PIPE_A), cntl); 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; return cntl;
if (crtc_state->gamma_enable) if (crtc_state->gamma_enable)
cntl = MCURSOR_GAMMA_ENABLE; cntl = MCURSOR_PIPE_GAMMA_ENABLE;
if (crtc_state->csc_enable) if (crtc_state->csc_enable)
cntl |= MCURSOR_PIPE_CSC_ENABLE; cntl |= MCURSOR_PIPE_CSC_ENABLE;
if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv)) if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv))
cntl |= MCURSOR_PIPE_SELECT(crtc->pipe); cntl |= MCURSOR_PIPE_SEL(crtc->pipe);
return cntl; return cntl;
} }
@@ -502,7 +502,7 @@ static void i9xx_cursor_update_arm(struct intel_plane *plane,
i9xx_cursor_ctl_crtc(crtc_state); i9xx_cursor_ctl_crtc(crtc_state);
if (width != height) 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); base = intel_cursor_base(plane_state);
pos = intel_cursor_position(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)); 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)) if (DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv))
*pipe = plane->pipe; *pipe = plane->pipe;
else else
*pipe = (val & MCURSOR_PIPE_SELECT_MASK) >> *pipe = REG_FIELD_GET(MCURSOR_PIPE_SEL_MASK, val);
MCURSOR_PIPE_SELECT_SHIFT;
intel_display_power_put(dev_priv, power_domain, wakeref); intel_display_power_put(dev_priv, power_domain, wakeref);

View File

@@ -32,6 +32,7 @@
#include "intel_audio.h" #include "intel_audio.h"
#include "intel_backlight.h" #include "intel_backlight.h"
#include "intel_combo_phy.h" #include "intel_combo_phy.h"
#include "intel_combo_phy_regs.h"
#include "intel_connector.h" #include "intel_connector.h"
#include "intel_crtc.h" #include "intel_crtc.h"
#include "intel_ddi.h" #include "intel_ddi.h"
@@ -56,6 +57,7 @@
#include "intel_snps_phy.h" #include "intel_snps_phy.h"
#include "intel_sprite.h" #include "intel_sprite.h"
#include "intel_tc.h" #include "intel_tc.h"
#include "intel_tc_phy_regs.h"
#include "intel_vdsc.h" #include "intel_vdsc.h"
#include "intel_vrr.h" #include "intel_vrr.h"
#include "skl_scaler.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); 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, static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
struct intel_encoder *encoder, struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state, 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); 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 * 7.b Configure TRANS_DDI_FUNC_CTL DDI Select, DDI Mode Select & MST
* Transport Select * 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_ddi_enable_fec(encoder, crtc_state);
intel_dsc_dp_pps_write(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, 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_ddi_enable_pipe_clock(encoder, crtc_state);
intel_dsc_dp_pps_write(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, 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); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
if (IS_DG2(dev_priv)) if (DISPLAY_VER(dev_priv) >= 12)
dg2_ddi_pre_enable_dp(state, encoder, crtc_state, conn_state);
else if (DISPLAY_VER(dev_priv) >= 12)
tgl_ddi_pre_enable_dp(state, encoder, crtc_state, conn_state); tgl_ddi_pre_enable_dp(state, encoder, crtc_state, conn_state);
else else
hsw_ddi_pre_enable_dp(state, encoder, crtc_state, conn_state); 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 /* MST will call a setting of MSA after an allocating of Virtual Channel
* from MST encoder pre_enable callback. * 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_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, 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->output_types |= BIT(INTEL_OUTPUT_DP);
pipe_config->lane_count = pipe_config->lane_count =
((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1; ((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) { if (DISPLAY_VER(dev_priv) >= 11) {
i915_reg_t dp_tp_ctl = dp_tp_ctl_reg(encoder, pipe_config); 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 = pipe_config->mst_master_transcoder =
REG_FIELD_GET(TRANS_DDI_MST_TRANSPORT_SELECT_MASK, temp); 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 |= pipe_config->infoframes.enable |=
intel_hdmi_infoframes_enabled(encoder, pipe_config); 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) const struct intel_link_m_n *m_n_2)
{ {
return m_n_1->tu == m_n_2->tu && return m_n_1->tu == m_n_2->tu &&
m_n_1->gmch_m == m_n_2->gmch_m && m_n_1->data_m == m_n_2->data_m &&
m_n_1->gmch_n == m_n_2->gmch_n && m_n_1->data_n == m_n_2->data_n &&
m_n_1->link_m == m_n_2->link_m && m_n_1->link_m == m_n_2->link_m &&
m_n_1->link_n == m_n_2->link_n; m_n_1->link_n == m_n_2->link_n;
} }

View File

@@ -6,7 +6,7 @@
#ifndef __INTEL_DDI_H__ #ifndef __INTEL_DDI_H__
#define __INTEL_DDI_H__ #define __INTEL_DDI_H__
#include "i915_reg.h" #include "i915_reg_defs.h"
struct drm_connector_state; struct drm_connector_state;
struct drm_i915_private; struct drm_i915_private;

View File

@@ -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[] = { static const union intel_ddi_buf_trans_entry _dg2_snps_trans[] = {
{ .snps = { 26, 0, 0 } }, /* VS 0, pre-emph 0 */ { .snps = { 25, 0, 0 } }, /* VS 0, pre-emph 0 */
{ .snps = { 33, 0, 6 } }, /* VS 0, pre-emph 1 */ { .snps = { 32, 0, 6 } }, /* VS 0, pre-emph 1 */
{ .snps = { 38, 0, 12 } }, /* VS 0, pre-emph 2 */ { .snps = { 35, 0, 10 } }, /* VS 0, pre-emph 2 */
{ .snps = { 43, 0, 19 } }, /* VS 0, pre-emph 3 */ { .snps = { 43, 0, 17 } }, /* VS 0, pre-emph 3 */
{ .snps = { 39, 0, 0 } }, /* VS 1, pre-emph 0 */ { .snps = { 35, 0, 0 } }, /* VS 1, pre-emph 0 */
{ .snps = { 44, 0, 8 } }, /* VS 1, pre-emph 1 */ { .snps = { 45, 0, 8 } }, /* VS 1, pre-emph 1 */
{ .snps = { 47, 0, 15 } }, /* VS 1, pre-emph 2 */ { .snps = { 48, 0, 14 } }, /* VS 1, pre-emph 2 */
{ .snps = { 52, 0, 0 } }, /* VS 2, pre-emph 0 */ { .snps = { 47, 0, 0 } }, /* VS 2, pre-emph 0 */
{ .snps = { 51, 0, 10 } }, /* VS 2, pre-emph 1 */ { .snps = { 55, 0, 7 } }, /* VS 2, pre-emph 1 */
{ .snps = { 62, 0, 0 } }, /* VS 3, pre-emph 0 */ { .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[] = { static const union intel_ddi_buf_trans_entry _dg2_snps_trans_uhbr[] = {
{ .snps = { 62, 0, 0 } }, /* preset 0 */ { .snps = { 62, 0, 0 } }, /* preset 0 */
{ .snps = { 56, 0, 6 } }, /* preset 1 */ { .snps = { 55, 0, 7 } }, /* preset 1 */
{ .snps = { 51, 0, 11 } }, /* preset 2 */ { .snps = { 50, 0, 12 } }, /* preset 2 */
{ .snps = { 48, 0, 14 } }, /* preset 3 */ { .snps = { 44, 0, 18 } }, /* preset 3 */
{ .snps = { 43, 0, 19 } }, /* preset 4 */ { .snps = { 35, 0, 21 } }, /* preset 4 */
{ .snps = { 59, 3, 0 } }, /* preset 5 */ { .snps = { 59, 3, 0 } }, /* preset 5 */
{ .snps = { 53, 3, 6 } }, /* preset 6 */ { .snps = { 53, 3, 6 } }, /* preset 6 */
{ .snps = { 49, 3, 10 } }, /* preset 7 */ { .snps = { 48, 3, 11 } }, /* preset 7 */
{ .snps = { 45, 3, 14 } }, /* preset 8 */ { .snps = { 42, 5, 15 } }, /* preset 8 */
{ .snps = { 42, 3, 17 } }, /* preset 9 */ { .snps = { 37, 5, 20 } }, /* preset 9 */
{ .snps = { 56, 6, 0 } }, /* preset 10 */ { .snps = { 56, 6, 0 } }, /* preset 10 */
{ .snps = { 50, 6, 6 } }, /* preset 11 */ { .snps = { 48, 7, 7 } }, /* preset 11 */
{ .snps = { 47, 6, 9 } }, /* preset 12 */ { .snps = { 45, 7, 10 } }, /* preset 12 */
{ .snps = { 42, 6, 14 } }, /* preset 13 */ { .snps = { 39, 8, 15 } }, /* preset 13 */
{ .snps = { 46, 8, 8 } }, /* preset 14 */ { .snps = { 48, 14, 0 } }, /* preset 14 */
{ .snps = { 56, 3, 3 } }, /* preset 15 */ { .snps = { 45, 4, 4 } }, /* preset 15 */
}; };
static const struct intel_ddi_buf_trans dg2_snps_trans_uhbr = { static const struct intel_ddi_buf_trans dg2_snps_trans_uhbr = {

View File

@@ -7,7 +7,6 @@
#define __INTEL_DE_H__ #define __INTEL_DE_H__
#include "i915_drv.h" #include "i915_drv.h"
#include "i915_reg.h"
#include "i915_trace.h" #include "i915_trace.h"
#include "intel_uncore.h" #include "intel_uncore.h"

View File

@@ -118,9 +118,6 @@
static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_state); 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_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 i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state);
static void ilk_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); 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); i915_reg_t reg = PIPEDSL(pipe);
u32 line1, line2; u32 line1, line2;
u32 line_mask;
if (DISPLAY_VER(dev_priv) == 2) line1 = intel_de_read(dev_priv, reg) & PIPEDSL_LINE_MASK;
line_mask = DSL_LINEMASK_GEN2;
else
line_mask = DSL_LINEMASK_GEN3;
line1 = intel_de_read(dev_priv, reg) & line_mask;
msleep(5); msleep(5);
line2 = intel_de_read(dev_priv, reg) & line_mask; line2 = intel_de_read(dev_priv, reg) & PIPEDSL_LINE_MASK;
return line1 != line2; 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) { if (DISPLAY_VER(dev_priv) >= 4) {
enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder; enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder;
i915_reg_t reg = PIPECONF(cpu_transcoder);
/* Wait for the Pipe State to go off */ /* Wait for the Pipe State to go off */
if (intel_de_wait_for_clear(dev_priv, reg, if (intel_de_wait_for_clear(dev_priv, PIPECONF(cpu_transcoder),
I965_PIPECONF_ACTIVE, 100)) PIPECONF_STATE_ENABLE, 100))
drm_WARN(&dev_priv->drm, 1, drm_WARN(&dev_priv->drm, 1, "pipe_off wait timed out\n");
"pipe_off wait timed out\n");
} else { } else {
intel_wait_for_pipe_scanline_stopped(crtc); intel_wait_for_pipe_scanline_stopped(crtc);
} }
@@ -1118,7 +1107,7 @@ void hsw_enable_ips(const struct intel_crtc_state *crtc_state)
drm_WARN_ON(dev, !(crtc_state->active_planes & ~BIT(PLANE_CURSOR))); drm_WARN_ON(dev, !(crtc_state->active_planes & ~BIT(PLANE_CURSOR)));
if (IS_BROADWELL(dev_priv)) { if (IS_BROADWELL(dev_priv)) {
drm_WARN_ON(dev, sandybridge_pcode_write(dev_priv, DISPLAY_IPS_CONTROL, drm_WARN_ON(dev, snb_pcode_write(dev_priv, DISPLAY_IPS_CONTROL,
IPS_ENABLE | IPS_PCODE_CONTROL)); IPS_ENABLE | IPS_PCODE_CONTROL));
/* Quoting Art Runyan: "its not safe to expect any particular /* Quoting Art Runyan: "its not safe to expect any particular
* value in IPS_CTL bit 31 after enabling IPS through the * value in IPS_CTL bit 31 after enabling IPS through the
@@ -1149,7 +1138,7 @@ void hsw_disable_ips(const struct intel_crtc_state *crtc_state)
if (IS_BROADWELL(dev_priv)) { if (IS_BROADWELL(dev_priv)) {
drm_WARN_ON(dev, 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 * Wait for PCODE to finish disabling IPS. The BSpec specified
* 42ms timeout value leads to occasional timeouts so use 100ms * 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) { for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
if (plane->enable_flip_done && if (plane->enable_flip_done &&
plane->pipe == crtc->pipe && plane->pipe == crtc->pipe &&
update_planes & BIT(plane->id)) update_planes & BIT(plane->id) &&
plane_state->do_async_flip)
plane->enable_flip_done(plane); 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) { for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
if (plane->disable_flip_done && if (plane->disable_flip_done &&
plane->pipe == crtc->pipe && plane->pipe == crtc->pipe &&
update_planes & BIT(plane->id)) update_planes & BIT(plane->id) &&
plane_state->do_async_flip)
plane->disable_flip_done(plane); 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); 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, static void ilk_crtc_enable(struct intel_atomic_state *state,
struct intel_crtc *crtc) 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_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
intel_set_pch_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)) ilk_configure_cpu_transcoder(new_crtc_state);
intel_dp_set_m_n(new_crtc_state, M1_N1);
intel_set_transcoder_timings(new_crtc_state);
intel_set_pipe_src_size(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; crtc->active = true;
intel_encoders_pre_enable(state, crtc); intel_encoders_pre_enable(state, crtc);
if (new_crtc_state->has_pch_encoder) { if (new_crtc_state->has_pch_encoder) {
/* Note: FDI PLL enabling _must_ be done before we enable the ilk_pch_pre_enable(state, crtc);
* cpu pipes, hence this is separate from all the other fdi/pch
* enabling. */
ilk_fdi_pll_enable(new_crtc_state);
} else { } else {
assert_fdi_tx_disabled(dev_priv, pipe); assert_fdi_tx_disabled(dev_priv, pipe);
assert_fdi_rx_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, static void icl_ddi_bigjoiner_pre_enable(struct intel_atomic_state *state,
const struct intel_crtc_state *crtc_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_state *master_crtc_state;
struct intel_crtc *master_crtc; struct intel_crtc *master_crtc;
struct drm_connector_state *conn_state; 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) if (crtc_state->bigjoiner_slave)
intel_encoders_pre_enable(state, master_crtc); intel_encoders_pre_enable(state, master_crtc);
}
/* need to enable VDSC, which we skipped in pre-enable */ static void hsw_configure_cpu_transcoder(const struct intel_crtc_state *crtc_state)
intel_dsc_enable(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) if (crtc_state->has_pch_encoder) {
intel_uncompressed_joiner_enable(crtc_state); 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, 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); 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); intel_set_pipe_src_size(new_crtc_state);
if (DISPLAY_VER(dev_priv) >= 9 || IS_BROADWELL(dev_priv)) if (DISPLAY_VER(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
bdw_set_pipemisc(new_crtc_state); bdw_set_pipemisc(new_crtc_state);
if (!new_crtc_state->bigjoiner_slave && !transcoder_is_dsi(cpu_transcoder)) { if (!new_crtc_state->bigjoiner_slave && !transcoder_is_dsi(cpu_transcoder))
intel_set_transcoder_timings(new_crtc_state); hsw_configure_cpu_transcoder(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);
}
crtc->active = true; crtc->active = true;
@@ -2441,6 +2453,23 @@ static void modeset_put_crtc_power_domains(struct intel_crtc *crtc,
domains); 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, static void valleyview_crtc_enable(struct intel_atomic_state *state,
struct intel_crtc *crtc) 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)) if (drm_WARN_ON(&dev_priv->drm, crtc->active))
return; return;
if (intel_crtc_has_dp_encoder(new_crtc_state)) i9xx_configure_cpu_transcoder(new_crtc_state);
intel_dp_set_m_n(new_crtc_state, M1_N1);
intel_set_transcoder_timings(new_crtc_state);
intel_set_pipe_src_size(new_crtc_state); intel_set_pipe_src_size(new_crtc_state);
if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) { 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); intel_de_write(dev_priv, CHV_CANVAS(pipe), 0);
} }
i9xx_set_pipeconf(new_crtc_state);
crtc->active = true; crtc->active = true;
intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, 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)) if (drm_WARN_ON(&dev_priv->drm, crtc->active))
return; return;
if (intel_crtc_has_dp_encoder(new_crtc_state)) i9xx_configure_cpu_transcoder(new_crtc_state);
intel_dp_set_m_n(new_crtc_state, M1_N1);
intel_set_transcoder_timings(new_crtc_state);
intel_set_pipe_src_size(new_crtc_state); intel_set_pipe_src_size(new_crtc_state);
i9xx_set_pipeconf(new_crtc_state);
crtc->active = true; crtc->active = true;
if (DISPLAY_VER(dev_priv) != 2) 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; m_n->tu = 64;
compute_m_n(data_clock, compute_m_n(data_clock,
link_clock * nlanes * 8, link_clock * nlanes * 8,
&m_n->gmch_m, &m_n->gmch_n, &m_n->data_m, &m_n->data_n,
constant_n); constant_n);
compute_m_n(pixel_clock, link_clock, 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, void intel_zero_m_n(struct intel_link_m_n *m_n)
const struct intel_link_m_n *m_n)
{ {
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); /* corresponds to 0 register value */
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); memset(m_n, 0, sizeof(*m_n));
enum pipe pipe = crtc->pipe; m_n->tu = 1;
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);
} }
static bool transcoder_has_m2_n2(struct drm_i915_private *dev_priv, 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) enum transcoder transcoder)
{ {
if (IS_HASWELL(dev_priv)) if (IS_HASWELL(dev_priv))
return transcoder == TRANSCODER_EDP; return transcoder == TRANSCODER_EDP;
/* return IS_DISPLAY_VER(dev_priv, 5, 7) || IS_CHERRYVIEW(dev_priv);
* 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);
} }
static void intel_cpu_transcoder_set_m_n(const struct intel_crtc_state *crtc_state, void intel_cpu_transcoder_set_m1_n1(struct intel_crtc *crtc,
const struct intel_link_m_n *m_n, enum transcoder transcoder,
const struct intel_link_m_n *m2_n2) 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); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum pipe pipe = crtc->pipe; enum pipe pipe = crtc->pipe;
enum transcoder transcoder = crtc_state->cpu_transcoder;
if (DISPLAY_VER(dev_priv) >= 5) { if (DISPLAY_VER(dev_priv) >= 5)
intel_de_write(dev_priv, PIPE_DATA_M1(transcoder), intel_set_m_n(dev_priv, m_n,
TU_SIZE(m_n->tu) | m_n->gmch_m); PIPE_DATA_M1(transcoder), PIPE_DATA_N1(transcoder),
intel_de_write(dev_priv, PIPE_DATA_N1(transcoder), PIPE_LINK_M1(transcoder), PIPE_LINK_N1(transcoder));
m_n->gmch_n); else
intel_de_write(dev_priv, PIPE_LINK_M1(transcoder), intel_set_m_n(dev_priv, m_n,
m_n->link_m); PIPE_DATA_M_G4X(pipe), PIPE_DATA_N_G4X(pipe),
intel_de_write(dev_priv, PIPE_LINK_N1(transcoder), PIPE_LINK_M_G4X(pipe), PIPE_LINK_N_G4X(pipe));
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);
}
} }
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 *dev_priv = to_i915(crtc->base.dev);
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
if (m_n == M1_N1) { if (!intel_cpu_transcoder_has_m2_n2(dev_priv, transcoder))
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");
return; return;
}
if (crtc_state->has_pch_encoder) intel_set_m_n(dev_priv, m_n,
intel_pch_transcoder_set_m_n(crtc_state, &crtc_state->dp_m_n); PIPE_DATA_M2(transcoder), PIPE_DATA_N2(transcoder),
else PIPE_LINK_M2(transcoder), PIPE_LINK_N2(transcoder));
intel_cpu_transcoder_set_m_n(crtc_state, dp_m_n, dp_m2_n2);
} }
static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_state) 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. * always be the user's requested size.
*/ */
intel_de_write(dev_priv, PIPESRC(pipe), 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) 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; u32 tmp;
tmp = intel_de_read(dev_priv, PIPESRC(crtc->pipe)); tmp = intel_de_read(dev_priv, PIPESRC(crtc->pipe));
pipe_config->pipe_src_h = (tmp & 0xffff) + 1; pipe_config->pipe_src_w = REG_FIELD_GET(PIPESRC_WIDTH_MASK, tmp) + 1;
pipe_config->pipe_src_w = ((tmp >> 16) & 0xffff) + 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) 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) { switch (crtc_state->pipe_bpp) {
case 18: case 18:
pipeconf |= PIPECONF_6BPC; pipeconf |= PIPECONF_BPC_6;
break; break;
case 24: case 24:
pipeconf |= PIPECONF_8BPC; pipeconf |= PIPECONF_BPC_8;
break; break;
case 30: case 30:
pipeconf |= PIPECONF_10BPC; pipeconf |= PIPECONF_BPC_10;
break; break;
default: default:
/* Case prevented by intel_choose_pipe_bpp_dither. */ /* 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 else
pipeconf |= PIPECONF_INTERLACE_W_SYNC_SHIFT; pipeconf |= PIPECONF_INTERLACE_W_SYNC_SHIFT;
} else { } else {
pipeconf |= PIPECONF_PROGRESSIVE; pipeconf |= PIPECONF_INTERLACE_PROGRESSIVE;
} }
if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) && 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)); 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; crtc_state->gamma_enable = true;
if (!HAS_GMCH(dev_priv) && if (!HAS_GMCH(dev_priv) &&
tmp & DISPPLANE_PIPE_CSC_ENABLE) tmp & DISP_PIPE_CSC_ENABLE)
crtc_state->csc_enable = true; 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) || if (IS_G4X(dev_priv) || IS_VALLEYVIEW(dev_priv) ||
IS_CHERRYVIEW(dev_priv)) { IS_CHERRYVIEW(dev_priv)) {
switch (tmp & PIPECONF_BPC_MASK) { switch (tmp & PIPECONF_BPC_MASK) {
case PIPECONF_6BPC: case PIPECONF_BPC_6:
pipe_config->pipe_bpp = 18; pipe_config->pipe_bpp = 18;
break; break;
case PIPECONF_8BPC: case PIPECONF_BPC_8:
pipe_config->pipe_bpp = 24; pipe_config->pipe_bpp = 24;
break; break;
case PIPECONF_10BPC: case PIPECONF_BPC_10:
pipe_config->pipe_bpp = 30; pipe_config->pipe_bpp = 30;
break; break;
default: default:
MISSING_CASE(tmp);
break; break;
} }
} }
@@ -3596,8 +3586,7 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
(tmp & PIPECONF_COLOR_RANGE_SELECT)) (tmp & PIPECONF_COLOR_RANGE_SELECT))
pipe_config->limited_color_range = true; pipe_config->limited_color_range = true;
pipe_config->gamma_mode = (tmp & PIPECONF_GAMMA_MODE_MASK_I9XX) >> pipe_config->gamma_mode = REG_FIELD_GET(PIPECONF_GAMMA_MODE_MASK_I9XX, tmp);
PIPECONF_GAMMA_MODE_SHIFT;
if (IS_CHERRYVIEW(dev_priv)) if (IS_CHERRYVIEW(dev_priv))
pipe_config->cgm_mode = intel_de_read(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) { switch (crtc_state->pipe_bpp) {
case 18: case 18:
val |= PIPECONF_6BPC; val |= PIPECONF_BPC_6;
break; break;
case 24: case 24:
val |= PIPECONF_8BPC; val |= PIPECONF_BPC_8;
break; break;
case 30: case 30:
val |= PIPECONF_10BPC; val |= PIPECONF_BPC_10;
break; break;
case 36: case 36:
val |= PIPECONF_12BPC; val |= PIPECONF_BPC_12;
break; break;
default: default:
/* Case prevented by intel_choose_pipe_bpp_dither. */ /* 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) 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) if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
val |= PIPECONF_INTERLACED_ILK; val |= PIPECONF_INTERLACE_IF_ID_ILK;
else else
val |= PIPECONF_PROGRESSIVE; val |= PIPECONF_INTERLACE_PF_PD_ILK;
/* /*
* This would end up with an odd purple hue over * 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; u32 val = 0;
if (IS_HASWELL(dev_priv) && crtc_state->dither) 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) if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
val |= PIPECONF_INTERLACED_ILK; val |= PIPECONF_INTERLACE_IF_ID_ILK;
else else
val |= PIPECONF_PROGRESSIVE; val |= PIPECONF_INTERLACE_PF_PD_ILK;
if (IS_HASWELL(dev_priv) && if (IS_HASWELL(dev_priv) &&
crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB) 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) { switch (crtc_state->pipe_bpp) {
case 18: case 18:
val |= PIPEMISC_6_BPC; val |= PIPEMISC_BPC_6;
break; break;
case 24: case 24:
val |= PIPEMISC_8_BPC; val |= PIPEMISC_BPC_8;
break; break;
case 30: case 30:
val |= PIPEMISC_10_BPC; val |= PIPEMISC_BPC_10;
break; break;
case 36: case 36:
/* Port output 12BPC defined for ADLP+ */ /* Port output 12BPC defined for ADLP+ */
if (DISPLAY_VER(dev_priv) > 12) if (DISPLAY_VER(dev_priv) > 12)
val |= PIPEMISC_12_BPC_ADLP; val |= PIPEMISC_BPC_12_ADLP;
break; break;
default: default:
MISSING_CASE(crtc_state->pipe_bpp); 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), 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 : scaler_in_use ? PIPE_MISC2_BUBBLE_COUNTER_SCALER_EN :
PIPE_MISC2_BUBBLE_COUNTER_SCALER_DIS); 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)); tmp = intel_de_read(dev_priv, PIPEMISC(crtc->pipe));
switch (tmp & PIPEMISC_BPC_MASK) { switch (tmp & PIPEMISC_BPC_MASK) {
case PIPEMISC_6_BPC: case PIPEMISC_BPC_6:
return 18; return 18;
case PIPEMISC_8_BPC: case PIPEMISC_BPC_8:
return 24; return 24;
case PIPEMISC_10_BPC: case PIPEMISC_BPC_10:
return 30; return 30;
/* /*
* PORT OUTPUT 12 BPC defined for ADLP+. * 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 * on older platforms, need to find a workaround for 12 BPC
* MIPI DSI HW readout. * MIPI DSI HW readout.
*/ */
case PIPEMISC_12_BPC_ADLP: case PIPEMISC_BPC_12_ADLP:
if (DISPLAY_VER(dev_priv) > 12) if (DISPLAY_VER(dev_priv) > 12)
return 36; return 36;
fallthrough; 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); return DIV_ROUND_UP(bps, link_bw * 8);
} }
static void intel_pch_transcoder_get_m_n(struct intel_crtc *crtc, void intel_get_m_n(struct drm_i915_private *i915,
struct intel_link_m_n *m_n) 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; m_n->link_m = intel_de_read(i915, link_m_reg) & DATA_LINK_M_N_MASK;
struct drm_i915_private *dev_priv = to_i915(dev); m_n->link_n = intel_de_read(i915, link_n_reg) & DATA_LINK_M_N_MASK;
enum pipe pipe = crtc->pipe; 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->link_m = intel_de_read(dev_priv, PCH_TRANS_LINK_M1(pipe)); m_n->tu = REG_FIELD_GET(TU_SIZE_MASK, intel_de_read(i915, data_m_reg)) + 1;
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;
} }
static void intel_cpu_transcoder_get_m_n(struct intel_crtc *crtc, void intel_cpu_transcoder_get_m1_n1(struct intel_crtc *crtc,
enum transcoder transcoder, enum transcoder transcoder,
struct intel_link_m_n *m_n, struct intel_link_m_n *m_n)
struct intel_link_m_n *m2_n2)
{ {
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum pipe pipe = crtc->pipe; enum pipe pipe = crtc->pipe;
if (DISPLAY_VER(dev_priv) >= 5) { if (DISPLAY_VER(dev_priv) >= 5)
m_n->link_m = intel_de_read(dev_priv, intel_get_m_n(dev_priv, m_n,
PIPE_LINK_M1(transcoder)); PIPE_DATA_M1(transcoder), PIPE_DATA_N1(transcoder),
m_n->link_n = intel_de_read(dev_priv, PIPE_LINK_M1(transcoder), PIPE_LINK_N1(transcoder));
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);
else else
intel_cpu_transcoder_get_m_n(crtc, pipe_config->cpu_transcoder, intel_get_m_n(dev_priv, m_n,
&pipe_config->dp_m_n, PIPE_DATA_M_G4X(pipe), PIPE_DATA_N_G4X(pipe),
&pipe_config->dp_m2_n2); PIPE_LINK_M_G4X(pipe), PIPE_LINK_N_G4X(pipe));
} }
void ilk_get_fdi_m_n_config(struct intel_crtc *crtc, void intel_cpu_transcoder_get_m2_n2(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config) enum transcoder transcoder,
struct intel_link_m_n *m_n)
{ {
intel_cpu_transcoder_get_m_n(crtc, pipe_config->cpu_transcoder, struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
&pipe_config->fdi_m_n, NULL);
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, 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; goto out;
switch (tmp & PIPECONF_BPC_MASK) { switch (tmp & PIPECONF_BPC_MASK) {
case PIPECONF_6BPC: case PIPECONF_BPC_6:
pipe_config->pipe_bpp = 18; pipe_config->pipe_bpp = 18;
break; break;
case PIPECONF_8BPC: case PIPECONF_BPC_8:
pipe_config->pipe_bpp = 24; pipe_config->pipe_bpp = 24;
break; break;
case PIPECONF_10BPC: case PIPECONF_BPC_10:
pipe_config->pipe_bpp = 30; pipe_config->pipe_bpp = 30;
break; break;
case PIPECONF_12BPC: case PIPECONF_BPC_12:
pipe_config->pipe_bpp = 36; pipe_config->pipe_bpp = 36;
break; break;
default: default:
@@ -4066,8 +4019,7 @@ static bool ilk_get_pipe_config(struct intel_crtc *crtc,
break; break;
} }
pipe_config->gamma_mode = (tmp & PIPECONF_GAMMA_MODE_MASK_ILK) >> pipe_config->gamma_mode = REG_FIELD_GET(PIPECONF_GAMMA_MODE_MASK_ILK, tmp);
PIPECONF_GAMMA_MODE_SHIFT;
pipe_config->csc_mode = intel_de_read(dev_priv, pipe_config->csc_mode = intel_de_read(dev_priv,
PIPE_CSC_MODE(crtc->pipe)); PIPE_CSC_MODE(crtc->pipe));
@@ -4380,13 +4332,13 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
active = true; active = true;
} }
if (!active)
goto out;
intel_dsc_get_config(pipe_config); intel_dsc_get_config(pipe_config);
if (DISPLAY_VER(dev_priv) >= 13 && !pipe_config->dsc.compression_enable) if (DISPLAY_VER(dev_priv) >= 13 && !pipe_config->dsc.compression_enable)
intel_uncompressed_joiner_get_config(pipe_config); intel_uncompressed_joiner_get_config(pipe_config);
if (!active)
goto out;
if (!transcoder_is_dsi(pipe_config->cpu_transcoder) || if (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||
DISPLAY_VER(dev_priv) >= 11) DISPLAY_VER(dev_priv) >= 11)
intel_get_transcoder_timings(crtc, pipe_config); 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); 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, int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_state,
struct intel_crtc_state *new_crtc_state, struct intel_crtc_state *new_crtc_state,
const struct intel_plane_state *old_plane_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)))) needs_scaling(new_plane_state))))
new_crtc_state->disable_lp_wm = true; 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; 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); struct drm_i915_private *i915 = to_i915(pipe_config->uapi.crtc->dev);
drm_dbg_kms(&i915->drm, 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, 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); m_n->link_m, m_n->link_n, m_n->tu);
} }
@@ -5658,8 +5635,8 @@ static void intel_dump_pipe_config(const struct intel_crtc_state *pipe_config,
if (intel_crtc_has_dp_encoder(pipe_config)) { if (intel_crtc_has_dp_encoder(pipe_config)) {
intel_dump_m_n_config(pipe_config, "dp m_n", intel_dump_m_n_config(pipe_config, "dp m_n",
pipe_config->lane_count, &pipe_config->dp_m_n); pipe_config->lane_count,
if (pipe_config->has_drrs) &pipe_config->dp_m_n);
intel_dump_m_n_config(pipe_config, "dp m2_n2", intel_dump_m_n_config(pipe_config, "dp m2_n2",
pipe_config->lane_count, pipe_config->lane_count,
&pipe_config->dp_m2_n2); &pipe_config->dp_m2_n2);
@@ -6189,8 +6166,8 @@ intel_compare_link_m_n(const struct intel_link_m_n *m_n,
bool exact) bool exact)
{ {
return m_n->tu == m2_n2->tu && return m_n->tu == m2_n2->tu &&
intel_compare_m_n(m_n->gmch_m, m_n->gmch_n, intel_compare_m_n(m_n->data_m, m_n->data_n,
m2_n2->gmch_m, m2_n2->gmch_n, exact) && m2_n2->data_m, m2_n2->data_n, exact) &&
intel_compare_m_n(m_n->link_m, m_n->link_n, intel_compare_m_n(m_n->link_m, m_n->link_n,
m2_n2->link_m, m2_n2->link_n, exact); 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,\ &pipe_config->name,\
!fastset)) { \ !fastset)) { \
pipe_config_mismatch(fastset, crtc, __stringify(name), \ pipe_config_mismatch(fastset, crtc, __stringify(name), \
"(expected tu %i gmch %i/%i link %i/%i, " \ "(expected tu %i data %i/%i link %i/%i, " \
"found tu %i, gmch %i/%i link %i/%i)", \ "found tu %i, data %i/%i link %i/%i)", \
current_config->name.tu, \ current_config->name.tu, \
current_config->name.gmch_m, \ current_config->name.data_m, \
current_config->name.gmch_n, \ current_config->name.data_n, \
current_config->name.link_m, \ current_config->name.link_m, \
current_config->name.link_n, \ current_config->name.link_n, \
pipe_config->name.tu, \ pipe_config->name.tu, \
pipe_config->name.gmch_m, \ pipe_config->name.data_m, \
pipe_config->name.gmch_n, \ pipe_config->name.data_n, \
pipe_config->name.link_m, \ pipe_config->name.link_m, \
pipe_config->name.link_n); \ pipe_config->name.link_n); \
ret = false; \ ret = false; \
@@ -6416,22 +6393,22 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
!intel_compare_link_m_n(&current_config->alt_name, \ !intel_compare_link_m_n(&current_config->alt_name, \
&pipe_config->name, !fastset)) { \ &pipe_config->name, !fastset)) { \
pipe_config_mismatch(fastset, crtc, __stringify(name), \ pipe_config_mismatch(fastset, crtc, __stringify(name), \
"(expected tu %i gmch %i/%i link %i/%i, " \ "(expected tu %i data %i/%i link %i/%i, " \
"or tu %i gmch %i/%i link %i/%i, " \ "or tu %i data %i/%i link %i/%i, " \
"found tu %i, gmch %i/%i link %i/%i)", \ "found tu %i, data %i/%i link %i/%i)", \
current_config->name.tu, \ current_config->name.tu, \
current_config->name.gmch_m, \ current_config->name.data_m, \
current_config->name.gmch_n, \ current_config->name.data_n, \
current_config->name.link_m, \ current_config->name.link_m, \
current_config->name.link_n, \ current_config->name.link_n, \
current_config->alt_name.tu, \ current_config->alt_name.tu, \
current_config->alt_name.gmch_m, \ current_config->alt_name.data_m, \
current_config->alt_name.gmch_n, \ current_config->alt_name.data_n, \
current_config->alt_name.link_m, \ current_config->alt_name.link_m, \
current_config->alt_name.link_n, \ current_config->alt_name.link_n, \
pipe_config->name.tu, \ pipe_config->name.tu, \
pipe_config->name.gmch_m, \ pipe_config->name.data_m, \
pipe_config->name.gmch_n, \ pipe_config->name.data_n, \
pipe_config->name.link_m, \ pipe_config->name.link_m, \
pipe_config->name.link_n); \ pipe_config->name.link_n); \
ret = false; \ 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_I(lane_count);
PIPE_CONF_CHECK_X(lane_lat_optim_mask); PIPE_CONF_CHECK_X(lane_lat_optim_mask);
if (DISPLAY_VER(dev_priv) < 8) { if (DISPLAY_VER(dev_priv) >= 9 || IS_BROADWELL(dev_priv)) {
PIPE_CONF_CHECK_M_N(dp_m_n);
if (current_config->has_drrs)
PIPE_CONF_CHECK_M_N(dp_m2_n2);
} else
PIPE_CONF_CHECK_M_N_ALT(dp_m_n, dp_m2_n2); 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); 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 *old_crtc_state,
struct intel_crtc_state *new_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_state *slave_crtc_state, *master_crtc_state;
struct intel_crtc *slave_crtc, *master_crtc; struct intel_crtc *slave_crtc, *master_crtc;
@@ -7617,7 +7594,8 @@ static int intel_atomic_check_bigjoiner(struct intel_atomic_state *state,
slave_crtc = intel_dsc_get_bigjoiner_secondary(crtc); slave_crtc = intel_dsc_get_bigjoiner_secondary(crtc);
if (!slave_crtc) { if (!slave_crtc) {
DRM_DEBUG_KMS("[CRTC:%d:%s] Big joiner configuration requires " drm_dbg_kms(&i915->drm,
"[CRTC:%d:%s] Big joiner configuration requires "
"CRTC + 1 to be used, doesn't exist\n", "CRTC + 1 to be used, doesn't exist\n",
crtc->base.base.id, crtc->base.name); crtc->base.base.id, crtc->base.name);
return -EINVAL; return -EINVAL;
@@ -7633,13 +7611,15 @@ static int intel_atomic_check_bigjoiner(struct intel_atomic_state *state,
if (slave_crtc_state->uapi.enable) if (slave_crtc_state->uapi.enable)
goto claimed; goto claimed;
DRM_DEBUG_KMS("[CRTC:%d:%s] Used as slave for big joiner\n", drm_dbg_kms(&i915->drm,
"[CRTC:%d:%s] Used as slave for big joiner\n",
slave_crtc->base.base.id, slave_crtc->base.name); slave_crtc->base.base.id, slave_crtc->base.name);
return copy_bigjoiner_crtc_state(slave_crtc_state, new_crtc_state); return copy_bigjoiner_crtc_state(slave_crtc_state, new_crtc_state);
claimed: claimed:
DRM_DEBUG_KMS("[CRTC:%d:%s] Slave is enabled as normal CRTC, but " drm_dbg_kms(&i915->drm,
"[CRTC:%d:%s] Slave is enabled as normal CRTC, but "
"[CRTC:%d:%s] claiming this CRTC for bigjoiner.\n", "[CRTC:%d:%s] claiming this CRTC for bigjoiner.\n",
slave_crtc->base.base.id, slave_crtc->base.name, slave_crtc->base.base.id, slave_crtc->base.name,
master_crtc->base.base.id, master_crtc->base.name); master_crtc->base.base.id, master_crtc->base.name);
@@ -9478,7 +9458,7 @@ void intel_modeset_init_hw(struct drm_i915_private *i915)
cdclk_state = to_intel_cdclk_state(i915->cdclk.obj.state); cdclk_state = to_intel_cdclk_state(i915->cdclk.obj.state);
intel_update_cdclk(i915); 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; 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 */ udelay(150); /* wait for warmup */
} }
intel_de_write(dev_priv, PIPECONF(pipe), intel_de_write(dev_priv, PIPECONF(pipe), PIPECONF_ENABLE);
PIPECONF_ENABLE | PIPECONF_PROGRESSIVE);
intel_de_posting_read(dev_priv, PIPECONF(pipe)); intel_de_posting_read(dev_priv, PIPECONF(pipe));
intel_wait_for_pipe_scanline_moving(crtc); 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)); pipe_name(pipe));
drm_WARN_ON(&dev_priv->drm, drm_WARN_ON(&dev_priv->drm,
intel_de_read(dev_priv, DSPCNTR(PLANE_A)) & intel_de_read(dev_priv, DSPCNTR(PLANE_A)) & DISP_ENABLE);
DISPLAY_PLANE_ENABLE);
drm_WARN_ON(&dev_priv->drm, drm_WARN_ON(&dev_priv->drm,
intel_de_read(dev_priv, DSPCNTR(PLANE_B)) & intel_de_read(dev_priv, DSPCNTR(PLANE_B)) & DISP_ENABLE);
DISPLAY_PLANE_ENABLE);
drm_WARN_ON(&dev_priv->drm, drm_WARN_ON(&dev_priv->drm,
intel_de_read(dev_priv, DSPCNTR(PLANE_C)) & intel_de_read(dev_priv, DSPCNTR(PLANE_C)) & DISP_ENABLE);
DISPLAY_PLANE_ENABLE);
drm_WARN_ON(&dev_priv->drm, 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, 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_write(dev_priv, PIPECONF(pipe), 0);
intel_de_posting_read(dev_priv, PIPECONF(pipe)); 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); vlv_wm_sanitize(dev_priv);
} else if (DISPLAY_VER(dev_priv) >= 9) { } else if (DISPLAY_VER(dev_priv) >= 9) {
skl_wm_get_hw_state(dev_priv); skl_wm_get_hw_state(dev_priv);
skl_wm_sanitize(dev_priv);
} else if (HAS_PCH_SPLIT(dev_priv)) { } else if (HAS_PCH_SPLIT(dev_priv)) {
ilk_wm_get_hw_state(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_display_power_put(dev_priv, POWER_DOMAIN_INIT, wakeref);
intel_power_domains_sanitize_state(dev_priv);
} }
void intel_display_resume(struct drm_device *dev) void intel_display_resume(struct drm_device *dev)

View File

@@ -27,7 +27,8 @@
#include <drm/drm_util.h> #include <drm/drm_util.h>
enum link_m_n_set; #include "i915_reg_defs.h"
enum drm_scaling_filter; enum drm_scaling_filter;
struct dpll; struct dpll;
struct drm_connector; struct drm_connector;
@@ -317,8 +318,8 @@ enum aux_ch {
/* Used by dp and fdi links */ /* Used by dp and fdi links */
struct intel_link_m_n { struct intel_link_m_n {
u32 tu; u32 tu;
u32 gmch_m; u32 data_m;
u32 gmch_n; u32 data_n;
u32 link_m; u32 link_m;
u32 link_n; 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_prepare_reset(struct drm_i915_private *dev_priv);
void intel_display_finish_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, void intel_zero_m_n(struct intel_link_m_n *m_n);
struct intel_crtc_state *pipe_config); void intel_set_m_n(struct drm_i915_private *i915,
void intel_dp_set_m_n(const struct intel_crtc_state *crtc_state, const struct intel_link_m_n *m_n,
enum link_m_n_set m_n); i915_reg_t data_m_reg, i915_reg_t data_n_reg,
void ilk_get_fdi_m_n_config(struct intel_crtc *crtc, i915_reg_t link_m_reg, i915_reg_t link_n_reg);
struct intel_crtc_state *pipe_config); 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, void i9xx_crtc_clock_get(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config); struct intel_crtc_state *pipe_config);
int intel_dotclock_calculate(int link_freq, const struct intel_link_m_n *m_n); int intel_dotclock_calculate(int link_freq, const struct intel_link_m_n *m_n);

View File

@@ -2402,6 +2402,9 @@ void intel_connector_debugfs_add(struct intel_connector *intel_connector)
*/ */
void intel_crtc_debugfs_add(struct drm_crtc *crtc) void intel_crtc_debugfs_add(struct drm_crtc *crtc)
{ {
if (crtc->debugfs_entry) if (!crtc->debugfs_entry)
return;
crtc_updates_add(crtc); crtc_updates_add(crtc);
intel_fbc_crtc_debugfs_add(to_intel_crtc(crtc));
} }

View File

@@ -7,6 +7,7 @@
#include "i915_irq.h" #include "i915_irq.h"
#include "intel_cdclk.h" #include "intel_cdclk.h"
#include "intel_combo_phy.h" #include "intel_combo_phy.h"
#include "intel_combo_phy_regs.h"
#include "intel_crt.h" #include "intel_crt.h"
#include "intel_de.h" #include "intel_de.h"
#include "intel_display_power.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; int ret, tries = 0;
while (1) { while (1) {
ret = sandybridge_pcode_write_timeout(i915, ret = snb_pcode_write_timeout(i915, ICL_PCODE_EXIT_TCCOLD, 0,
ICL_PCODE_EXIT_TCCOLD, 250, 1);
0, 250, 1);
if (ret != -EAGAIN || ++tries == 3) if (ret != -EAGAIN || ++tries == 3)
break; break;
msleep(1); 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 * Spec states that we should timeout the request after 200us
* but the function below will timeout after 500us * but the function below will timeout after 500us
*/ */
ret = sandybridge_pcode_read(i915, TGL_PCODE_TCCOLD, &low_val, ret = snb_pcode_read(i915, TGL_PCODE_TCCOLD, &low_val, &high_val);
&high_val);
if (ret == 0) { if (ret == 0) {
if (block && if (block &&
(low_val & TGL_PCODE_EXIT_TCCOLD_DATA_L_EXIT_FAILED)) (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) static void hsw_write_dcomp(struct drm_i915_private *dev_priv, u32 val)
{ {
if (IS_HASWELL(dev_priv)) { if (IS_HASWELL(dev_priv)) {
if (sandybridge_pcode_write(dev_priv, if (snb_pcode_write(dev_priv, GEN6_PCODE_WRITE_D_COMP, val))
GEN6_PCODE_WRITE_D_COMP, val))
drm_dbg_kms(&dev_priv->drm, drm_dbg_kms(&dev_priv->drm,
"Failed to write to D_COMP\n"); "Failed to write to D_COMP\n");
} else { } 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_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL);
intel_update_cdclk(dev_priv); 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_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 * intel_power_domains_enable - enable toggling of display power wells
* @i915: i915 device instance * @i915: i915 device instance

View File

@@ -7,7 +7,6 @@
#define __INTEL_DISPLAY_POWER_H__ #define __INTEL_DISPLAY_POWER_H__
#include "intel_runtime_pm.h" #include "intel_runtime_pm.h"
#include "i915_reg.h"
enum dpio_channel; enum dpio_channel;
enum dpio_phy; 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, void intel_power_domains_suspend(struct drm_i915_private *dev_priv,
enum i915_drm_suspend_mode); enum i915_drm_suspend_mode);
void intel_power_domains_resume(struct drm_i915_private *dev_priv); 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_suspend_late(struct drm_i915_private *i915);
void intel_display_power_resume_early(struct drm_i915_private *i915); void intel_display_power_resume_early(struct drm_i915_private *i915);

View File

@@ -13,6 +13,7 @@
#include <linux/tracepoint.h> #include <linux/tracepoint.h>
#include "i915_drv.h" #include "i915_drv.h"
#include "i915_irq.h"
#include "intel_crtc.h" #include "intel_crtc.h"
#include "intel_display_types.h" #include "intel_display_types.h"

View File

@@ -634,6 +634,9 @@ struct intel_plane_state {
struct intel_fb_view view; struct intel_fb_view view;
/* Indicates if async flip is required */
bool do_async_flip;
/* Plane pxp decryption state */ /* Plane pxp decryption state */
bool decrypt; bool decrypt;
@@ -1442,25 +1445,6 @@ struct intel_hdmi {
}; };
struct intel_dp_mst_encoder; 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 { struct intel_dp_compliance_data {
unsigned long edid; unsigned long edid;

View File

@@ -43,9 +43,9 @@
__stringify(major) "_" \ __stringify(major) "_" \
__stringify(minor) ".bin" __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_PATH DMC_PATH(adlp, 2, 14)
#define ADLP_DMC_VERSION_REQUIRED DMC_VERSION(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)) { if (IS_ALDERLAKE_P(dev_priv)) {
dmc->fw_path = ADLP_DMC_PATH; dmc->fw_path = ADLP_DMC_PATH;
dmc->required_version = ADLP_DMC_VERSION_REQUIRED; 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)) { } else if (IS_ALDERLAKE_S(dev_priv)) {
dmc->fw_path = ADLS_DMC_PATH; dmc->fw_path = ADLS_DMC_PATH;
dmc->required_version = ADLS_DMC_VERSION_REQUIRED; 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)) { } else if (IS_DG1(dev_priv)) {
dmc->fw_path = DG1_DMC_PATH; dmc->fw_path = DG1_DMC_PATH;
dmc->required_version = DG1_DMC_VERSION_REQUIRED; 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)) { } else if (IS_ROCKETLAKE(dev_priv)) {
dmc->fw_path = RKL_DMC_PATH; dmc->fw_path = RKL_DMC_PATH;
dmc->required_version = RKL_DMC_VERSION_REQUIRED; 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) { } else if (DISPLAY_VER(dev_priv) >= 12) {
dmc->fw_path = TGL_DMC_PATH; dmc->fw_path = TGL_DMC_PATH;
dmc->required_version = TGL_DMC_VERSION_REQUIRED; 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) { } else if (DISPLAY_VER(dev_priv) == 11) {
dmc->fw_path = ICL_DMC_PATH; dmc->fw_path = ICL_DMC_PATH;
dmc->required_version = ICL_DMC_VERSION_REQUIRED; dmc->required_version = ICL_DMC_VERSION_REQUIRED;

View File

@@ -6,7 +6,7 @@
#ifndef __INTEL_DMC_H__ #ifndef __INTEL_DMC_H__
#define __INTEL_DMC_H__ #define __INTEL_DMC_H__
#include "i915_reg.h" #include "i915_reg_defs.h"
#include "intel_wakeref.h" #include "intel_wakeref.h"
#include <linux/workqueue.h> #include <linux/workqueue.h>

View File

@@ -46,6 +46,7 @@
#include "intel_atomic.h" #include "intel_atomic.h"
#include "intel_audio.h" #include "intel_audio.h"
#include "intel_backlight.h" #include "intel_backlight.h"
#include "intel_combo_phy_regs.h"
#include "intel_connector.h" #include "intel_connector.h"
#include "intel_crtc.h" #include "intel_crtc.h"
#include "intel_ddi.h" #include "intel_ddi.h"
@@ -72,8 +73,6 @@
#include "intel_vdsc.h" #include "intel_vdsc.h"
#include "intel_vrr.h" #include "intel_vrr.h"
#define DP_DPRX_ESI_LEN 14
/* DP DSC throughput values used for slice count calculations KPixels/s */ /* DP DSC throughput values used for slice count calculations KPixels/s */
#define DP_DSC_PEAK_PIXEL_RATE 2720000 #define DP_DSC_PEAK_PIXEL_RATE 2720000
#define DP_DSC_MAX_ENC_THROUGHPUT_0 340000 #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 / i915->max_cdclk_freq * 48 /
intel_dp_mode_to_fec_clock(mode_clock); 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); bits_per_pixel = min(bits_per_pixel, max_bpp_bigjoiner);
} }
@@ -1167,13 +1166,12 @@ static bool intel_dp_hdmi_tmds_clock_valid(struct intel_dp *intel_dp,
return true; return true;
} }
static bool intel_dp_hdmi_deep_color_possible(struct intel_dp *intel_dp, static bool intel_dp_hdmi_bpc_possible(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state, const struct intel_crtc_state *crtc_state,
int bpc) int bpc)
{ {
return intel_hdmi_deep_color_possible(crtc_state, bpc, return intel_hdmi_bpc_possible(crtc_state, bpc, intel_dp->has_hdmi_sink,
intel_dp->has_hdmi_sink,
intel_dp_hdmi_ycbcr420(intel_dp, crtc_state)) && intel_dp_hdmi_ycbcr420(intel_dp, crtc_state)) &&
intel_dp_hdmi_tmds_clock_valid(intel_dp, crtc_state, bpc); 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) { if (intel_dp->dfp.min_tmds_clock) {
for (; bpc >= 10; bpc -= 2) { 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; break;
} }
} }
@@ -1897,7 +1895,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
/* FIXME: abstract this better */ /* FIXME: abstract this better */
if (pipe_config->splitter.enable) 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)) if (!HAS_DDI(dev_priv))
g4x_dp_set_clock(encoder, pipe_config); g4x_dp_set_clock(encoder, pipe_config);
@@ -2813,11 +2811,22 @@ intel_dp_configure_mst(struct intel_dp *intel_dp)
} }
static bool 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, return drm_dp_dpcd_read(&intel_dp->aux, DP_SINK_COUNT_ESI, esi, 4) == 4;
sink_irq_vector, DP_DPRX_ESI_LEN) == }
DP_DPRX_ESI_LEN;
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 bool
@@ -2909,7 +2918,8 @@ out:
} }
static ssize_t 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, struct dp_sdp *sdp,
size_t size) 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)); len = hdmi_drm_infoframe_pack_only(drm_infoframe, buf, sizeof(buf));
if (len < 0) { 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; return -ENOSPC;
} }
if (len != infoframe_size) { 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; return -ENOSPC;
} }
@@ -3003,7 +3013,8 @@ static void intel_write_dp_sdp(struct intel_encoder *encoder,
sizeof(sdp)); sizeof(sdp));
break; break;
case HDMI_PACKET_TYPE_GAMUT_METADATA: 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)); &sdp, sizeof(sdp));
break; break;
default: default:
@@ -3411,22 +3422,22 @@ static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp,
switch (data->phy_pattern) { switch (data->phy_pattern) {
case DP_PHY_TEST_PATTERN_NONE: 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); intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), 0x0);
break; break;
case DP_PHY_TEST_PATTERN_D10_2: 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), intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe),
DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_D10_2); DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_D10_2);
break; break;
case DP_PHY_TEST_PATTERN_ERROR_COUNT: 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), intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe),
DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_ENABLE |
DDI_DP_COMP_CTL_SCRAMBLED_0); DDI_DP_COMP_CTL_SCRAMBLED_0);
break; break;
case DP_PHY_TEST_PATTERN_PRBS7: 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), intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe),
DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_PRBS7); DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_PRBS7);
break; 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 * current firmware of DPR-100 could not set it, so hardcoding
* now for complaince test. * 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; pattern_val = 0x3e0f83e0;
intel_de_write(dev_priv, DDI_DP_COMP_PAT(pipe, 0), pattern_val); intel_de_write(dev_priv, DDI_DP_COMP_PAT(pipe, 0), pattern_val);
pattern_val = 0x0f83e0f8; 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 * current firmware of DPR-100 could not set it, so hardcoding
* now for complaince test. * 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; pattern_val = 0xFB;
intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe),
DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_HBR2 | 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, static void intel_dp_process_phy_request(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state) const struct intel_crtc_state *crtc_state)
{ {
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
struct drm_dp_phy_test_params *data = struct drm_dp_phy_test_params *data =
&intel_dp->compliance.test_data.phytest; &intel_dp->compliance.test_data.phytest;
u8 link_status[DP_LINK_STATUS_SIZE]; u8 link_status[DP_LINK_STATUS_SIZE];
if (drm_dp_dpcd_read_phy_link_status(&intel_dp->aux, DP_PHY_DPRX, if (drm_dp_dpcd_read_phy_link_status(&intel_dp->aux, DP_PHY_DPRX,
link_status) < 0) { link_status) < 0) {
DRM_DEBUG_KMS("failed to get link status\n"); drm_dbg_kms(&i915->drm, "failed to get link status\n");
return; 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) 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 = struct drm_dp_phy_test_params *data =
&intel_dp->compliance.test_data.phytest; &intel_dp->compliance.test_data.phytest;
if (drm_dp_get_phy_test_pattern(&intel_dp->aux, data)) { 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; return DP_TEST_NAK;
} }
@@ -3615,16 +3629,45 @@ update_status:
} }
static void 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;
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) { if (esi[1] & DP_CP_IRQ) {
intel_hdcp_handle_cp_irq(intel_dp->attached_connector); intel_hdcp_handle_cp_irq(intel_dp->attached_connector);
*handled = true; 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;
}
/** /**
* intel_dp_check_mst_status - service any pending MST interrupts, check link status * intel_dp_check_mst_status - service any pending MST interrupts, check link status
* @intel_dp: Intel DP struct * @intel_dp: Intel DP struct
@@ -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); drm_WARN_ON_ONCE(&i915->drm, intel_dp->active_mst_links < 0);
for (;;) { for (;;) {
/* u8 esi[4] = {};
* The +2 is because DP_DPRX_ESI_LEN is 14, but we then u8 ack[4] = {};
* 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;
if (!intel_dp_get_sink_irq_esi(intel_dp, esi)) { if (!intel_dp_get_sink_irq_esi(intel_dp, esi)) {
drm_dbg_kms(&i915->drm, drm_dbg_kms(&i915->drm,
@@ -3670,30 +3701,22 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp)
break; 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 && if (intel_dp->active_mst_links > 0 && link_ok &&
!drm_dp_channel_eq_ok(&esi[10], intel_dp->lane_count)) { esi[3] & LINK_STATUS_CHANGED) {
drm_dbg_kms(&i915->drm, if (!intel_dp_mst_link_status(intel_dp))
"channel EQ not ok, retraining\n");
link_ok = false; 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 (!memchr_inv(ack, 0, sizeof(ack)))
if (!handled)
break; break;
for (retry = 0; retry < 3; retry++) { if (!intel_dp_ack_sink_irq_esi(intel_dp, ack))
int wret; drm_dbg_kms(&i915->drm, "Failed to ack ESI\n");
wret = drm_dp_dpcd_write(&intel_dp->aux,
DP_SINK_COUNT_ESI+1,
&esi[1], 3);
if (wret == 3)
break;
}
} }
return link_ok; return link_ok;
@@ -4974,6 +4997,14 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
mutex_lock(&dev->mode_config.mutex); mutex_lock(&dev->mode_config.mutex);
edid = drm_get_edid(connector, &intel_dp->aux.ddc); 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 (edid) {
if (drm_add_edid_modes(connector, edid)) { if (drm_add_edid_modes(connector, edid)) {
drm_connector_update_edid_property(connector, edid); drm_connector_update_edid_property(connector, edid);
@@ -5048,7 +5079,7 @@ static void intel_dp_modeset_retry_work_fn(struct work_struct *work)
intel_connector = container_of(work, typeof(*intel_connector), intel_connector = container_of(work, typeof(*intel_connector),
modeset_retry_work); modeset_retry_work);
connector = &intel_connector->base; connector = &intel_connector->base;
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, drm_dbg_kms(connector->dev, "[CONNECTOR:%d:%s]\n", connector->base.id,
connector->name); connector->name);
/* Grab the locks before changing connector property*/ /* Grab the locks before changing connector property*/

View File

@@ -8,8 +8,6 @@
#include <linux/types.h> #include <linux/types.h>
#include "i915_reg.h"
enum intel_output_format; enum intel_output_format;
enum pipe; enum pipe;
enum port; enum port;

View File

@@ -10,7 +10,7 @@
#include "intel_pps.h" #include "intel_pps.h"
#include "intel_tc.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; int i;
u32 v = 0; u32 v = 0;
@@ -22,7 +22,7 @@ u32 intel_dp_pack_aux(const u8 *src, int src_bytes)
return v; 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; int i;
@@ -267,7 +267,7 @@ intel_dp_aux_xfer(struct intel_dp *intel_dp,
for (i = 0; i < send_bytes; i += 4) for (i = 0; i < send_bytes; i += 4)
intel_uncore_write(uncore, intel_uncore_write(uncore,
ch_data[i >> 2], ch_data[i >> 2],
intel_dp_pack_aux(send + i, intel_dp_aux_pack(send + i,
send_bytes - i)); send_bytes - i));
/* Send the command and wait for it to complete */ /* Send the command and wait for it to complete */
@@ -352,7 +352,7 @@ done:
recv_bytes = recv_size; recv_bytes = recv_size;
for (i = 0; i < recv_bytes; i += 4) 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); recv + i, recv_bytes - i);
ret = recv_bytes; ret = recv_bytes;

View File

@@ -6,12 +6,8 @@
#ifndef __INTEL_DP_AUX_H__ #ifndef __INTEL_DP_AUX_H__
#define __INTEL_DP_AUX_H__ #define __INTEL_DP_AUX_H__
#include <linux/types.h>
struct intel_dp; 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_fini(struct intel_dp *intel_dp);
void intel_dp_aux_init(struct intel_dp *intel_dp); void intel_dp_aux_init(struct intel_dp *intel_dp);

View File

@@ -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_enable_pipe_clock(encoder, pipe_config);
intel_ddi_set_dp_msa(pipe_config, conn_state); 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, static void intel_mst_enable_dp(struct intel_atomic_state *state,

View File

@@ -28,6 +28,7 @@
#include "intel_dpll_mgr.h" #include "intel_dpll_mgr.h"
#include "intel_pch_refclk.h" #include "intel_pch_refclk.h"
#include "intel_tc.h" #include "intel_tc.h"
#include "intel_tc_phy_regs.h"
/** /**
* DOC: Display PLLs * DOC: Display PLLs
@@ -49,6 +50,41 @@
* commit phase. * 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 { struct intel_dpll_mgr {
const struct dpll_info *dpll_info; const struct dpll_info *dpll_info;

View File

@@ -44,6 +44,7 @@ struct intel_crtc;
struct intel_crtc_state; struct intel_crtc_state;
struct intel_encoder; struct intel_encoder;
struct intel_shared_dpll; struct intel_shared_dpll;
struct intel_shared_dpll_funcs;
/** /**
* enum intel_dpll_id - possible DPLL ids * 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_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 * struct dpll_info - display PLL platform specific info
*/ */

View File

@@ -47,17 +47,13 @@
* requested by userspace. * requested by userspace.
*/ */
void static bool can_enable_drrs(struct intel_connector *connector,
intel_drrs_compute_config(struct intel_dp *intel_dp, const struct intel_crtc_state *pipe_config)
struct intel_crtc_state *pipe_config,
int output_bpp, bool constant_n)
{ {
struct intel_connector *intel_connector = intel_dp->attached_connector; const struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
int pixel_clock;
if (pipe_config->vrr.enable) if (pipe_config->vrr.enable)
return; return false;
/* /*
* DRRS and PSR can't be enable together, so giving preference to PSR * 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(). * after intel_psr_compute_config().
*/ */
if (pipe_config->has_psr) if (pipe_config->has_psr)
return; return false;
if (!intel_connector->panel.downclock_mode || return connector->panel.downclock_mode &&
dev_priv->drrs.type != SEAMLESS_DRRS_SUPPORT) 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; return;
}
pipe_config->has_drrs = true; 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) if (pipe_config->splitter.enable)
pixel_clock /= pipe_config->splitter.link_count; pixel_clock /= pipe_config->splitter.link_count;
@@ -84,7 +95,42 @@ intel_drrs_compute_config(struct intel_dp *intel_dp,
/* FIXME: abstract this better */ /* FIXME: abstract this better */
if (pipe_config->splitter.enable) 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, 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; return;
} }
if (DISPLAY_VER(dev_priv) >= 8 && !IS_CHERRYVIEW(dev_priv)) { if (DISPLAY_VER(dev_priv) >= 8 && !IS_CHERRYVIEW(dev_priv))
switch (refresh_type) { intel_drrs_set_refresh_rate_m_n(crtc_state, refresh_type);
case DRRS_HIGH_RR: else if (DISPLAY_VER(dev_priv) > 6)
intel_dp_set_m_n(crtc_state, M1_N1); intel_drrs_set_refresh_rate_pipeconf(crtc_state, refresh_type);
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);
}
dev_priv->drrs.refresh_rate_type = 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_display_mode *fixed_mode)
{ {
struct drm_i915_private *dev_priv = to_i915(connector->base.dev); struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
struct intel_encoder *encoder = connector->encoder;
struct drm_display_mode *downclock_mode = NULL; struct drm_display_mode *downclock_mode = NULL;
INIT_DELAYED_WORK(&dev_priv->drrs.work, intel_drrs_downclock_work); INIT_DELAYED_WORK(&dev_priv->drrs.work, intel_drrs_downclock_work);
@@ -416,6 +436,13 @@ intel_drrs_init(struct intel_connector *connector,
return NULL; 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) { if (dev_priv->vbt.drrs_type != SEAMLESS_DRRS_SUPPORT) {
drm_dbg_kms(&dev_priv->drm, "VBT doesn't support DRRS\n"); drm_dbg_kms(&dev_priv->drm, "VBT doesn't support DRRS\n");
return NULL; return NULL;

View File

@@ -8,7 +8,7 @@
#include <linux/types.h> #include <linux/types.h>
#include "i915_reg.h" #include "i915_reg_defs.h"
struct intel_crtc_state; struct intel_crtc_state;
struct i915_vma; struct i915_vma;

View File

@@ -39,6 +39,7 @@
#include <video/mipi_display.h> #include <video/mipi_display.h>
#include "i915_drv.h" #include "i915_drv.h"
#include "i915_reg.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_dsi.h" #include "intel_dsi.h"
#include "intel_dsi_vbt.h" #include "intel_dsi_vbt.h"
@@ -426,24 +427,16 @@ static void i2c_acpi_find_adapter(struct intel_dsi *intel_dsi,
const u16 slave_addr) const u16 slave_addr)
{ {
struct drm_device *drm_dev = intel_dsi->base.base.dev; struct drm_device *drm_dev = intel_dsi->base.base.dev;
struct device *dev = drm_dev->dev; struct acpi_device *adev = ACPI_COMPANION(drm_dev->dev);
struct acpi_device *acpi_dev; struct i2c_adapter_lookup lookup = {
struct list_head resource_list; .slave_addr = slave_addr,
struct i2c_adapter_lookup lookup; .intel_dsi = intel_dsi,
.dev_handle = acpi_device_handle(adev),
};
LIST_HEAD(resource_list);
acpi_dev = ACPI_COMPANION(dev); acpi_dev_get_resources(adev, &resource_list, i2c_adapter_lookup, &lookup);
if (acpi_dev) {
memset(&lookup, 0, sizeof(lookup));
lookup.slave_addr = slave_addr;
lookup.intel_dsi = intel_dsi;
lookup.dev_handle = acpi_device_handle(acpi_dev);
INIT_LIST_HEAD(&resource_list);
acpi_dev_get_resources(acpi_dev, &resource_list,
i2c_adapter_lookup,
&lookup);
acpi_dev_free_resource_list(&resource_list); acpi_dev_free_resource_list(&resource_list);
}
} }
#else #else
static inline void i2c_acpi_find_adapter(struct intel_dsi *intel_dsi, static inline void i2c_acpi_find_adapter(struct intel_dsi *intel_dsi,

View File

@@ -27,7 +27,7 @@
#include <drm/drm_crtc.h> #include <drm/drm_crtc.h>
#include "i915_reg.h" #include "i915_reg_defs.h"
struct intel_dvo_device { struct intel_dvo_device {
const char *name; const char *name;

View File

@@ -49,6 +49,14 @@
#include "intel_fbc.h" #include "intel_fbc.h"
#include "intel_frontbuffer.h" #include "intel_frontbuffer.h"
#define for_each_fbc_id(__dev_priv, __fbc_id) \
for ((__fbc_id) = INTEL_FBC_A; (__fbc_id) < I915_MAX_FBCS; (__fbc_id)++) \
for_each_if(INTEL_INFO(__dev_priv)->display.fbc_mask & BIT(__fbc_id))
#define for_each_intel_fbc(__dev_priv, __fbc, __fbc_id) \
for_each_fbc_id((__dev_priv), (__fbc_id)) \
for_each_if((__fbc) = (__dev_priv)->fbc[(__fbc_id)])
struct intel_fbc_funcs { struct intel_fbc_funcs {
void (*activate)(struct intel_fbc *fbc); void (*activate)(struct intel_fbc *fbc);
void (*deactivate)(struct intel_fbc *fbc); void (*deactivate)(struct intel_fbc *fbc);
@@ -85,6 +93,8 @@ struct intel_fbc {
struct drm_mm_node compressed_fb; struct drm_mm_node compressed_fb;
struct drm_mm_node compressed_llb; struct drm_mm_node compressed_llb;
enum intel_fbc_id id;
u8 limit; u8 limit;
bool false_color; bool false_color;
@@ -454,10 +464,10 @@ static void ilk_fbc_activate(struct intel_fbc *fbc)
struct intel_fbc_state *fbc_state = &fbc->state; struct intel_fbc_state *fbc_state = &fbc->state;
struct drm_i915_private *i915 = fbc->i915; struct drm_i915_private *i915 = fbc->i915;
intel_de_write(i915, ILK_DPFC_FENCE_YOFF, intel_de_write(i915, ILK_DPFC_FENCE_YOFF(fbc->id),
fbc_state->fence_y_offset); fbc_state->fence_y_offset);
intel_de_write(i915, ILK_DPFC_CONTROL, intel_de_write(i915, ILK_DPFC_CONTROL(fbc->id),
DPFC_CTL_EN | g4x_dpfc_ctl(fbc)); DPFC_CTL_EN | g4x_dpfc_ctl(fbc));
} }
@@ -467,28 +477,28 @@ static void ilk_fbc_deactivate(struct intel_fbc *fbc)
u32 dpfc_ctl; u32 dpfc_ctl;
/* Disable compression */ /* Disable compression */
dpfc_ctl = intel_de_read(i915, ILK_DPFC_CONTROL); dpfc_ctl = intel_de_read(i915, ILK_DPFC_CONTROL(fbc->id));
if (dpfc_ctl & DPFC_CTL_EN) { if (dpfc_ctl & DPFC_CTL_EN) {
dpfc_ctl &= ~DPFC_CTL_EN; dpfc_ctl &= ~DPFC_CTL_EN;
intel_de_write(i915, ILK_DPFC_CONTROL, dpfc_ctl); intel_de_write(i915, ILK_DPFC_CONTROL(fbc->id), dpfc_ctl);
} }
} }
static bool ilk_fbc_is_active(struct intel_fbc *fbc) static bool ilk_fbc_is_active(struct intel_fbc *fbc)
{ {
return intel_de_read(fbc->i915, ILK_DPFC_CONTROL) & DPFC_CTL_EN; return intel_de_read(fbc->i915, ILK_DPFC_CONTROL(fbc->id)) & DPFC_CTL_EN;
} }
static bool ilk_fbc_is_compressing(struct intel_fbc *fbc) static bool ilk_fbc_is_compressing(struct intel_fbc *fbc)
{ {
return intel_de_read(fbc->i915, ILK_DPFC_STATUS) & DPFC_COMP_SEG_MASK; return intel_de_read(fbc->i915, ILK_DPFC_STATUS(fbc->id)) & DPFC_COMP_SEG_MASK;
} }
static void ilk_fbc_program_cfb(struct intel_fbc *fbc) static void ilk_fbc_program_cfb(struct intel_fbc *fbc)
{ {
struct drm_i915_private *i915 = fbc->i915; struct drm_i915_private *i915 = fbc->i915;
intel_de_write(i915, ILK_DPFC_CB_BASE, fbc->compressed_fb.start); intel_de_write(i915, ILK_DPFC_CB_BASE(fbc->id), fbc->compressed_fb.start);
} }
static const struct intel_fbc_funcs ilk_fbc_funcs = { static const struct intel_fbc_funcs ilk_fbc_funcs = {
@@ -524,8 +534,8 @@ static void snb_fbc_nuke(struct intel_fbc *fbc)
{ {
struct drm_i915_private *i915 = fbc->i915; struct drm_i915_private *i915 = fbc->i915;
intel_de_write(i915, MSG_FBC_REND_STATE, FBC_REND_NUKE); intel_de_write(i915, MSG_FBC_REND_STATE(fbc->id), FBC_REND_NUKE);
intel_de_posting_read(i915, MSG_FBC_REND_STATE); intel_de_posting_read(i915, MSG_FBC_REND_STATE(fbc->id));
} }
static const struct intel_fbc_funcs snb_fbc_funcs = { static const struct intel_fbc_funcs snb_fbc_funcs = {
@@ -547,7 +557,7 @@ static void glk_fbc_program_cfb_stride(struct intel_fbc *fbc)
val |= FBC_STRIDE_OVERRIDE | val |= FBC_STRIDE_OVERRIDE |
FBC_STRIDE(fbc_state->override_cfb_stride / fbc->limit); FBC_STRIDE(fbc_state->override_cfb_stride / fbc->limit);
intel_de_write(i915, GLK_FBC_STRIDE, val); intel_de_write(i915, GLK_FBC_STRIDE(fbc->id), val);
} }
static void skl_fbc_program_cfb_stride(struct intel_fbc *fbc) static void skl_fbc_program_cfb_stride(struct intel_fbc *fbc)
@@ -598,19 +608,19 @@ static void ivb_fbc_activate(struct intel_fbc *fbc)
if (i915->ggtt.num_fences) if (i915->ggtt.num_fences)
snb_fbc_program_fence(fbc); snb_fbc_program_fence(fbc);
intel_de_write(i915, ILK_DPFC_CONTROL, intel_de_write(i915, ILK_DPFC_CONTROL(fbc->id),
DPFC_CTL_EN | ivb_dpfc_ctl(fbc)); DPFC_CTL_EN | ivb_dpfc_ctl(fbc));
} }
static bool ivb_fbc_is_compressing(struct intel_fbc *fbc) static bool ivb_fbc_is_compressing(struct intel_fbc *fbc)
{ {
return intel_de_read(fbc->i915, ILK_DPFC_STATUS2) & DPFC_COMP_SEG_MASK_IVB; return intel_de_read(fbc->i915, ILK_DPFC_STATUS2(fbc->id)) & DPFC_COMP_SEG_MASK_IVB;
} }
static void ivb_fbc_set_false_color(struct intel_fbc *fbc, static void ivb_fbc_set_false_color(struct intel_fbc *fbc,
bool enable) bool enable)
{ {
intel_de_rmw(fbc->i915, ILK_DPFC_CONTROL, intel_de_rmw(fbc->i915, ILK_DPFC_CONTROL(fbc->id),
DPFC_CTL_FALSE_COLOR, enable ? DPFC_CTL_FALSE_COLOR : 0); DPFC_CTL_FALSE_COLOR, enable ? DPFC_CTL_FALSE_COLOR : 0);
} }
@@ -810,16 +820,16 @@ static void __intel_fbc_cleanup_cfb(struct intel_fbc *fbc)
void intel_fbc_cleanup(struct drm_i915_private *i915) void intel_fbc_cleanup(struct drm_i915_private *i915)
{ {
struct intel_fbc *fbc = i915->fbc; struct intel_fbc *fbc;
enum intel_fbc_id fbc_id;
if (!fbc)
return;
for_each_intel_fbc(i915, fbc, fbc_id) {
mutex_lock(&fbc->lock); mutex_lock(&fbc->lock);
__intel_fbc_cleanup_cfb(fbc); __intel_fbc_cleanup_cfb(fbc);
mutex_unlock(&fbc->lock); mutex_unlock(&fbc->lock);
kfree(fbc); kfree(fbc);
}
} }
static bool stride_is_valid(const struct intel_plane_state *plane_state) static bool stride_is_valid(const struct intel_plane_state *plane_state)
@@ -1305,15 +1315,10 @@ static unsigned int intel_fbc_get_frontbuffer_bit(struct intel_fbc *fbc)
return fbc->possible_framebuffer_bits; return fbc->possible_framebuffer_bits;
} }
void intel_fbc_invalidate(struct drm_i915_private *i915, static void __intel_fbc_invalidate(struct intel_fbc *fbc,
unsigned int frontbuffer_bits, unsigned int frontbuffer_bits,
enum fb_op_origin origin) enum fb_op_origin origin)
{ {
struct intel_fbc *fbc = i915->fbc;
if (!fbc)
return;
if (origin == ORIGIN_FLIP || origin == ORIGIN_CURSOR_UPDATE) if (origin == ORIGIN_FLIP || origin == ORIGIN_CURSOR_UPDATE)
return; return;
@@ -1327,14 +1332,22 @@ void intel_fbc_invalidate(struct drm_i915_private *i915,
mutex_unlock(&fbc->lock); mutex_unlock(&fbc->lock);
} }
void intel_fbc_flush(struct drm_i915_private *i915, void intel_fbc_invalidate(struct drm_i915_private *i915,
unsigned int frontbuffer_bits, enum fb_op_origin origin) unsigned int frontbuffer_bits,
enum fb_op_origin origin)
{ {
struct intel_fbc *fbc = i915->fbc; struct intel_fbc *fbc;
enum intel_fbc_id fbc_id;
if (!fbc) for_each_intel_fbc(i915, fbc, fbc_id)
return; __intel_fbc_invalidate(fbc, frontbuffer_bits, origin);
}
static void __intel_fbc_flush(struct intel_fbc *fbc,
unsigned int frontbuffer_bits,
enum fb_op_origin origin)
{
mutex_lock(&fbc->lock); mutex_lock(&fbc->lock);
fbc->busy_bits &= ~frontbuffer_bits; fbc->busy_bits &= ~frontbuffer_bits;
@@ -1354,6 +1367,17 @@ out:
mutex_unlock(&fbc->lock); mutex_unlock(&fbc->lock);
} }
void intel_fbc_flush(struct drm_i915_private *i915,
unsigned int frontbuffer_bits,
enum fb_op_origin origin)
{
struct intel_fbc *fbc;
enum intel_fbc_id fbc_id;
for_each_intel_fbc(i915, fbc, fbc_id)
__intel_fbc_flush(fbc, frontbuffer_bits, origin);
}
int intel_fbc_atomic_check(struct intel_atomic_state *state) int intel_fbc_atomic_check(struct intel_atomic_state *state)
{ {
struct intel_plane_state *plane_state; struct intel_plane_state *plane_state;
@@ -1483,15 +1507,15 @@ void intel_fbc_update(struct intel_atomic_state *state,
*/ */
void intel_fbc_global_disable(struct drm_i915_private *i915) void intel_fbc_global_disable(struct drm_i915_private *i915)
{ {
struct intel_fbc *fbc = i915->fbc; struct intel_fbc *fbc;
enum intel_fbc_id fbc_id;
if (!fbc)
return;
for_each_intel_fbc(i915, fbc, fbc_id) {
mutex_lock(&fbc->lock); mutex_lock(&fbc->lock);
if (fbc->state.plane) if (fbc->state.plane)
__intel_fbc_disable(fbc); __intel_fbc_disable(fbc);
mutex_unlock(&fbc->lock); mutex_unlock(&fbc->lock);
}
} }
static void intel_fbc_underrun_work_fn(struct work_struct *work) static void intel_fbc_underrun_work_fn(struct work_struct *work)
@@ -1516,19 +1540,9 @@ out:
mutex_unlock(&fbc->lock); mutex_unlock(&fbc->lock);
} }
/* static void __intel_fbc_reset_underrun(struct intel_fbc *fbc)
* intel_fbc_reset_underrun - reset FBC fifo underrun status.
* @i915: the i915 device
*
* See intel_fbc_handle_fifo_underrun_irq(). For automated testing we
* want to re-enable FBC after an underrun to increase test coverage.
*/
void intel_fbc_reset_underrun(struct drm_i915_private *i915)
{ {
struct intel_fbc *fbc = i915->fbc; struct drm_i915_private *i915 = fbc->i915;
if (!fbc)
return;
cancel_work_sync(&fbc->underrun_work); cancel_work_sync(&fbc->underrun_work);
@@ -1544,6 +1558,38 @@ void intel_fbc_reset_underrun(struct drm_i915_private *i915)
mutex_unlock(&fbc->lock); mutex_unlock(&fbc->lock);
} }
/*
* intel_fbc_reset_underrun - reset FBC fifo underrun status.
* @i915: the i915 device
*
* See intel_fbc_handle_fifo_underrun_irq(). For automated testing we
* want to re-enable FBC after an underrun to increase test coverage.
*/
void intel_fbc_reset_underrun(struct drm_i915_private *i915)
{
struct intel_fbc *fbc;
enum intel_fbc_id fbc_id;
for_each_intel_fbc(i915, fbc, fbc_id)
__intel_fbc_reset_underrun(fbc);
}
static void __intel_fbc_handle_fifo_underrun_irq(struct intel_fbc *fbc)
{
/*
* There's no guarantee that underrun_detected won't be set to true
* right after this check and before the work is scheduled, but that's
* not a problem since we'll check it again under the work function
* while FBC is locked. This check here is just to prevent us from
* unnecessarily scheduling the work, and it relies on the fact that we
* never switch underrun_detect back to false after it's true.
*/
if (READ_ONCE(fbc->underrun_detected))
return;
schedule_work(&fbc->underrun_work);
}
/** /**
* intel_fbc_handle_fifo_underrun_irq - disable FBC when we get a FIFO underrun * intel_fbc_handle_fifo_underrun_irq - disable FBC when we get a FIFO underrun
* @i915: i915 device * @i915: i915 device
@@ -1560,21 +1606,11 @@ void intel_fbc_reset_underrun(struct drm_i915_private *i915)
*/ */
void intel_fbc_handle_fifo_underrun_irq(struct drm_i915_private *i915) void intel_fbc_handle_fifo_underrun_irq(struct drm_i915_private *i915)
{ {
struct intel_fbc *fbc = i915->fbc; struct intel_fbc *fbc;
enum intel_fbc_id fbc_id;
if (!fbc) for_each_intel_fbc(i915, fbc, fbc_id)
return; __intel_fbc_handle_fifo_underrun_irq(fbc);
/* There's no guarantee that underrun_detected won't be set to true
* right after this check and before the work is scheduled, but that's
* not a problem since we'll check it again under the work function
* while FBC is locked. This check here is just to prevent us from
* unnecessarily scheduling the work, and it relies on the fact that we
* never switch underrun_detect back to false after it's true. */
if (READ_ONCE(fbc->underrun_detected))
return;
schedule_work(&fbc->underrun_work);
} }
/* /*
@@ -1622,7 +1658,8 @@ void intel_fbc_add_plane(struct intel_fbc *fbc, struct intel_plane *plane)
fbc->possible_framebuffer_bits |= plane->frontbuffer_bit; fbc->possible_framebuffer_bits |= plane->frontbuffer_bit;
} }
static struct intel_fbc *intel_fbc_create(struct drm_i915_private *i915) static struct intel_fbc *intel_fbc_create(struct drm_i915_private *i915,
enum intel_fbc_id fbc_id)
{ {
struct intel_fbc *fbc; struct intel_fbc *fbc;
@@ -1630,6 +1667,7 @@ static struct intel_fbc *intel_fbc_create(struct drm_i915_private *i915)
if (!fbc) if (!fbc)
return NULL; return NULL;
fbc->id = fbc_id;
fbc->i915 = i915; fbc->i915 = i915;
INIT_WORK(&fbc->underrun_work, intel_fbc_underrun_work_fn); INIT_WORK(&fbc->underrun_work, intel_fbc_underrun_work_fn);
mutex_init(&fbc->lock); mutex_init(&fbc->lock);
@@ -1658,32 +1696,35 @@ static struct intel_fbc *intel_fbc_create(struct drm_i915_private *i915)
*/ */
void intel_fbc_init(struct drm_i915_private *i915) void intel_fbc_init(struct drm_i915_private *i915)
{ {
struct intel_fbc *fbc; enum intel_fbc_id fbc_id;
if (!drm_mm_initialized(&i915->mm.stolen)) if (!drm_mm_initialized(&i915->mm.stolen))
mkwrite_device_info(i915)->display.has_fbc = false; mkwrite_device_info(i915)->display.fbc_mask = 0;
if (need_fbc_vtd_wa(i915)) if (need_fbc_vtd_wa(i915))
mkwrite_device_info(i915)->display.has_fbc = false; mkwrite_device_info(i915)->display.fbc_mask = 0;
i915->params.enable_fbc = intel_sanitize_fbc_option(i915); i915->params.enable_fbc = intel_sanitize_fbc_option(i915);
drm_dbg_kms(&i915->drm, "Sanitized enable_fbc value: %d\n", drm_dbg_kms(&i915->drm, "Sanitized enable_fbc value: %d\n",
i915->params.enable_fbc); i915->params.enable_fbc);
if (!HAS_FBC(i915)) for_each_fbc_id(i915, fbc_id) {
return; struct intel_fbc *fbc;
fbc = intel_fbc_create(i915); fbc = intel_fbc_create(i915, fbc_id);
if (!fbc) if (!fbc)
return; continue;
/* We still don't have any sort of hardware state readout for FBC, so /*
* deactivate it in case the BIOS activated it to make sure software * We still don't have any sort of hardware state readout
* matches the hardware state. */ * for FBC, so deactivate it in case the BIOS activated it
* to make sure software matches the hardware state.
*/
if (intel_fbc_hw_is_active(fbc)) if (intel_fbc_hw_is_active(fbc))
intel_fbc_hw_deactivate(fbc); intel_fbc_hw_deactivate(fbc);
i915->fbc = fbc; i915->fbc[fbc->id] = fbc;
}
} }
static int intel_fbc_debugfs_status_show(struct seq_file *m, void *unused) static int intel_fbc_debugfs_status_show(struct seq_file *m, void *unused)
@@ -1759,25 +1800,32 @@ DEFINE_SIMPLE_ATTRIBUTE(intel_fbc_debugfs_false_color_fops,
intel_fbc_debugfs_false_color_set, intel_fbc_debugfs_false_color_set,
"%llu\n"); "%llu\n");
static void intel_fbc_debugfs_add(struct intel_fbc *fbc) static void intel_fbc_debugfs_add(struct intel_fbc *fbc,
struct dentry *parent)
{ {
struct drm_i915_private *i915 = fbc->i915; debugfs_create_file("i915_fbc_status", 0444, parent,
struct drm_minor *minor = i915->drm.primary; fbc, &intel_fbc_debugfs_status_fops);
debugfs_create_file("i915_fbc_status", 0444,
minor->debugfs_root, fbc,
&intel_fbc_debugfs_status_fops);
if (fbc->funcs->set_false_color) if (fbc->funcs->set_false_color)
debugfs_create_file("i915_fbc_false_color", 0644, debugfs_create_file("i915_fbc_false_color", 0644, parent,
minor->debugfs_root, fbc, fbc, &intel_fbc_debugfs_false_color_fops);
&intel_fbc_debugfs_false_color_fops);
} }
void intel_fbc_crtc_debugfs_add(struct intel_crtc *crtc)
{
struct intel_plane *plane = to_intel_plane(crtc->base.primary);
if (plane->fbc)
intel_fbc_debugfs_add(plane->fbc, crtc->base.debugfs_entry);
}
/* FIXME: remove this once igt is on board with per-crtc stuff */
void intel_fbc_debugfs_register(struct drm_i915_private *i915) void intel_fbc_debugfs_register(struct drm_i915_private *i915)
{ {
struct intel_fbc *fbc = i915->fbc; struct drm_minor *minor = i915->drm.primary;
struct intel_fbc *fbc;
fbc = i915->fbc[INTEL_FBC_A];
if (fbc) if (fbc)
intel_fbc_debugfs_add(fbc); intel_fbc_debugfs_add(fbc, minor->debugfs_root);
} }

View File

@@ -17,6 +17,12 @@ struct intel_fbc;
struct intel_plane; struct intel_plane;
struct intel_plane_state; struct intel_plane_state;
enum intel_fbc_id {
INTEL_FBC_A,
I915_MAX_FBCS,
};
int intel_fbc_atomic_check(struct intel_atomic_state *state); int intel_fbc_atomic_check(struct intel_atomic_state *state);
bool intel_fbc_pre_update(struct intel_atomic_state *state, bool intel_fbc_pre_update(struct intel_atomic_state *state,
struct intel_crtc *crtc); struct intel_crtc *crtc);
@@ -36,6 +42,7 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv,
void intel_fbc_add_plane(struct intel_fbc *fbc, struct intel_plane *plane); void intel_fbc_add_plane(struct intel_fbc *fbc, struct intel_plane *plane);
void intel_fbc_handle_fifo_underrun_irq(struct drm_i915_private *i915); void intel_fbc_handle_fifo_underrun_irq(struct drm_i915_private *i915);
void intel_fbc_reset_underrun(struct drm_i915_private *i915); void intel_fbc_reset_underrun(struct drm_i915_private *i915);
void intel_fbc_crtc_debugfs_add(struct intel_crtc *crtc);
void intel_fbc_debugfs_register(struct drm_i915_private *i915); void intel_fbc_debugfs_register(struct drm_i915_private *i915);
#endif /* __INTEL_FBC_H__ */ #endif /* __INTEL_FBC_H__ */

View File

@@ -931,13 +931,6 @@ struct i2c_adapter *intel_gmbus_get_adapter(struct drm_i915_private *dev_priv,
return &dev_priv->gmbus[pin].adapter; return &dev_priv->gmbus[pin].adapter;
} }
void intel_gmbus_set_speed(struct i2c_adapter *adapter, int speed)
{
struct intel_gmbus *bus = to_intel_gmbus(adapter);
bus->reg0 = (bus->reg0 & ~(0x3 << 8)) | speed;
}
void intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit) void intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit)
{ {
struct intel_gmbus *bus = to_intel_gmbus(adapter); struct intel_gmbus *bus = to_intel_gmbus(adapter);

View File

@@ -41,7 +41,6 @@ int intel_gmbus_output_aksv(struct i2c_adapter *adapter);
struct i2c_adapter * struct i2c_adapter *
intel_gmbus_get_adapter(struct drm_i915_private *dev_priv, unsigned int pin); intel_gmbus_get_adapter(struct drm_i915_private *dev_priv, unsigned int pin);
void intel_gmbus_set_speed(struct i2c_adapter *adapter, int speed);
void intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit); void intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit);
bool intel_gmbus_is_forced_bit(struct i2c_adapter *adapter); bool intel_gmbus_is_forced_bit(struct i2c_adapter *adapter);
void intel_gmbus_reset(struct drm_i915_private *dev_priv); void intel_gmbus_reset(struct drm_i915_private *dev_priv);

View File

@@ -297,8 +297,7 @@ static int intel_hdcp_load_keys(struct drm_i915_private *dev_priv)
* Mailbox interface. * Mailbox interface.
*/ */
if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv)) { if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv)) {
ret = sandybridge_pcode_write(dev_priv, ret = snb_pcode_write(dev_priv, SKL_PCODE_LOAD_HDCP_KEYS, 1);
SKL_PCODE_LOAD_HDCP_KEYS, 1);
if (ret) { if (ret) {
drm_err(&dev_priv->drm, drm_err(&dev_priv->drm,
"Failed to initiate HDCP key load (%d)\n", "Failed to initiate HDCP key load (%d)\n",

View File

@@ -2002,7 +2002,7 @@ intel_hdmi_mode_valid(struct drm_connector *connector,
return intel_mode_valid_max_plane_size(dev_priv, mode, false); return intel_mode_valid_max_plane_size(dev_priv, mode, false);
} }
bool intel_hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state, bool intel_hdmi_bpc_possible(const struct intel_crtc_state *crtc_state,
int bpc, bool has_hdmi_sink, bool ycbcr420_output) int bpc, bool has_hdmi_sink, bool ycbcr420_output)
{ {
struct drm_atomic_state *state = crtc_state->uapi.state; struct drm_atomic_state *state = crtc_state->uapi.state;
@@ -2010,9 +2010,6 @@ bool intel_hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
struct drm_connector *connector; struct drm_connector *connector;
int i; int i;
if (crtc_state->pipe_bpp < bpc * 3)
return false;
for_each_new_connector_in_state(state, connector, connector_state, i) { for_each_new_connector_in_state(state, connector, connector_state, i) {
if (connector_state->crtc != crtc_state->uapi.crtc) if (connector_state->crtc != crtc_state->uapi.crtc)
continue; continue;
@@ -2024,8 +2021,7 @@ bool intel_hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
return true; return true;
} }
static bool hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state, static bool hdmi_bpc_possible(const struct intel_crtc_state *crtc_state, int bpc)
int bpc)
{ {
struct drm_i915_private *dev_priv = struct drm_i915_private *dev_priv =
to_i915(crtc_state->uapi.crtc->dev); to_i915(crtc_state->uapi.crtc->dev);
@@ -2039,7 +2035,7 @@ static bool hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
* HDMI deep color affects the clocks, so it's only possible * HDMI deep color affects the clocks, so it's only possible
* when not cloning with other encoder types. * when not cloning with other encoder types.
*/ */
if (crtc_state->output_types != BIT(INTEL_OUTPUT_HDMI)) if (bpc > 8 && crtc_state->output_types != BIT(INTEL_OUTPUT_HDMI))
return false; return false;
/* Display Wa_1405510057:icl,ehl */ /* Display Wa_1405510057:icl,ehl */
@@ -2049,35 +2045,50 @@ static bool hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
adjusted_mode->crtc_hblank_start) % 8 == 2) adjusted_mode->crtc_hblank_start) % 8 == 2)
return false; return false;
return intel_hdmi_deep_color_possible(crtc_state, bpc, return intel_hdmi_bpc_possible(crtc_state, bpc, crtc_state->has_hdmi_sink,
crtc_state->has_hdmi_sink,
intel_hdmi_is_ycbcr420(crtc_state)); intel_hdmi_is_ycbcr420(crtc_state));
} }
static int intel_hdmi_compute_bpc(struct intel_encoder *encoder, static int intel_hdmi_compute_bpc(struct intel_encoder *encoder,
struct intel_crtc_state *crtc_state, struct intel_crtc_state *crtc_state,
int clock) int clock, bool respect_downstream_limits)
{ {
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
bool ycbcr420_output = intel_hdmi_is_ycbcr420(crtc_state); bool ycbcr420_output = intel_hdmi_is_ycbcr420(crtc_state);
int bpc; int bpc;
for (bpc = 12; bpc >= 10; bpc -= 2) { /*
if (hdmi_deep_color_possible(crtc_state, bpc) && * pipe_bpp could already be below 8bpc due to FDI
hdmi_port_clock_valid(intel_hdmi, * bandwidth constraints. HDMI minimum is 8bpc however.
intel_hdmi_tmds_clock(clock, bpc, ycbcr420_output), */
true, crtc_state->has_hdmi_sink) == MODE_OK) bpc = max(crtc_state->pipe_bpp / 3, 8);
/*
* We will never exceed downstream TMDS clock limits while
* attempting deep color. If the user insists on forcing an
* out of spec mode they will have to be satisfied with 8bpc.
*/
if (!respect_downstream_limits)
bpc = 8;
for (; bpc >= 8; bpc -= 2) {
int tmds_clock = intel_hdmi_tmds_clock(clock, bpc, ycbcr420_output);
if (hdmi_bpc_possible(crtc_state, bpc) &&
hdmi_port_clock_valid(intel_hdmi, tmds_clock,
respect_downstream_limits,
crtc_state->has_hdmi_sink) == MODE_OK)
return bpc; return bpc;
} }
return 8; return -EINVAL;
} }
static int intel_hdmi_compute_clock(struct intel_encoder *encoder, static int intel_hdmi_compute_clock(struct intel_encoder *encoder,
struct intel_crtc_state *crtc_state) struct intel_crtc_state *crtc_state,
bool respect_downstream_limits)
{ {
struct drm_i915_private *i915 = to_i915(encoder->base.dev); struct drm_i915_private *i915 = to_i915(encoder->base.dev);
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
const struct drm_display_mode *adjusted_mode = const struct drm_display_mode *adjusted_mode =
&crtc_state->hw.adjusted_mode; &crtc_state->hw.adjusted_mode;
int bpc, clock = adjusted_mode->crtc_clock; int bpc, clock = adjusted_mode->crtc_clock;
@@ -2085,31 +2096,25 @@ static int intel_hdmi_compute_clock(struct intel_encoder *encoder,
if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK) if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK)
clock *= 2; clock *= 2;
bpc = intel_hdmi_compute_bpc(encoder, crtc_state, clock); bpc = intel_hdmi_compute_bpc(encoder, crtc_state, clock,
respect_downstream_limits);
if (bpc < 0)
return bpc;
crtc_state->port_clock = intel_hdmi_tmds_clock(clock, bpc, crtc_state->port_clock =
intel_hdmi_is_ycbcr420(crtc_state)); intel_hdmi_tmds_clock(clock, bpc, intel_hdmi_is_ycbcr420(crtc_state));
/* /*
* pipe_bpp could already be below 8bpc due to * pipe_bpp could already be below 8bpc due to
* FDI bandwidth constraints. We shouldn't bump it * FDI bandwidth constraints. We shouldn't bump it
* back up to 8bpc in that case. * back up to the HDMI minimum 8bpc in that case.
*/ */
if (crtc_state->pipe_bpp > bpc * 3) crtc_state->pipe_bpp = min(crtc_state->pipe_bpp, bpc * 3);
crtc_state->pipe_bpp = bpc * 3;
drm_dbg_kms(&i915->drm, drm_dbg_kms(&i915->drm,
"picking %d bpc for HDMI output (pipe bpp: %d)\n", "picking %d bpc for HDMI output (pipe bpp: %d)\n",
bpc, crtc_state->pipe_bpp); bpc, crtc_state->pipe_bpp);
if (hdmi_port_clock_valid(intel_hdmi, crtc_state->port_clock,
false, crtc_state->has_hdmi_sink) != MODE_OK) {
drm_dbg_kms(&i915->drm,
"unsupported HDMI clock (%d kHz), rejecting mode\n",
crtc_state->port_clock);
return -EINVAL;
}
return 0; return 0;
} }
@@ -2170,7 +2175,8 @@ intel_hdmi_output_format(struct intel_connector *connector,
static int intel_hdmi_compute_output_format(struct intel_encoder *encoder, static int intel_hdmi_compute_output_format(struct intel_encoder *encoder,
struct intel_crtc_state *crtc_state, struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state) const struct drm_connector_state *conn_state,
bool respect_downstream_limits)
{ {
struct intel_connector *connector = to_intel_connector(conn_state->connector); struct intel_connector *connector = to_intel_connector(conn_state->connector);
const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
@@ -2187,7 +2193,7 @@ static int intel_hdmi_compute_output_format(struct intel_encoder *encoder,
crtc_state->output_format = INTEL_OUTPUT_FORMAT_RGB; crtc_state->output_format = INTEL_OUTPUT_FORMAT_RGB;
} }
ret = intel_hdmi_compute_clock(encoder, crtc_state); ret = intel_hdmi_compute_clock(encoder, crtc_state, respect_downstream_limits);
if (ret) { if (ret) {
if (intel_hdmi_is_ycbcr420(crtc_state) || if (intel_hdmi_is_ycbcr420(crtc_state) ||
!connector->base.ycbcr_420_allowed || !connector->base.ycbcr_420_allowed ||
@@ -2195,7 +2201,7 @@ static int intel_hdmi_compute_output_format(struct intel_encoder *encoder,
return ret; return ret;
crtc_state->output_format = intel_hdmi_output_format(connector, true); crtc_state->output_format = intel_hdmi_output_format(connector, true);
ret = intel_hdmi_compute_clock(encoder, crtc_state); ret = intel_hdmi_compute_clock(encoder, crtc_state, respect_downstream_limits);
} }
return ret; return ret;
@@ -2231,9 +2237,19 @@ int intel_hdmi_compute_config(struct intel_encoder *encoder,
pipe_config->has_audio = pipe_config->has_audio =
intel_hdmi_has_audio(encoder, pipe_config, conn_state); intel_hdmi_has_audio(encoder, pipe_config, conn_state);
ret = intel_hdmi_compute_output_format(encoder, pipe_config, conn_state); /*
* Try to respect downstream TMDS clock limits first, if
* that fails assume the user might know something we don't.
*/
ret = intel_hdmi_compute_output_format(encoder, pipe_config, conn_state, true);
if (ret) if (ret)
ret = intel_hdmi_compute_output_format(encoder, pipe_config, conn_state, false);
if (ret) {
drm_dbg_kms(&dev_priv->drm,
"unsupported HDMI clock (%d kHz), rejecting mode\n",
pipe_config->hw.adjusted_mode.crtc_clock);
return ret; return ret;
}
if (intel_hdmi_is_ycbcr420(pipe_config)) { if (intel_hdmi_is_ycbcr420(pipe_config)) {
ret = intel_panel_fitting(pipe_config, conn_state); ret = intel_panel_fitting(pipe_config, conn_state);
@@ -2359,6 +2375,14 @@ intel_hdmi_dp_dual_mode_detect(struct drm_connector *connector, bool has_edid)
"DP dual mode adaptor (%s) detected (max TMDS clock: %d kHz)\n", "DP dual mode adaptor (%s) detected (max TMDS clock: %d kHz)\n",
drm_dp_get_dual_mode_type_name(type), drm_dp_get_dual_mode_type_name(type),
hdmi->dp_dual_mode.max_tmds_clock); hdmi->dp_dual_mode.max_tmds_clock);
/* Older VBTs are often buggy and can't be trusted :( Play it safe. */
if ((DISPLAY_VER(dev_priv) >= 8 || IS_HASWELL(dev_priv)) &&
!intel_bios_is_port_dp_dual_mode(dev_priv, port)) {
drm_dbg_kms(&dev_priv->drm,
"Ignoring DP dual mode adaptor max TMDS clock for native HDMI port\n");
hdmi->dp_dual_mode.max_tmds_clock = 0;
}
} }
static bool static bool

View File

@@ -9,8 +9,6 @@
#include <linux/hdmi.h> #include <linux/hdmi.h>
#include <linux/types.h> #include <linux/types.h>
#include "i915_reg.h"
struct drm_connector; struct drm_connector;
struct drm_encoder; struct drm_encoder;
struct drm_i915_private; struct drm_i915_private;
@@ -46,8 +44,8 @@ void intel_read_infoframe(struct intel_encoder *encoder,
union hdmi_infoframe *frame); union hdmi_infoframe *frame);
bool intel_hdmi_limited_color_range(const struct intel_crtc_state *crtc_state, bool intel_hdmi_limited_color_range(const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state); const struct drm_connector_state *conn_state);
bool intel_hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state, int bpc, bool intel_hdmi_bpc_possible(const struct intel_crtc_state *crtc_state,
bool has_hdmi_sink, bool ycbcr420_output); int bpc, bool has_hdmi_sink, bool ycbcr420_output);
int intel_hdmi_dsc_get_bpp(int src_fractional_bpp, int slice_width, int intel_hdmi_dsc_get_bpp(int src_fractional_bpp, int slice_width,
int num_slices, int output_format, bool hdmi_all_bpp, int num_slices, int output_format, bool hdmi_all_bpp,
int hdmi_max_chunk_bytes); int hdmi_max_chunk_bytes);

View File

@@ -281,7 +281,7 @@ intel_encoder_hotplug(struct intel_encoder *encoder,
ret = true; ret = true;
if (ret) { if (ret) {
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s (epoch counter %llu->%llu)\n", drm_dbg_kms(dev, "[CONNECTOR:%d:%s] status updated from %s to %s (epoch counter %llu->%llu)\n",
connector->base.base.id, connector->base.base.id,
connector->base.name, connector->base.name,
drm_get_connector_status_name(old_status), drm_get_connector_status_name(old_status),

View File

@@ -78,11 +78,12 @@ static const char *lspcon_mode_name(enum drm_lspcon_mode mode)
static bool lspcon_detect_vendor(struct intel_lspcon *lspcon) static bool lspcon_detect_vendor(struct intel_lspcon *lspcon)
{ {
struct intel_dp *dp = lspcon_to_intel_dp(lspcon); struct intel_dp *dp = lspcon_to_intel_dp(lspcon);
struct drm_i915_private *i915 = dp_to_i915(dp);
struct drm_dp_dpcd_ident *ident; struct drm_dp_dpcd_ident *ident;
u32 vendor_oui; u32 vendor_oui;
if (drm_dp_read_desc(&dp->aux, &dp->desc, drm_dp_is_branch(dp->dpcd))) { if (drm_dp_read_desc(&dp->aux, &dp->desc, drm_dp_is_branch(dp->dpcd))) {
DRM_ERROR("Can't read description\n"); drm_err(&i915->drm, "Can't read description\n");
return false; return false;
} }
@@ -93,16 +94,16 @@ static bool lspcon_detect_vendor(struct intel_lspcon *lspcon)
switch (vendor_oui) { switch (vendor_oui) {
case LSPCON_VENDOR_MCA_OUI: case LSPCON_VENDOR_MCA_OUI:
lspcon->vendor = LSPCON_VENDOR_MCA; lspcon->vendor = LSPCON_VENDOR_MCA;
DRM_DEBUG_KMS("Vendor: Mega Chips\n"); drm_dbg_kms(&i915->drm, "Vendor: Mega Chips\n");
break; break;
case LSPCON_VENDOR_PARADE_OUI: case LSPCON_VENDOR_PARADE_OUI:
lspcon->vendor = LSPCON_VENDOR_PARADE; lspcon->vendor = LSPCON_VENDOR_PARADE;
DRM_DEBUG_KMS("Vendor: Parade Tech\n"); drm_dbg_kms(&i915->drm, "Vendor: Parade Tech\n");
break; break;
default: default:
DRM_ERROR("Invalid/Unknown vendor OUI\n"); drm_err(&i915->drm, "Invalid/Unknown vendor OUI\n");
return false; return false;
} }
@@ -119,21 +120,19 @@ static u32 get_hdr_status_reg(struct intel_lspcon *lspcon)
void lspcon_detect_hdr_capability(struct intel_lspcon *lspcon) void lspcon_detect_hdr_capability(struct intel_lspcon *lspcon)
{ {
struct intel_digital_port *dig_port = struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon);
container_of(lspcon, struct intel_digital_port, lspcon); struct drm_i915_private *i915 = dp_to_i915(intel_dp);
struct drm_device *dev = dig_port->base.base.dev;
struct intel_dp *dp = lspcon_to_intel_dp(lspcon);
u8 hdr_caps; u8 hdr_caps;
int ret; int ret;
ret = drm_dp_dpcd_read(&dp->aux, get_hdr_status_reg(lspcon), ret = drm_dp_dpcd_read(&intel_dp->aux, get_hdr_status_reg(lspcon),
&hdr_caps, 1); &hdr_caps, 1);
if (ret < 0) { if (ret < 0) {
drm_dbg_kms(dev, "HDR capability detection failed\n"); drm_dbg_kms(&i915->drm, "HDR capability detection failed\n");
lspcon->hdr_supported = false; lspcon->hdr_supported = false;
} else if (hdr_caps & 0x1) { } else if (hdr_caps & 0x1) {
drm_dbg_kms(dev, "LSPCON capable of HDR\n"); drm_dbg_kms(&i915->drm, "LSPCON capable of HDR\n");
lspcon->hdr_supported = true; lspcon->hdr_supported = true;
} }
} }
@@ -141,11 +140,12 @@ void lspcon_detect_hdr_capability(struct intel_lspcon *lspcon)
static enum drm_lspcon_mode lspcon_get_current_mode(struct intel_lspcon *lspcon) static enum drm_lspcon_mode lspcon_get_current_mode(struct intel_lspcon *lspcon)
{ {
struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon); struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon);
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
enum drm_lspcon_mode current_mode; enum drm_lspcon_mode current_mode;
struct i2c_adapter *adapter = &intel_dp->aux.ddc; struct i2c_adapter *adapter = &intel_dp->aux.ddc;
if (drm_lspcon_get_mode(intel_dp->aux.drm_dev, adapter, &current_mode)) { if (drm_lspcon_get_mode(intel_dp->aux.drm_dev, adapter, &current_mode)) {
DRM_DEBUG_KMS("Error reading LSPCON mode\n"); drm_dbg_kms(&i915->drm, "Error reading LSPCON mode\n");
return DRM_LSPCON_MODE_INVALID; return DRM_LSPCON_MODE_INVALID;
} }
return current_mode; return current_mode;
@@ -154,21 +154,23 @@ static enum drm_lspcon_mode lspcon_get_current_mode(struct intel_lspcon *lspcon)
static enum drm_lspcon_mode lspcon_wait_mode(struct intel_lspcon *lspcon, static enum drm_lspcon_mode lspcon_wait_mode(struct intel_lspcon *lspcon,
enum drm_lspcon_mode mode) enum drm_lspcon_mode mode)
{ {
struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon);
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
enum drm_lspcon_mode current_mode; enum drm_lspcon_mode current_mode;
current_mode = lspcon_get_current_mode(lspcon); current_mode = lspcon_get_current_mode(lspcon);
if (current_mode == mode) if (current_mode == mode)
goto out; goto out;
DRM_DEBUG_KMS("Waiting for LSPCON mode %s to settle\n", drm_dbg_kms(&i915->drm, "Waiting for LSPCON mode %s to settle\n",
lspcon_mode_name(mode)); lspcon_mode_name(mode));
wait_for((current_mode = lspcon_get_current_mode(lspcon)) == mode, 400); wait_for((current_mode = lspcon_get_current_mode(lspcon)) == mode, 400);
if (current_mode != mode) if (current_mode != mode)
DRM_ERROR("LSPCON mode hasn't settled\n"); drm_err(&i915->drm, "LSPCON mode hasn't settled\n");
out: out:
DRM_DEBUG_KMS("Current LSPCON mode %s\n", drm_dbg_kms(&i915->drm, "Current LSPCON mode %s\n",
lspcon_mode_name(current_mode)); lspcon_mode_name(current_mode));
return current_mode; return current_mode;
@@ -178,43 +180,46 @@ static int lspcon_change_mode(struct intel_lspcon *lspcon,
enum drm_lspcon_mode mode) enum drm_lspcon_mode mode)
{ {
struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon); struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon);
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
int err; int err;
enum drm_lspcon_mode current_mode; enum drm_lspcon_mode current_mode;
struct i2c_adapter *adapter = &intel_dp->aux.ddc; struct i2c_adapter *adapter = &intel_dp->aux.ddc;
err = drm_lspcon_get_mode(intel_dp->aux.drm_dev, adapter, &current_mode); err = drm_lspcon_get_mode(intel_dp->aux.drm_dev, adapter, &current_mode);
if (err) { if (err) {
DRM_ERROR("Error reading LSPCON mode\n"); drm_err(&i915->drm, "Error reading LSPCON mode\n");
return err; return err;
} }
if (current_mode == mode) { if (current_mode == mode) {
DRM_DEBUG_KMS("Current mode = desired LSPCON mode\n"); drm_dbg_kms(&i915->drm, "Current mode = desired LSPCON mode\n");
return 0; return 0;
} }
err = drm_lspcon_set_mode(intel_dp->aux.drm_dev, adapter, mode); err = drm_lspcon_set_mode(intel_dp->aux.drm_dev, adapter, mode);
if (err < 0) { if (err < 0) {
DRM_ERROR("LSPCON mode change failed\n"); drm_err(&i915->drm, "LSPCON mode change failed\n");
return err; return err;
} }
lspcon->mode = mode; lspcon->mode = mode;
DRM_DEBUG_KMS("LSPCON mode changed done\n"); drm_dbg_kms(&i915->drm, "LSPCON mode changed done\n");
return 0; return 0;
} }
static bool lspcon_wake_native_aux_ch(struct intel_lspcon *lspcon) static bool lspcon_wake_native_aux_ch(struct intel_lspcon *lspcon)
{ {
struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon);
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
u8 rev; u8 rev;
if (drm_dp_dpcd_readb(&lspcon_to_intel_dp(lspcon)->aux, DP_DPCD_REV, if (drm_dp_dpcd_readb(&lspcon_to_intel_dp(lspcon)->aux, DP_DPCD_REV,
&rev) != 1) { &rev) != 1) {
DRM_DEBUG_KMS("Native AUX CH down\n"); drm_dbg_kms(&i915->drm, "Native AUX CH down\n");
return false; return false;
} }
DRM_DEBUG_KMS("Native AUX CH up, DPCD version: %d.%d\n", drm_dbg_kms(&i915->drm, "Native AUX CH up, DPCD version: %d.%d\n",
rev >> 4, rev & 0xf); rev >> 4, rev & 0xf);
return true; return true;
@@ -225,6 +230,7 @@ static bool lspcon_probe(struct intel_lspcon *lspcon)
int retry; int retry;
enum drm_dp_dual_mode_type adaptor_type; enum drm_dp_dual_mode_type adaptor_type;
struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon); struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon);
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
struct i2c_adapter *adapter = &intel_dp->aux.ddc; struct i2c_adapter *adapter = &intel_dp->aux.ddc;
enum drm_lspcon_mode expected_mode; enum drm_lspcon_mode expected_mode;
@@ -242,13 +248,13 @@ static bool lspcon_probe(struct intel_lspcon *lspcon)
} }
if (adaptor_type != DRM_DP_DUAL_MODE_LSPCON) { if (adaptor_type != DRM_DP_DUAL_MODE_LSPCON) {
DRM_DEBUG_KMS("No LSPCON detected, found %s\n", drm_dbg_kms(&i915->drm, "No LSPCON detected, found %s\n",
drm_dp_get_dual_mode_type_name(adaptor_type)); drm_dp_get_dual_mode_type_name(adaptor_type));
return false; return false;
} }
/* Yay ... got a LSPCON device */ /* Yay ... got a LSPCON device */
DRM_DEBUG_KMS("LSPCON detected\n"); drm_dbg_kms(&i915->drm, "LSPCON detected\n");
lspcon->mode = lspcon_wait_mode(lspcon, expected_mode); lspcon->mode = lspcon_wait_mode(lspcon, expected_mode);
/* /*
@@ -258,7 +264,7 @@ static bool lspcon_probe(struct intel_lspcon *lspcon)
*/ */
if (lspcon->mode != DRM_LSPCON_MODE_PCON) { if (lspcon->mode != DRM_LSPCON_MODE_PCON) {
if (lspcon_change_mode(lspcon, DRM_LSPCON_MODE_PCON) < 0) { if (lspcon_change_mode(lspcon, DRM_LSPCON_MODE_PCON) < 0) {
DRM_ERROR("LSPCON mode change to PCON failed\n"); drm_err(&i915->drm, "LSPCON mode change to PCON failed\n");
return false; return false;
} }
} }
@@ -268,12 +274,13 @@ static bool lspcon_probe(struct intel_lspcon *lspcon)
static void lspcon_resume_in_pcon_wa(struct intel_lspcon *lspcon) static void lspcon_resume_in_pcon_wa(struct intel_lspcon *lspcon)
{ {
struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon); struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon);
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
unsigned long start = jiffies; unsigned long start = jiffies;
while (1) { while (1) {
if (intel_digital_port_connected(&dig_port->base)) { if (intel_digital_port_connected(&dig_port->base)) {
DRM_DEBUG_KMS("LSPCON recovering in PCON mode after %u ms\n", drm_dbg_kms(&i915->drm, "LSPCON recovering in PCON mode after %u ms\n",
jiffies_to_msecs(jiffies - start)); jiffies_to_msecs(jiffies - start));
return; return;
} }
@@ -284,7 +291,7 @@ static void lspcon_resume_in_pcon_wa(struct intel_lspcon *lspcon)
usleep_range(10000, 15000); usleep_range(10000, 15000);
} }
DRM_DEBUG_KMS("LSPCON DP descriptor mismatch after resume\n"); drm_dbg_kms(&i915->drm, "LSPCON DP descriptor mismatch after resume\n");
} }
static bool lspcon_parade_fw_ready(struct drm_dp_aux *aux) static bool lspcon_parade_fw_ready(struct drm_dp_aux *aux)
@@ -301,7 +308,7 @@ static bool lspcon_parade_fw_ready(struct drm_dp_aux *aux)
ret = drm_dp_dpcd_read(aux, LSPCON_PARADE_AVI_IF_CTRL, ret = drm_dp_dpcd_read(aux, LSPCON_PARADE_AVI_IF_CTRL,
&avi_if_ctrl, 1); &avi_if_ctrl, 1);
if (ret < 0) { if (ret < 0) {
DRM_ERROR("Failed to read AVI IF control\n"); drm_err(aux->drm_dev, "Failed to read AVI IF control\n");
return false; return false;
} }
@@ -309,7 +316,7 @@ static bool lspcon_parade_fw_ready(struct drm_dp_aux *aux)
return true; return true;
} }
DRM_ERROR("Parade FW not ready to accept AVI IF\n"); drm_err(aux->drm_dev, "Parade FW not ready to accept AVI IF\n");
return false; return false;
} }
@@ -324,7 +331,7 @@ static bool _lspcon_parade_write_infoframe_blocks(struct drm_dp_aux *aux,
while (block_count < 4) { while (block_count < 4) {
if (!lspcon_parade_fw_ready(aux)) { if (!lspcon_parade_fw_ready(aux)) {
DRM_DEBUG_KMS("LSPCON FW not ready, block %d\n", drm_dbg_kms(aux->drm_dev, "LSPCON FW not ready, block %d\n",
block_count); block_count);
return false; return false;
} }
@@ -333,7 +340,7 @@ static bool _lspcon_parade_write_infoframe_blocks(struct drm_dp_aux *aux,
data = avi_buf + block_count * 8; data = avi_buf + block_count * 8;
ret = drm_dp_dpcd_write(aux, reg, data, 8); ret = drm_dp_dpcd_write(aux, reg, data, 8);
if (ret < 0) { if (ret < 0) {
DRM_ERROR("Failed to write AVI IF block %d\n", drm_err(aux->drm_dev, "Failed to write AVI IF block %d\n",
block_count); block_count);
return false; return false;
} }
@@ -348,7 +355,7 @@ static bool _lspcon_parade_write_infoframe_blocks(struct drm_dp_aux *aux,
avi_if_ctrl = LSPCON_PARADE_AVI_IF_KICKOFF | block_count; avi_if_ctrl = LSPCON_PARADE_AVI_IF_KICKOFF | block_count;
ret = drm_dp_dpcd_write(aux, reg, &avi_if_ctrl, 1); ret = drm_dp_dpcd_write(aux, reg, &avi_if_ctrl, 1);
if (ret < 0) { if (ret < 0) {
DRM_ERROR("Failed to update (0x%x), block %d\n", drm_err(aux->drm_dev, "Failed to update (0x%x), block %d\n",
reg, block_count); reg, block_count);
return false; return false;
} }
@@ -356,7 +363,7 @@ static bool _lspcon_parade_write_infoframe_blocks(struct drm_dp_aux *aux,
block_count++; block_count++;
} }
DRM_DEBUG_KMS("Wrote AVI IF blocks successfully\n"); drm_dbg_kms(aux->drm_dev, "Wrote AVI IF blocks successfully\n");
return true; return true;
} }
@@ -378,14 +385,14 @@ static bool _lspcon_write_avi_infoframe_parade(struct drm_dp_aux *aux,
*/ */
if (len > LSPCON_PARADE_AVI_IF_DATA_SIZE - 1) { if (len > LSPCON_PARADE_AVI_IF_DATA_SIZE - 1) {
DRM_ERROR("Invalid length of infoframes\n"); drm_err(aux->drm_dev, "Invalid length of infoframes\n");
return false; return false;
} }
memcpy(&avi_if[1], frame, len); memcpy(&avi_if[1], frame, len);
if (!_lspcon_parade_write_infoframe_blocks(aux, avi_if)) { if (!_lspcon_parade_write_infoframe_blocks(aux, avi_if)) {
DRM_DEBUG_KMS("Failed to write infoframe blocks\n"); drm_dbg_kms(aux->drm_dev, "Failed to write infoframe blocks\n");
return false; return false;
} }
@@ -412,7 +419,7 @@ static bool _lspcon_write_avi_infoframe_mca(struct drm_dp_aux *aux,
mdelay(50); mdelay(50);
continue; continue;
} else { } else {
DRM_ERROR("DPCD write failed at:0x%x\n", reg); drm_err(aux->drm_dev, "DPCD write failed at:0x%x\n", reg);
return false; return false;
} }
} }
@@ -423,7 +430,7 @@ static bool _lspcon_write_avi_infoframe_mca(struct drm_dp_aux *aux,
reg = LSPCON_MCA_AVI_IF_CTRL; reg = LSPCON_MCA_AVI_IF_CTRL;
ret = drm_dp_dpcd_read(aux, reg, &val, 1); ret = drm_dp_dpcd_read(aux, reg, &val, 1);
if (ret < 0) { if (ret < 0) {
DRM_ERROR("DPCD read failed, address 0x%x\n", reg); drm_err(aux->drm_dev, "DPCD read failed, address 0x%x\n", reg);
return false; return false;
} }
@@ -433,19 +440,19 @@ static bool _lspcon_write_avi_infoframe_mca(struct drm_dp_aux *aux,
ret = drm_dp_dpcd_write(aux, reg, &val, 1); ret = drm_dp_dpcd_write(aux, reg, &val, 1);
if (ret < 0) { if (ret < 0) {
DRM_ERROR("DPCD read failed, address 0x%x\n", reg); drm_err(aux->drm_dev, "DPCD read failed, address 0x%x\n", reg);
return false; return false;
} }
val = 0; val = 0;
ret = drm_dp_dpcd_read(aux, reg, &val, 1); ret = drm_dp_dpcd_read(aux, reg, &val, 1);
if (ret < 0) { if (ret < 0) {
DRM_ERROR("DPCD read failed, address 0x%x\n", reg); drm_err(aux->drm_dev, "DPCD read failed, address 0x%x\n", reg);
return false; return false;
} }
if (val == LSPCON_MCA_AVI_IF_HANDLED) if (val == LSPCON_MCA_AVI_IF_HANDLED)
DRM_DEBUG_KMS("AVI IF handled by FW\n"); drm_dbg_kms(aux->drm_dev, "AVI IF handled by FW\n");
return true; return true;
} }
@@ -457,6 +464,7 @@ void lspcon_write_infoframe(struct intel_encoder *encoder,
{ {
bool ret = true; bool ret = true;
struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
struct intel_lspcon *lspcon = enc_to_intel_lspcon(encoder); struct intel_lspcon *lspcon = enc_to_intel_lspcon(encoder);
switch (type) { switch (type) {
@@ -469,7 +477,7 @@ void lspcon_write_infoframe(struct intel_encoder *encoder,
frame, len); frame, len);
break; break;
case HDMI_PACKET_TYPE_GAMUT_METADATA: case HDMI_PACKET_TYPE_GAMUT_METADATA:
drm_dbg_kms(encoder->base.dev, "Update HDR metadata for lspcon\n"); drm_dbg_kms(&i915->drm, "Update HDR metadata for lspcon\n");
/* It uses the legacy hsw implementation for the same */ /* It uses the legacy hsw implementation for the same */
hsw_write_infoframe(encoder, crtc_state, type, frame, len); hsw_write_infoframe(encoder, crtc_state, type, frame, len);
break; break;
@@ -478,7 +486,7 @@ void lspcon_write_infoframe(struct intel_encoder *encoder,
} }
if (!ret) { if (!ret) {
DRM_ERROR("Failed to write infoframes\n"); drm_err(&i915->drm, "Failed to write infoframes\n");
return; return;
} }
} }
@@ -504,11 +512,12 @@ void lspcon_set_infoframes(struct intel_encoder *encoder,
u8 buf[VIDEO_DIP_DATA_SIZE]; u8 buf[VIDEO_DIP_DATA_SIZE];
struct intel_digital_port *dig_port = enc_to_dig_port(encoder); struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
struct intel_lspcon *lspcon = &dig_port->lspcon; struct intel_lspcon *lspcon = &dig_port->lspcon;
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
const struct drm_display_mode *adjusted_mode = const struct drm_display_mode *adjusted_mode =
&crtc_state->hw.adjusted_mode; &crtc_state->hw.adjusted_mode;
if (!lspcon->active) { if (!lspcon->active) {
DRM_ERROR("Writing infoframes while LSPCON disabled ?\n"); drm_err(&i915->drm, "Writing infoframes while LSPCON disabled ?\n");
return; return;
} }
@@ -518,7 +527,7 @@ void lspcon_set_infoframes(struct intel_encoder *encoder,
conn_state->connector, conn_state->connector,
adjusted_mode); adjusted_mode);
if (ret < 0) { if (ret < 0) {
DRM_ERROR("couldn't fill AVI infoframe\n"); drm_err(&i915->drm, "couldn't fill AVI infoframe\n");
return; return;
} }
@@ -559,7 +568,7 @@ void lspcon_set_infoframes(struct intel_encoder *encoder,
ret = hdmi_infoframe_pack(&frame, buf, sizeof(buf)); ret = hdmi_infoframe_pack(&frame, buf, sizeof(buf));
if (ret < 0) { if (ret < 0) {
DRM_ERROR("Failed to pack AVI IF\n"); drm_err(&i915->drm, "Failed to pack AVI IF\n");
return; return;
} }
@@ -575,7 +584,7 @@ static bool _lspcon_read_avi_infoframe_enabled_mca(struct drm_dp_aux *aux)
ret = drm_dp_dpcd_read(aux, reg, &val, 1); ret = drm_dp_dpcd_read(aux, reg, &val, 1);
if (ret < 0) { if (ret < 0) {
DRM_ERROR("DPCD read failed, address 0x%x\n", reg); drm_err(aux->drm_dev, "DPCD read failed, address 0x%x\n", reg);
return false; return false;
} }
@@ -590,7 +599,7 @@ static bool _lspcon_read_avi_infoframe_enabled_parade(struct drm_dp_aux *aux)
ret = drm_dp_dpcd_read(aux, reg, &val, 1); ret = drm_dp_dpcd_read(aux, reg, &val, 1);
if (ret < 0) { if (ret < 0) {
DRM_ERROR("DPCD read failed, address 0x%x\n", reg); drm_err(aux->drm_dev, "DPCD read failed, address 0x%x\n", reg);
return false; return false;
} }
@@ -634,31 +643,32 @@ void lspcon_wait_pcon_mode(struct intel_lspcon *lspcon)
bool lspcon_init(struct intel_digital_port *dig_port) bool lspcon_init(struct intel_digital_port *dig_port)
{ {
struct intel_dp *dp = &dig_port->dp; struct intel_dp *intel_dp = &dig_port->dp;
struct intel_lspcon *lspcon = &dig_port->lspcon; struct intel_lspcon *lspcon = &dig_port->lspcon;
struct drm_connector *connector = &dp->attached_connector->base; struct drm_i915_private *i915 = dp_to_i915(intel_dp);
struct drm_connector *connector = &intel_dp->attached_connector->base;
lspcon->active = false; lspcon->active = false;
lspcon->mode = DRM_LSPCON_MODE_INVALID; lspcon->mode = DRM_LSPCON_MODE_INVALID;
if (!lspcon_probe(lspcon)) { if (!lspcon_probe(lspcon)) {
DRM_ERROR("Failed to probe lspcon\n"); drm_err(&i915->drm, "Failed to probe lspcon\n");
return false; return false;
} }
if (drm_dp_read_dpcd_caps(&dp->aux, dp->dpcd) != 0) { if (drm_dp_read_dpcd_caps(&intel_dp->aux, intel_dp->dpcd) != 0) {
DRM_ERROR("LSPCON DPCD read failed\n"); drm_err(&i915->drm, "LSPCON DPCD read failed\n");
return false; return false;
} }
if (!lspcon_detect_vendor(lspcon)) { if (!lspcon_detect_vendor(lspcon)) {
DRM_ERROR("LSPCON vendor detection failed\n"); drm_err(&i915->drm, "LSPCON vendor detection failed\n");
return false; return false;
} }
connector->ycbcr_420_allowed = true; connector->ycbcr_420_allowed = true;
lspcon->active = true; lspcon->active = true;
DRM_DEBUG_KMS("Success: LSPCON init\n"); drm_dbg_kms(&i915->drm, "Success: LSPCON init\n");
return true; return true;
} }
@@ -674,15 +684,15 @@ void lspcon_resume(struct intel_digital_port *dig_port)
{ {
struct intel_lspcon *lspcon = &dig_port->lspcon; struct intel_lspcon *lspcon = &dig_port->lspcon;
struct drm_device *dev = dig_port->base.base.dev; struct drm_device *dev = dig_port->base.base.dev;
struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_private *i915 = to_i915(dev);
enum drm_lspcon_mode expected_mode; enum drm_lspcon_mode expected_mode;
if (!intel_bios_is_lspcon_present(dev_priv, dig_port->base.port)) if (!intel_bios_is_lspcon_present(i915, dig_port->base.port))
return; return;
if (!lspcon->active) { if (!lspcon->active) {
if (!lspcon_init(dig_port)) { if (!lspcon_init(dig_port)) {
DRM_ERROR("LSPCON init failed on port %c\n", drm_err(&i915->drm, "LSPCON init failed on port %c\n",
port_name(dig_port->base.port)); port_name(dig_port->base.port));
return; return;
} }
@@ -699,7 +709,7 @@ void lspcon_resume(struct intel_digital_port *dig_port)
return; return;
if (lspcon_change_mode(lspcon, DRM_LSPCON_MODE_PCON)) if (lspcon_change_mode(lspcon, DRM_LSPCON_MODE_PCON))
DRM_ERROR("LSPCON resume failed\n"); drm_err(&i915->drm, "LSPCON resume failed\n");
else else
DRM_DEBUG_KMS("LSPCON resume success\n"); drm_dbg_kms(&i915->drm, "LSPCON resume success\n");
} }

View File

@@ -8,7 +8,7 @@
#include <linux/types.h> #include <linux/types.h>
#include "i915_reg.h" #include "i915_reg_defs.h"
enum pipe; enum pipe;
struct drm_i915_private; struct drm_i915_private;

View File

@@ -35,6 +35,7 @@
#include "intel_backlight.h" #include "intel_backlight.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_opregion.h" #include "intel_opregion.h"
#include "intel_pci_config.h"
#define OPREGION_HEADER_OFFSET 0 #define OPREGION_HEADER_OFFSET 0
#define OPREGION_ACPI_OFFSET 0x100 #define OPREGION_ACPI_OFFSET 0x100
@@ -195,6 +196,8 @@ struct opregion_asle_ext {
#define ASLE_IUER_WINDOWS_BTN (1 << 1) #define ASLE_IUER_WINDOWS_BTN (1 << 1)
#define ASLE_IUER_POWER_BTN (1 << 0) #define ASLE_IUER_POWER_BTN (1 << 0)
#define ASLE_PHED_EDID_VALID_MASK 0x3
/* Software System Control Interrupt (SWSCI) */ /* Software System Control Interrupt (SWSCI) */
#define SWSCI_SCIC_INDICATOR (1 << 0) #define SWSCI_SCIC_INDICATOR (1 << 0)
#define SWSCI_SCIC_MAIN_FUNCTION_SHIFT 1 #define SWSCI_SCIC_MAIN_FUNCTION_SHIFT 1
@@ -908,8 +911,10 @@ int intel_opregion_setup(struct drm_i915_private *dev_priv)
opregion->asle->ardy = ASLE_ARDY_NOT_READY; opregion->asle->ardy = ASLE_ARDY_NOT_READY;
} }
if (mboxes & MBOX_ASLE_EXT) if (mboxes & MBOX_ASLE_EXT) {
drm_dbg(&dev_priv->drm, "ASLE extension supported\n"); drm_dbg(&dev_priv->drm, "ASLE extension supported\n");
opregion->asle_ext = base + OPREGION_ASLE_EXT_OFFSET;
}
if (intel_load_vbt_firmware(dev_priv) == 0) if (intel_load_vbt_firmware(dev_priv) == 0)
goto out; goto out;
@@ -1036,6 +1041,54 @@ intel_opregion_get_panel_type(struct drm_i915_private *dev_priv)
return ret - 1; return ret - 1;
} }
/**
* intel_opregion_get_edid - Fetch EDID from ACPI OpRegion mailbox #5
* @intel_connector: eDP connector
*
* This reads the ACPI Opregion mailbox #5 to extract the EDID that is passed
* to it.
*
* Returns:
* The EDID in the OpRegion, or NULL if there is none or it's invalid.
*
*/
struct edid *intel_opregion_get_edid(struct intel_connector *intel_connector)
{
struct drm_connector *connector = &intel_connector->base;
struct drm_i915_private *i915 = to_i915(connector->dev);
struct intel_opregion *opregion = &i915->opregion;
const void *in_edid;
const struct edid *edid;
struct edid *new_edid;
int len;
if (!opregion->asle_ext)
return NULL;
in_edid = opregion->asle_ext->bddc;
/* Validity corresponds to number of 128-byte blocks */
len = (opregion->asle_ext->phed & ASLE_PHED_EDID_VALID_MASK) * 128;
if (!len || !memchr_inv(in_edid, 0, len))
return NULL;
edid = in_edid;
if (len < EDID_LENGTH * (1 + edid->extensions)) {
drm_dbg_kms(&i915->drm, "Invalid EDID in ACPI OpRegion (Mailbox #5): too short\n");
return NULL;
}
new_edid = drm_edid_duplicate(edid);
if (!new_edid)
return NULL;
if (!drm_edid_is_valid(new_edid)) {
kfree(new_edid);
drm_dbg_kms(&i915->drm, "Invalid EDID in ACPI OpRegion (Mailbox #5)\n");
return NULL;
}
return new_edid;
}
void intel_opregion_register(struct drm_i915_private *i915) void intel_opregion_register(struct drm_i915_private *i915)
{ {
struct intel_opregion *opregion = &i915->opregion; struct intel_opregion *opregion = &i915->opregion;
@@ -1129,6 +1182,7 @@ void intel_opregion_unregister(struct drm_i915_private *i915)
opregion->acpi = NULL; opregion->acpi = NULL;
opregion->swsci = NULL; opregion->swsci = NULL;
opregion->asle = NULL; opregion->asle = NULL;
opregion->asle_ext = NULL;
opregion->vbt = NULL; opregion->vbt = NULL;
opregion->lid_state = NULL; opregion->lid_state = NULL;
} }

View File

@@ -29,12 +29,14 @@
#include <linux/pci.h> #include <linux/pci.h>
struct drm_i915_private; struct drm_i915_private;
struct intel_connector;
struct intel_encoder; struct intel_encoder;
struct opregion_header; struct opregion_header;
struct opregion_acpi; struct opregion_acpi;
struct opregion_swsci; struct opregion_swsci;
struct opregion_asle; struct opregion_asle;
struct opregion_asle_ext;
struct intel_opregion { struct intel_opregion {
struct opregion_header *header; struct opregion_header *header;
@@ -43,6 +45,7 @@ struct intel_opregion {
u32 swsci_gbda_sub_functions; u32 swsci_gbda_sub_functions;
u32 swsci_sbcb_sub_functions; u32 swsci_sbcb_sub_functions;
struct opregion_asle *asle; struct opregion_asle *asle;
struct opregion_asle_ext *asle_ext;
void *rvda; void *rvda;
void *vbt_firmware; void *vbt_firmware;
const void *vbt; const void *vbt;
@@ -71,6 +74,7 @@ int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder,
int intel_opregion_notify_adapter(struct drm_i915_private *dev_priv, int intel_opregion_notify_adapter(struct drm_i915_private *dev_priv,
pci_power_t state); pci_power_t state);
int intel_opregion_get_panel_type(struct drm_i915_private *dev_priv); int intel_opregion_get_panel_type(struct drm_i915_private *dev_priv);
struct edid *intel_opregion_get_edid(struct intel_connector *connector);
#else /* CONFIG_ACPI*/ #else /* CONFIG_ACPI*/
@@ -117,6 +121,12 @@ static inline int intel_opregion_get_panel_type(struct drm_i915_private *dev)
return -ENODEV; return -ENODEV;
} }
static inline struct edid *
intel_opregion_get_edid(struct intel_connector *connector)
{
return NULL;
}
#endif /* CONFIG_ACPI */ #endif /* CONFIG_ACPI */
#endif #endif

View File

@@ -38,6 +38,7 @@
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_frontbuffer.h" #include "intel_frontbuffer.h"
#include "intel_overlay.h" #include "intel_overlay.h"
#include "intel_pci_config.h"
/* Limits for overlay size. According to intel doc, the real limits are: /* Limits for overlay size. According to intel doc, the real limits are:
* Y width: 4095, UV width (planar): 2047, Y height: 2047, * Y width: 4095, UV width (planar): 2047, Y height: 2047,
@@ -959,6 +960,9 @@ static int check_overlay_dst(struct intel_overlay *overlay,
const struct intel_crtc_state *pipe_config = const struct intel_crtc_state *pipe_config =
overlay->crtc->config; overlay->crtc->config;
if (rec->dst_height == 0 || rec->dst_width == 0)
return -EINVAL;
if (rec->dst_x < pipe_config->pipe_src_w && if (rec->dst_x < pipe_config->pipe_src_w &&
rec->dst_x + rec->dst_width <= pipe_config->pipe_src_w && rec->dst_x + rec->dst_width <= pipe_config->pipe_src_w &&
rec->dst_y < pipe_config->pipe_src_h && rec->dst_y < pipe_config->pipe_src_h &&

View File

@@ -88,6 +88,50 @@ static void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv,
pipe_name(pipe)); pipe_name(pipe));
} }
static void intel_pch_transcoder_set_m1_n1(struct intel_crtc *crtc,
const struct intel_link_m_n *m_n)
{
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum pipe pipe = crtc->pipe;
intel_set_m_n(dev_priv, m_n,
PCH_TRANS_DATA_M1(pipe), PCH_TRANS_DATA_N1(pipe),
PCH_TRANS_LINK_M1(pipe), PCH_TRANS_LINK_N1(pipe));
}
static void intel_pch_transcoder_set_m2_n2(struct intel_crtc *crtc,
const struct intel_link_m_n *m_n)
{
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum pipe pipe = crtc->pipe;
intel_set_m_n(dev_priv, m_n,
PCH_TRANS_DATA_M2(pipe), PCH_TRANS_DATA_N2(pipe),
PCH_TRANS_LINK_M2(pipe), PCH_TRANS_LINK_N2(pipe));
}
void intel_pch_transcoder_get_m1_n1(struct intel_crtc *crtc,
struct intel_link_m_n *m_n)
{
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum pipe pipe = crtc->pipe;
intel_get_m_n(dev_priv, m_n,
PCH_TRANS_DATA_M1(pipe), PCH_TRANS_DATA_N1(pipe),
PCH_TRANS_LINK_M1(pipe), PCH_TRANS_LINK_N1(pipe));
}
void intel_pch_transcoder_get_m2_n2(struct intel_crtc *crtc,
struct intel_link_m_n *m_n)
{
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum pipe pipe = crtc->pipe;
intel_get_m_n(dev_priv, m_n,
PCH_TRANS_DATA_M2(pipe), PCH_TRANS_DATA_N2(pipe),
PCH_TRANS_LINK_M2(pipe), PCH_TRANS_LINK_N2(pipe));
}
static void ilk_pch_transcoder_set_timings(const struct intel_crtc_state *crtc_state, static void ilk_pch_transcoder_set_timings(const struct intel_crtc_state *crtc_state,
enum pipe pch_transcoder) enum pipe pch_transcoder)
{ {
@@ -157,20 +201,20 @@ static void ilk_enable_pch_transcoder(const struct intel_crtc_state *crtc_state)
*/ */
val &= ~PIPECONF_BPC_MASK; val &= ~PIPECONF_BPC_MASK;
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
val |= PIPECONF_8BPC; val |= PIPECONF_BPC_8;
else else
val |= pipeconf_val & PIPECONF_BPC_MASK; val |= pipeconf_val & PIPECONF_BPC_MASK;
} }
val &= ~TRANS_INTERLACE_MASK; val &= ~TRANS_INTERLACE_MASK;
if ((pipeconf_val & PIPECONF_INTERLACE_MASK) == PIPECONF_INTERLACED_ILK) { if ((pipeconf_val & PIPECONF_INTERLACE_MASK_ILK) == PIPECONF_INTERLACE_IF_ID_ILK) {
if (HAS_PCH_IBX(dev_priv) && if (HAS_PCH_IBX(dev_priv) &&
intel_crtc_has_type(crtc_state, INTEL_OUTPUT_SDVO)) intel_crtc_has_type(crtc_state, INTEL_OUTPUT_SDVO))
val |= TRANS_LEGACY_INTERLACED_ILK; val |= TRANS_INTERLACE_LEGACY_VSYNC_IBX;
else else
val |= TRANS_INTERLACED; val |= TRANS_INTERLACE_INTERLACED;
} else { } else {
val |= TRANS_PROGRESSIVE; val |= TRANS_INTERLACE_PROGRESSIVE;
} }
intel_de_write(dev_priv, reg, val | TRANS_ENABLE); intel_de_write(dev_priv, reg, val | TRANS_ENABLE);
@@ -211,6 +255,20 @@ static void ilk_disable_pch_transcoder(struct intel_crtc *crtc)
} }
} }
void ilk_pch_pre_enable(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
const struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
/*
* 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(crtc_state);
}
/* /*
* Enable PCH resources required for PCH ports: * Enable PCH resources required for PCH ports:
* - PCH PLLs * - PCH PLLs
@@ -264,6 +322,10 @@ void ilk_pch_enable(struct intel_atomic_state *state,
/* set transcoder timing, panel must allow it */ /* set transcoder timing, panel must allow it */
assert_pps_unlocked(dev_priv, pipe); assert_pps_unlocked(dev_priv, pipe);
if (intel_crtc_has_dp_encoder(crtc_state)) {
intel_pch_transcoder_set_m1_n1(crtc, &crtc_state->dp_m_n);
intel_pch_transcoder_set_m2_n2(crtc, &crtc_state->dp_m2_n2);
}
ilk_pch_transcoder_set_timings(crtc_state, pipe); ilk_pch_transcoder_set_timings(crtc_state, pipe);
intel_fdi_normal_train(crtc); intel_fdi_normal_train(crtc);
@@ -279,7 +341,8 @@ void ilk_pch_enable(struct intel_atomic_state *state,
temp = intel_de_read(dev_priv, reg); temp = intel_de_read(dev_priv, reg);
temp &= ~(TRANS_DP_PORT_SEL_MASK | temp &= ~(TRANS_DP_PORT_SEL_MASK |
TRANS_DP_SYNC_MASK | TRANS_DP_VSYNC_ACTIVE_HIGH |
TRANS_DP_HSYNC_ACTIVE_HIGH |
TRANS_DP_BPC_MASK); TRANS_DP_BPC_MASK);
temp |= TRANS_DP_OUTPUT_ENABLE; temp |= TRANS_DP_OUTPUT_ENABLE;
temp |= bpc << 9; /* same format but at 11:9 */ temp |= bpc << 9; /* same format but at 11:9 */
@@ -371,7 +434,8 @@ void ilk_pch_get_config(struct intel_crtc_state *crtc_state)
crtc_state->fdi_lanes = ((FDI_DP_PORT_WIDTH_MASK & tmp) >> crtc_state->fdi_lanes = ((FDI_DP_PORT_WIDTH_MASK & tmp) >>
FDI_DP_PORT_WIDTH_SHIFT) + 1; FDI_DP_PORT_WIDTH_SHIFT) + 1;
ilk_get_fdi_m_n_config(crtc, crtc_state); intel_cpu_transcoder_get_m1_n1(crtc, crtc_state->cpu_transcoder,
&crtc_state->fdi_m_n);
if (HAS_PCH_IBX(dev_priv)) { if (HAS_PCH_IBX(dev_priv)) {
/* /*
@@ -422,11 +486,10 @@ static void lpt_enable_pch_transcoder(struct drm_i915_private *dev_priv,
val = TRANS_ENABLE; val = TRANS_ENABLE;
pipeconf_val = intel_de_read(dev_priv, PIPECONF(cpu_transcoder)); pipeconf_val = intel_de_read(dev_priv, PIPECONF(cpu_transcoder));
if ((pipeconf_val & PIPECONF_INTERLACE_MASK_HSW) == if ((pipeconf_val & PIPECONF_INTERLACE_MASK_HSW) == PIPECONF_INTERLACE_IF_ID_ILK)
PIPECONF_INTERLACED_ILK) val |= TRANS_INTERLACE_INTERLACED;
val |= TRANS_INTERLACED;
else else
val |= TRANS_PROGRESSIVE; val |= TRANS_INTERLACE_PROGRESSIVE;
intel_de_write(dev_priv, LPT_TRANSCONF, val); intel_de_write(dev_priv, LPT_TRANSCONF, val);
if (intel_de_wait_for_set(dev_priv, LPT_TRANSCONF, if (intel_de_wait_for_set(dev_priv, LPT_TRANSCONF,
@@ -495,7 +558,8 @@ void lpt_pch_get_config(struct intel_crtc_state *crtc_state)
crtc_state->fdi_lanes = ((FDI_DP_PORT_WIDTH_MASK & tmp) >> crtc_state->fdi_lanes = ((FDI_DP_PORT_WIDTH_MASK & tmp) >>
FDI_DP_PORT_WIDTH_SHIFT) + 1; FDI_DP_PORT_WIDTH_SHIFT) + 1;
ilk_get_fdi_m_n_config(crtc, crtc_state); intel_cpu_transcoder_get_m1_n1(crtc, crtc_state->cpu_transcoder,
&crtc_state->fdi_m_n);
crtc_state->hw.adjusted_mode.crtc_clock = lpt_get_iclkip(dev_priv); crtc_state->hw.adjusted_mode.crtc_clock = lpt_get_iclkip(dev_priv);
} }

View File

@@ -9,7 +9,10 @@
struct intel_atomic_state; struct intel_atomic_state;
struct intel_crtc; struct intel_crtc;
struct intel_crtc_state; struct intel_crtc_state;
struct intel_link_m_n;
void ilk_pch_pre_enable(struct intel_atomic_state *state,
struct intel_crtc *crtc);
void ilk_pch_enable(struct intel_atomic_state *state, void ilk_pch_enable(struct intel_atomic_state *state,
struct intel_crtc *crtc); struct intel_crtc *crtc);
void ilk_pch_disable(struct intel_atomic_state *state, void ilk_pch_disable(struct intel_atomic_state *state,
@@ -24,4 +27,9 @@ void lpt_pch_disable(struct intel_atomic_state *state,
struct intel_crtc *crtc); struct intel_crtc *crtc);
void lpt_pch_get_config(struct intel_crtc_state *crtc_state); void lpt_pch_get_config(struct intel_crtc_state *crtc_state);
void intel_pch_transcoder_get_m1_n1(struct intel_crtc *crtc,
struct intel_link_m_n *m_n);
void intel_pch_transcoder_get_m2_n2(struct intel_crtc *crtc,
struct intel_link_m_n *m_n);
#endif #endif

View File

@@ -1131,9 +1131,12 @@ intel_pps_readout_hw_state(struct intel_dp *intel_dp, struct edp_power_seq *seq)
} }
static void static void
intel_pps_dump_state(const char *state_name, const struct edp_power_seq *seq) intel_pps_dump_state(struct intel_dp *intel_dp, const char *state_name,
const struct edp_power_seq *seq)
{ {
DRM_DEBUG_KMS("%s t1_t3 %d t8 %d t9 %d t10 %d t11_t12 %d\n", struct drm_i915_private *i915 = dp_to_i915(intel_dp);
drm_dbg_kms(&i915->drm, "%s t1_t3 %d t8 %d t9 %d t10 %d t11_t12 %d\n",
state_name, state_name,
seq->t1_t3, seq->t8, seq->t9, seq->t10, seq->t11_t12); seq->t1_t3, seq->t8, seq->t9, seq->t10, seq->t11_t12);
} }
@@ -1141,6 +1144,7 @@ intel_pps_dump_state(const char *state_name, const struct edp_power_seq *seq)
static void static void
intel_pps_verify_state(struct intel_dp *intel_dp) intel_pps_verify_state(struct intel_dp *intel_dp)
{ {
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
struct edp_power_seq hw; struct edp_power_seq hw;
struct edp_power_seq *sw = &intel_dp->pps.pps_delays; struct edp_power_seq *sw = &intel_dp->pps.pps_delays;
@@ -1148,9 +1152,9 @@ intel_pps_verify_state(struct intel_dp *intel_dp)
if (hw.t1_t3 != sw->t1_t3 || hw.t8 != sw->t8 || hw.t9 != sw->t9 || if (hw.t1_t3 != sw->t1_t3 || hw.t8 != sw->t8 || hw.t9 != sw->t9 ||
hw.t10 != sw->t10 || hw.t11_t12 != sw->t11_t12) { hw.t10 != sw->t10 || hw.t11_t12 != sw->t11_t12) {
DRM_ERROR("PPS state mismatch\n"); drm_err(&i915->drm, "PPS state mismatch\n");
intel_pps_dump_state("sw", sw); intel_pps_dump_state(intel_dp, "sw", sw);
intel_pps_dump_state("hw", &hw); intel_pps_dump_state(intel_dp, "hw", &hw);
} }
} }
@@ -1168,7 +1172,7 @@ static void pps_init_delays(struct intel_dp *intel_dp)
intel_pps_readout_hw_state(intel_dp, &cur); intel_pps_readout_hw_state(intel_dp, &cur);
intel_pps_dump_state("cur", &cur); intel_pps_dump_state(intel_dp, "cur", &cur);
vbt = dev_priv->vbt.edp.pps; vbt = dev_priv->vbt.edp.pps;
/* On Toshiba Satellite P50-C-18C system the VBT T12 delay /* On Toshiba Satellite P50-C-18C system the VBT T12 delay
@@ -1200,7 +1204,7 @@ static void pps_init_delays(struct intel_dp *intel_dp)
* too. */ * too. */
spec.t11_t12 = (510 + 100) * 10; spec.t11_t12 = (510 + 100) * 10;
intel_pps_dump_state("vbt", &vbt); intel_pps_dump_state(intel_dp, "vbt", &vbt);
/* Use the max of the register settings and vbt. If both are /* Use the max of the register settings and vbt. If both are
* unset, fall back to the spec limits. */ * unset, fall back to the spec limits. */

View File

@@ -8,7 +8,7 @@
#include <linux/types.h> #include <linux/types.h>
#include "i915_reg.h" #include "i915_reg_defs.h"
struct drm_i915_private; struct drm_i915_private;
enum pipe; enum pipe;

View File

@@ -10,6 +10,7 @@
#include "intel_de.h" #include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_snps_phy.h" #include "intel_snps_phy.h"
#include "intel_snps_phy_regs.h"
/** /**
* DOC: Synopsis PHY support * DOC: Synopsis PHY support
@@ -23,17 +24,17 @@
* since it is not handled by the shared DPLL framework as on other platforms. * since it is not handled by the shared DPLL framework as on other platforms.
*/ */
void intel_snps_phy_wait_for_calibration(struct drm_i915_private *dev_priv) void intel_snps_phy_wait_for_calibration(struct drm_i915_private *i915)
{ {
enum phy phy; enum phy phy;
for_each_phy_masked(phy, ~0) { for_each_phy_masked(phy, ~0) {
if (!intel_phy_is_snps(dev_priv, phy)) if (!intel_phy_is_snps(i915, phy))
continue; continue;
if (intel_de_wait_for_clear(dev_priv, ICL_PHY_MISC(phy), if (intel_de_wait_for_clear(i915, ICL_PHY_MISC(phy),
DG2_PHY_DP_TX_ACK_MASK, 25)) DG2_PHY_DP_TX_ACK_MASK, 25))
DRM_ERROR("SNPS PHY %c failed to calibrate after 25ms.\n", drm_err(&i915->drm, "SNPS PHY %c failed to calibrate after 25ms.\n",
phy); phy);
} }
} }
@@ -775,6 +776,7 @@ intel_mpllb_tables_get(struct intel_crtc_state *crtc_state,
int intel_mpllb_calc_state(struct intel_crtc_state *crtc_state, int intel_mpllb_calc_state(struct intel_crtc_state *crtc_state,
struct intel_encoder *encoder) struct intel_encoder *encoder)
{ {
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
const struct intel_mpllb_state * const *tables; const struct intel_mpllb_state * const *tables;
int i; int i;
@@ -786,7 +788,7 @@ int intel_mpllb_calc_state(struct intel_crtc_state *crtc_state,
* until we have a proper algorithm under a valid * until we have a proper algorithm under a valid
* license. * license.
*/ */
DRM_DEBUG_KMS("Can't support HDMI link rate %d\n", drm_dbg_kms(&i915->drm, "Can't support HDMI link rate %d\n",
crtc_state->port_clock); crtc_state->port_clock);
return -EINVAL; return -EINVAL;
} }
@@ -854,7 +856,7 @@ void intel_mpllb_enable(struct intel_encoder *encoder,
* dp_mpllb_state interface signal. * dp_mpllb_state interface signal.
*/ */
if (intel_de_wait_for_set(dev_priv, enable_reg, PLL_LOCK, 5)) if (intel_de_wait_for_set(dev_priv, enable_reg, PLL_LOCK, 5))
DRM_ERROR("Port %c PLL not locked\n", phy_name(phy)); drm_dbg_kms(&dev_priv->drm, "Port %c PLL not locked\n", phy_name(phy));
/* /*
* 11. If the frequency will result in a change to the voltage * 11. If the frequency will result in a change to the voltage
@@ -867,8 +869,8 @@ void intel_mpllb_enable(struct intel_encoder *encoder,
void intel_mpllb_disable(struct intel_encoder *encoder) void intel_mpllb_disable(struct intel_encoder *encoder)
{ {
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct drm_i915_private *i915 = to_i915(encoder->base.dev);
enum phy phy = intel_port_to_phy(dev_priv, encoder->port); enum phy phy = intel_port_to_phy(i915, encoder->port);
i915_reg_t enable_reg = (phy <= PHY_D ? i915_reg_t enable_reg = (phy <= PHY_D ?
DG2_PLL_ENABLE(phy) : MG_PLL_ENABLE(0)); DG2_PLL_ENABLE(phy) : MG_PLL_ENABLE(0));
@@ -881,21 +883,21 @@ void intel_mpllb_disable(struct intel_encoder *encoder)
*/ */
/* 2. Software programs DPLL_ENABLE [PLL Enable] to "0" */ /* 2. Software programs DPLL_ENABLE [PLL Enable] to "0" */
intel_uncore_rmw(&dev_priv->uncore, enable_reg, PLL_ENABLE, 0); intel_uncore_rmw(&i915->uncore, enable_reg, PLL_ENABLE, 0);
/* /*
* 4. Software programs SNPS_PHY_MPLLB_DIV dp_mpllb_force_en to "0". * 4. Software programs SNPS_PHY_MPLLB_DIV dp_mpllb_force_en to "0".
* This will allow the PLL to stop running. * This will allow the PLL to stop running.
*/ */
intel_uncore_rmw(&dev_priv->uncore, SNPS_PHY_MPLLB_DIV(phy), intel_uncore_rmw(&i915->uncore, SNPS_PHY_MPLLB_DIV(phy),
SNPS_PHY_MPLLB_FORCE_EN, 0); SNPS_PHY_MPLLB_FORCE_EN, 0);
/* /*
* 5. Software polls DPLL_ENABLE [PLL Lock] for PHY acknowledgment * 5. Software polls DPLL_ENABLE [PLL Lock] for PHY acknowledgment
* (dp_txX_ack) that the new transmitter setting request is completed. * (dp_txX_ack) that the new transmitter setting request is completed.
*/ */
if (intel_de_wait_for_clear(dev_priv, enable_reg, PLL_LOCK, 5)) if (intel_de_wait_for_clear(i915, enable_reg, PLL_LOCK, 5))
DRM_ERROR("Port %c PLL not locked\n", phy_name(phy)); drm_err(&i915->drm, "Port %c PLL not locked\n", phy_name(phy));
/* /*
* 6. If the frequency will result in a change to the voltage * 6. If the frequency will result in a change to the voltage

View File

@@ -0,0 +1,75 @@
/* SPDX-License-Identifier: MIT */
/*
* Copyright © 2022 Intel Corporation
*/
#ifndef __INTEL_SNPS_PHY_REGS__
#define __INTEL_SNPS_PHY_REGS__
#include "i915_reg_defs.h"
#define _SNPS_PHY_A_BASE 0x168000
#define _SNPS_PHY_B_BASE 0x169000
#define _SNPS_PHY(phy) _PHY(phy, \
_SNPS_PHY_A_BASE, \
_SNPS_PHY_B_BASE)
#define _SNPS2(phy, reg) (_SNPS_PHY(phy) - \
_SNPS_PHY_A_BASE + (reg))
#define _MMIO_SNPS(phy, reg) _MMIO(_SNPS2(phy, reg))
#define _MMIO_SNPS_LN(ln, phy, reg) _MMIO(_SNPS2(phy, \
(reg) + (ln) * 0x10))
#define SNPS_PHY_MPLLB_CP(phy) _MMIO_SNPS(phy, 0x168000)
#define SNPS_PHY_MPLLB_CP_INT REG_GENMASK(31, 25)
#define SNPS_PHY_MPLLB_CP_INT_GS REG_GENMASK(23, 17)
#define SNPS_PHY_MPLLB_CP_PROP REG_GENMASK(15, 9)
#define SNPS_PHY_MPLLB_CP_PROP_GS REG_GENMASK(7, 1)
#define SNPS_PHY_MPLLB_DIV(phy) _MMIO_SNPS(phy, 0x168004)
#define SNPS_PHY_MPLLB_FORCE_EN REG_BIT(31)
#define SNPS_PHY_MPLLB_DIV_CLK_EN REG_BIT(30)
#define SNPS_PHY_MPLLB_DIV5_CLK_EN REG_BIT(29)
#define SNPS_PHY_MPLLB_V2I REG_GENMASK(27, 26)
#define SNPS_PHY_MPLLB_FREQ_VCO REG_GENMASK(25, 24)
#define SNPS_PHY_MPLLB_DIV_MULTIPLIER REG_GENMASK(23, 16)
#define SNPS_PHY_MPLLB_PMIX_EN REG_BIT(10)
#define SNPS_PHY_MPLLB_DP2_MODE REG_BIT(9)
#define SNPS_PHY_MPLLB_WORD_DIV2_EN REG_BIT(8)
#define SNPS_PHY_MPLLB_TX_CLK_DIV REG_GENMASK(7, 5)
#define SNPS_PHY_MPLLB_SHIM_DIV32_CLK_SEL REG_BIT(0)
#define SNPS_PHY_MPLLB_FRACN1(phy) _MMIO_SNPS(phy, 0x168008)
#define SNPS_PHY_MPLLB_FRACN_EN REG_BIT(31)
#define SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN REG_BIT(30)
#define SNPS_PHY_MPLLB_FRACN_DEN REG_GENMASK(15, 0)
#define SNPS_PHY_MPLLB_FRACN2(phy) _MMIO_SNPS(phy, 0x16800C)
#define SNPS_PHY_MPLLB_FRACN_REM REG_GENMASK(31, 16)
#define SNPS_PHY_MPLLB_FRACN_QUOT REG_GENMASK(15, 0)
#define SNPS_PHY_MPLLB_SSCEN(phy) _MMIO_SNPS(phy, 0x168014)
#define SNPS_PHY_MPLLB_SSC_EN REG_BIT(31)
#define SNPS_PHY_MPLLB_SSC_UP_SPREAD REG_BIT(30)
#define SNPS_PHY_MPLLB_SSC_PEAK REG_GENMASK(29, 10)
#define SNPS_PHY_MPLLB_SSCSTEP(phy) _MMIO_SNPS(phy, 0x168018)
#define SNPS_PHY_MPLLB_SSC_STEPSIZE REG_GENMASK(31, 11)
#define SNPS_PHY_MPLLB_DIV2(phy) _MMIO_SNPS(phy, 0x16801C)
#define SNPS_PHY_MPLLB_HDMI_PIXEL_CLK_DIV REG_GENMASK(19, 18)
#define SNPS_PHY_MPLLB_HDMI_DIV REG_GENMASK(17, 15)
#define SNPS_PHY_MPLLB_REF_CLK_DIV REG_GENMASK(14, 12)
#define SNPS_PHY_MPLLB_MULTIPLIER REG_GENMASK(11, 0)
#define SNPS_PHY_REF_CONTROL(phy) _MMIO_SNPS(phy, 0x168188)
#define SNPS_PHY_REF_CONTROL_REF_RANGE REG_GENMASK(31, 27)
#define SNPS_PHY_TX_REQ(phy) _MMIO_SNPS(phy, 0x168200)
#define SNPS_PHY_TX_REQ_LN_DIS_PWR_STATE_PSR REG_GENMASK(31, 30)
#define SNPS_PHY_TX_EQ(ln, phy) _MMIO_SNPS_LN(ln, phy, 0x168300)
#define SNPS_PHY_TX_EQ_MAIN REG_GENMASK(23, 18)
#define SNPS_PHY_TX_EQ_POST REG_GENMASK(15, 10)
#define SNPS_PHY_TX_EQ_PRE REG_GENMASK(7, 2)
#endif /* __INTEL_SNPS_PHY_REGS__ */

View File

@@ -53,6 +53,7 @@
int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state) int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state)
{ {
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
const struct drm_framebuffer *fb = plane_state->hw.fb; const struct drm_framebuffer *fb = plane_state->hw.fb;
struct drm_rect *src = &plane_state->uapi.src; struct drm_rect *src = &plane_state->uapi.src;
u32 src_x, src_y, src_w, src_h, hsub, vsub; u32 src_x, src_y, src_w, src_h, hsub, vsub;
@@ -94,13 +95,13 @@ int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state)
hsub = vsub = max(hsub, vsub); hsub = vsub = max(hsub, vsub);
if (src_x % hsub || src_w % hsub) { if (src_x % hsub || src_w % hsub) {
DRM_DEBUG_KMS("src x/w (%u, %u) must be a multiple of %u (rotated: %s)\n", drm_dbg_kms(&i915->drm, "src x/w (%u, %u) must be a multiple of %u (rotated: %s)\n",
src_x, src_w, hsub, yesno(rotated)); src_x, src_w, hsub, yesno(rotated));
return -EINVAL; return -EINVAL;
} }
if (src_y % vsub || src_h % vsub) { if (src_y % vsub || src_h % vsub) {
DRM_DEBUG_KMS("src y/h (%u, %u) must be a multiple of %u (rotated: %s)\n", drm_dbg_kms(&i915->drm, "src y/h (%u, %u) must be a multiple of %u (rotated: %s)\n",
src_y, src_h, vsub, yesno(rotated)); src_y, src_h, vsub, yesno(rotated));
return -EINVAL; return -EINVAL;
} }
@@ -313,7 +314,7 @@ static u32 vlv_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
u32 sprctl = 0; u32 sprctl = 0;
if (crtc_state->gamma_enable) if (crtc_state->gamma_enable)
sprctl |= SP_GAMMA_ENABLE; sprctl |= SP_PIPE_GAMMA_ENABLE;
return sprctl; return sprctl;
} }
@@ -436,9 +437,9 @@ vlv_sprite_update_noarm(struct intel_plane *plane,
intel_de_write_fw(dev_priv, SPSTRIDE(pipe, plane_id), intel_de_write_fw(dev_priv, SPSTRIDE(pipe, plane_id),
plane_state->view.color_plane[0].mapping_stride); plane_state->view.color_plane[0].mapping_stride);
intel_de_write_fw(dev_priv, SPPOS(pipe, plane_id), intel_de_write_fw(dev_priv, SPPOS(pipe, plane_id),
(crtc_y << 16) | crtc_x); SP_POS_Y(crtc_y) | SP_POS_X(crtc_x));
intel_de_write_fw(dev_priv, SPSIZE(pipe, plane_id), intel_de_write_fw(dev_priv, SPSIZE(pipe, plane_id),
((crtc_h - 1) << 16) | (crtc_w - 1)); SP_HEIGHT(crtc_h - 1) | SP_WIDTH(crtc_w - 1));
spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
} }
@@ -479,7 +480,8 @@ vlv_sprite_update_arm(struct intel_plane *plane,
intel_de_write_fw(dev_priv, SPCONSTALPHA(pipe, plane_id), 0); intel_de_write_fw(dev_priv, SPCONSTALPHA(pipe, plane_id), 0);
intel_de_write_fw(dev_priv, SPLINOFF(pipe, plane_id), linear_offset); intel_de_write_fw(dev_priv, SPLINOFF(pipe, plane_id), linear_offset);
intel_de_write_fw(dev_priv, SPTILEOFF(pipe, plane_id), (y << 16) | x); intel_de_write_fw(dev_priv, SPTILEOFF(pipe, plane_id),
SP_OFFSET_Y(y) | SP_OFFSET_X(x));
/* /*
* The control register self-arms if the plane was previously * The control register self-arms if the plane was previously
@@ -700,7 +702,7 @@ static u32 ivb_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
u32 sprctl = 0; u32 sprctl = 0;
if (crtc_state->gamma_enable) if (crtc_state->gamma_enable)
sprctl |= SPRITE_GAMMA_ENABLE; sprctl |= SPRITE_PIPE_GAMMA_ENABLE;
if (crtc_state->csc_enable) if (crtc_state->csc_enable)
sprctl |= SPRITE_PIPE_CSC_ENABLE; sprctl |= SPRITE_PIPE_CSC_ENABLE;
@@ -770,7 +772,7 @@ static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state,
} }
if (!ivb_need_sprite_gamma(plane_state)) if (!ivb_need_sprite_gamma(plane_state))
sprctl |= SPRITE_INT_GAMMA_DISABLE; sprctl |= SPRITE_PLANE_GAMMA_DISABLE;
if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709) if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709)
sprctl |= SPRITE_YUV_TO_RGB_CSC_FORMAT_BT709; sprctl |= SPRITE_YUV_TO_RGB_CSC_FORMAT_BT709;
@@ -863,14 +865,18 @@ ivb_sprite_update_noarm(struct intel_plane *plane,
unsigned long irqflags; unsigned long irqflags;
if (crtc_w != src_w || crtc_h != src_h) if (crtc_w != src_w || crtc_h != src_h)
sprscale = SPRITE_SCALE_ENABLE | ((src_w - 1) << 16) | (src_h - 1); sprscale = SPRITE_SCALE_ENABLE |
SPRITE_SRC_WIDTH(src_w - 1) |
SPRITE_SRC_HEIGHT(src_h - 1);
spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
intel_de_write_fw(dev_priv, SPRSTRIDE(pipe), intel_de_write_fw(dev_priv, SPRSTRIDE(pipe),
plane_state->view.color_plane[0].mapping_stride); plane_state->view.color_plane[0].mapping_stride);
intel_de_write_fw(dev_priv, SPRPOS(pipe), (crtc_y << 16) | crtc_x); intel_de_write_fw(dev_priv, SPRPOS(pipe),
intel_de_write_fw(dev_priv, SPRSIZE(pipe), ((crtc_h - 1) << 16) | (crtc_w - 1)); SPRITE_POS_Y(crtc_y) | SPRITE_POS_X(crtc_x));
intel_de_write_fw(dev_priv, SPRSIZE(pipe),
SPRITE_HEIGHT(crtc_h - 1) | SPRITE_WIDTH(crtc_w - 1));
if (IS_IVYBRIDGE(dev_priv)) if (IS_IVYBRIDGE(dev_priv))
intel_de_write_fw(dev_priv, SPRSCALE(pipe), sprscale); intel_de_write_fw(dev_priv, SPRSCALE(pipe), sprscale);
@@ -907,10 +913,12 @@ ivb_sprite_update_arm(struct intel_plane *plane,
/* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
* register */ * register */
if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
intel_de_write_fw(dev_priv, SPROFFSET(pipe), (y << 16) | x); intel_de_write_fw(dev_priv, SPROFFSET(pipe),
SPRITE_OFFSET_Y(y) | SPRITE_OFFSET_X(x));
} else { } else {
intel_de_write_fw(dev_priv, SPRLINOFF(pipe), linear_offset); intel_de_write_fw(dev_priv, SPRLINOFF(pipe), linear_offset);
intel_de_write_fw(dev_priv, SPRTILEOFF(pipe), (y << 16) | x); intel_de_write_fw(dev_priv, SPRTILEOFF(pipe),
SPRITE_OFFSET_Y(y) | SPRITE_OFFSET_X(x));
} }
/* /*
@@ -1047,7 +1055,7 @@ static u32 g4x_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
u32 dvscntr = 0; u32 dvscntr = 0;
if (crtc_state->gamma_enable) if (crtc_state->gamma_enable)
dvscntr |= DVS_GAMMA_ENABLE; dvscntr |= DVS_PIPE_GAMMA_ENABLE;
if (crtc_state->csc_enable) if (crtc_state->csc_enable)
dvscntr |= DVS_PIPE_CSC_ENABLE; dvscntr |= DVS_PIPE_CSC_ENABLE;
@@ -1199,14 +1207,18 @@ g4x_sprite_update_noarm(struct intel_plane *plane,
unsigned long irqflags; unsigned long irqflags;
if (crtc_w != src_w || crtc_h != src_h) if (crtc_w != src_w || crtc_h != src_h)
dvsscale = DVS_SCALE_ENABLE | ((src_w - 1) << 16) | (src_h - 1); dvsscale = DVS_SCALE_ENABLE |
DVS_SRC_WIDTH(src_w - 1) |
DVS_SRC_HEIGHT(src_h - 1);
spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
intel_de_write_fw(dev_priv, DVSSTRIDE(pipe), intel_de_write_fw(dev_priv, DVSSTRIDE(pipe),
plane_state->view.color_plane[0].mapping_stride); plane_state->view.color_plane[0].mapping_stride);
intel_de_write_fw(dev_priv, DVSPOS(pipe), (crtc_y << 16) | crtc_x); intel_de_write_fw(dev_priv, DVSPOS(pipe),
intel_de_write_fw(dev_priv, DVSSIZE(pipe), ((crtc_h - 1) << 16) | (crtc_w - 1)); DVS_POS_Y(crtc_y) | DVS_POS_X(crtc_x));
intel_de_write_fw(dev_priv, DVSSIZE(pipe),
DVS_HEIGHT(crtc_h - 1) | DVS_WIDTH(crtc_w - 1));
intel_de_write_fw(dev_priv, DVSSCALE(pipe), dvsscale); intel_de_write_fw(dev_priv, DVSSCALE(pipe), dvsscale);
spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
@@ -1321,6 +1333,7 @@ static int
g4x_sprite_check_scaling(struct intel_crtc_state *crtc_state, g4x_sprite_check_scaling(struct intel_crtc_state *crtc_state,
struct intel_plane_state *plane_state) struct intel_plane_state *plane_state)
{ {
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
const struct drm_framebuffer *fb = plane_state->hw.fb; const struct drm_framebuffer *fb = plane_state->hw.fb;
const struct drm_rect *src = &plane_state->uapi.src; const struct drm_rect *src = &plane_state->uapi.src;
const struct drm_rect *dst = &plane_state->uapi.dst; const struct drm_rect *dst = &plane_state->uapi.dst;
@@ -1346,7 +1359,7 @@ g4x_sprite_check_scaling(struct intel_crtc_state *crtc_state,
if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
if (src_h & 1) { if (src_h & 1) {
DRM_DEBUG_KMS("Source height must be even with interlaced modes\n"); drm_dbg_kms(&i915->drm, "Source height must be even with interlaced modes\n");
return -EINVAL; return -EINVAL;
} }
min_height = 6; min_height = 6;
@@ -1358,19 +1371,19 @@ g4x_sprite_check_scaling(struct intel_crtc_state *crtc_state,
if (src_w < min_width || src_h < min_height || if (src_w < min_width || src_h < min_height ||
src_w > 2048 || src_h > 2048) { src_w > 2048 || src_h > 2048) {
DRM_DEBUG_KMS("Source dimensions (%dx%d) exceed hardware limits (%dx%d - %dx%d)\n", drm_dbg_kms(&i915->drm, "Source dimensions (%dx%d) exceed hardware limits (%dx%d - %dx%d)\n",
src_w, src_h, min_width, min_height, 2048, 2048); src_w, src_h, min_width, min_height, 2048, 2048);
return -EINVAL; return -EINVAL;
} }
if (width_bytes > 4096) { if (width_bytes > 4096) {
DRM_DEBUG_KMS("Fetch width (%d) exceeds hardware max with scaling (%u)\n", drm_dbg_kms(&i915->drm, "Fetch width (%d) exceeds hardware max with scaling (%u)\n",
width_bytes, 4096); width_bytes, 4096);
return -EINVAL; return -EINVAL;
} }
if (stride > 4096) { if (stride > 4096) {
DRM_DEBUG_KMS("Stride (%u) exceeds hardware max with scaling (%u)\n", drm_dbg_kms(&i915->drm, "Stride (%u) exceeds hardware max with scaling (%u)\n",
stride, 4096); stride, 4096);
return -EINVAL; return -EINVAL;
} }

View File

@@ -4,10 +4,12 @@
*/ */
#include "i915_drv.h" #include "i915_drv.h"
#include "i915_reg.h"
#include "intel_display.h" #include "intel_display.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_dp_mst.h" #include "intel_dp_mst.h"
#include "intel_tc.h" #include "intel_tc.h"
#include "intel_tc_phy_regs.h"
static const char *tc_port_mode_name(enum tc_port_mode mode) static const char *tc_port_mode_name(enum tc_port_mode mode)
{ {
@@ -345,10 +347,11 @@ static bool icl_tc_phy_status_complete(struct intel_digital_port *dig_port)
static bool adl_tc_phy_status_complete(struct intel_digital_port *dig_port) static bool adl_tc_phy_status_complete(struct intel_digital_port *dig_port)
{ {
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
enum tc_port tc_port = intel_port_to_tc(i915, dig_port->base.port);
struct intel_uncore *uncore = &i915->uncore; struct intel_uncore *uncore = &i915->uncore;
u32 val; u32 val;
val = intel_uncore_read(uncore, TCSS_DDI_STATUS(dig_port->tc_phy_fia_idx)); val = intel_uncore_read(uncore, TCSS_DDI_STATUS(tc_port));
if (val == 0xffffffff) { if (val == 0xffffffff) {
drm_dbg_kms(&i915->drm, drm_dbg_kms(&i915->drm,
"Port %s: PHY in TCCOLD, assuming not complete\n", "Port %s: PHY in TCCOLD, assuming not complete\n",

View File

@@ -0,0 +1,280 @@
/* SPDX-License-Identifier: MIT */
/*
* Copyright © 2022 Intel Corporation
*/
#ifndef __INTEL_TC_PHY_REGS__
#define __INTEL_TC_PHY_REGS__
#include "i915_reg_defs.h"
#define MG_PHY_PORT_LN(ln, tc_port, ln0p1, ln0p2, ln1p1) \
_MMIO(_PORT(tc_port, ln0p1, ln0p2) + (ln) * ((ln1p1) - (ln0p1)))
#define MG_TX_LINK_PARAMS_TX1LN0_PORT1 0x16812C
#define MG_TX_LINK_PARAMS_TX1LN1_PORT1 0x16852C
#define MG_TX_LINK_PARAMS_TX1LN0_PORT2 0x16912C
#define MG_TX_LINK_PARAMS_TX1LN1_PORT2 0x16952C
#define MG_TX1_LINK_PARAMS(ln, tc_port) \
MG_PHY_PORT_LN(ln, tc_port, MG_TX_LINK_PARAMS_TX1LN0_PORT1, \
MG_TX_LINK_PARAMS_TX1LN0_PORT2, \
MG_TX_LINK_PARAMS_TX1LN1_PORT1)
#define MG_TX_LINK_PARAMS_TX2LN0_PORT1 0x1680AC
#define MG_TX_LINK_PARAMS_TX2LN1_PORT1 0x1684AC
#define MG_TX_LINK_PARAMS_TX2LN0_PORT2 0x1690AC
#define MG_TX_LINK_PARAMS_TX2LN1_PORT2 0x1694AC
#define MG_TX2_LINK_PARAMS(ln, tc_port) \
MG_PHY_PORT_LN(ln, tc_port, MG_TX_LINK_PARAMS_TX2LN0_PORT1, \
MG_TX_LINK_PARAMS_TX2LN0_PORT2, \
MG_TX_LINK_PARAMS_TX2LN1_PORT1)
#define CRI_USE_FS32 (1 << 5)
#define MG_TX_PISO_READLOAD_TX1LN0_PORT1 0x16814C
#define MG_TX_PISO_READLOAD_TX1LN1_PORT1 0x16854C
#define MG_TX_PISO_READLOAD_TX1LN0_PORT2 0x16914C
#define MG_TX_PISO_READLOAD_TX1LN1_PORT2 0x16954C
#define MG_TX1_PISO_READLOAD(ln, tc_port) \
MG_PHY_PORT_LN(ln, tc_port, MG_TX_PISO_READLOAD_TX1LN0_PORT1, \
MG_TX_PISO_READLOAD_TX1LN0_PORT2, \
MG_TX_PISO_READLOAD_TX1LN1_PORT1)
#define MG_TX_PISO_READLOAD_TX2LN0_PORT1 0x1680CC
#define MG_TX_PISO_READLOAD_TX2LN1_PORT1 0x1684CC
#define MG_TX_PISO_READLOAD_TX2LN0_PORT2 0x1690CC
#define MG_TX_PISO_READLOAD_TX2LN1_PORT2 0x1694CC
#define MG_TX2_PISO_READLOAD(ln, tc_port) \
MG_PHY_PORT_LN(ln, tc_port, MG_TX_PISO_READLOAD_TX2LN0_PORT1, \
MG_TX_PISO_READLOAD_TX2LN0_PORT2, \
MG_TX_PISO_READLOAD_TX2LN1_PORT1)
#define CRI_CALCINIT (1 << 1)
#define MG_TX_SWINGCTRL_TX1LN0_PORT1 0x168148
#define MG_TX_SWINGCTRL_TX1LN1_PORT1 0x168548
#define MG_TX_SWINGCTRL_TX1LN0_PORT2 0x169148
#define MG_TX_SWINGCTRL_TX1LN1_PORT2 0x169548
#define MG_TX1_SWINGCTRL(ln, tc_port) \
MG_PHY_PORT_LN(ln, tc_port, MG_TX_SWINGCTRL_TX1LN0_PORT1, \
MG_TX_SWINGCTRL_TX1LN0_PORT2, \
MG_TX_SWINGCTRL_TX1LN1_PORT1)
#define MG_TX_SWINGCTRL_TX2LN0_PORT1 0x1680C8
#define MG_TX_SWINGCTRL_TX2LN1_PORT1 0x1684C8
#define MG_TX_SWINGCTRL_TX2LN0_PORT2 0x1690C8
#define MG_TX_SWINGCTRL_TX2LN1_PORT2 0x1694C8
#define MG_TX2_SWINGCTRL(ln, tc_port) \
MG_PHY_PORT_LN(ln, tc_port, MG_TX_SWINGCTRL_TX2LN0_PORT1, \
MG_TX_SWINGCTRL_TX2LN0_PORT2, \
MG_TX_SWINGCTRL_TX2LN1_PORT1)
#define CRI_TXDEEMPH_OVERRIDE_17_12(x) ((x) << 0)
#define CRI_TXDEEMPH_OVERRIDE_17_12_MASK (0x3F << 0)
#define MG_TX_DRVCTRL_TX1LN0_TXPORT1 0x168144
#define MG_TX_DRVCTRL_TX1LN1_TXPORT1 0x168544
#define MG_TX_DRVCTRL_TX1LN0_TXPORT2 0x169144
#define MG_TX_DRVCTRL_TX1LN1_TXPORT2 0x169544
#define MG_TX_DRVCTRL_TX1LN0_TXPORT3 0x16A144
#define MG_TX_DRVCTRL_TX1LN1_TXPORT3 0x16A544
#define MG_TX_DRVCTRL_TX1LN0_TXPORT4 0x16B144
#define MG_TX_DRVCTRL_TX1LN1_TXPORT4 0x16B544
#define MG_TX1_DRVCTRL(ln, tc_port) \
MG_PHY_PORT_LN(ln, tc_port, MG_TX_DRVCTRL_TX1LN0_TXPORT1, \
MG_TX_DRVCTRL_TX1LN0_TXPORT2, \
MG_TX_DRVCTRL_TX1LN1_TXPORT1)
#define MG_TX_DRVCTRL_TX2LN0_PORT1 0x1680C4
#define MG_TX_DRVCTRL_TX2LN1_PORT1 0x1684C4
#define MG_TX_DRVCTRL_TX2LN0_PORT2 0x1690C4
#define MG_TX_DRVCTRL_TX2LN1_PORT2 0x1694C4
#define MG_TX2_DRVCTRL(ln, tc_port) \
MG_PHY_PORT_LN(ln, tc_port, MG_TX_DRVCTRL_TX2LN0_PORT1, \
MG_TX_DRVCTRL_TX2LN0_PORT2, \
MG_TX_DRVCTRL_TX2LN1_PORT1)
#define CRI_TXDEEMPH_OVERRIDE_11_6(x) ((x) << 24)
#define CRI_TXDEEMPH_OVERRIDE_11_6_MASK (0x3F << 24)
#define CRI_TXDEEMPH_OVERRIDE_EN (1 << 22)
#define CRI_TXDEEMPH_OVERRIDE_5_0(x) ((x) << 16)
#define CRI_TXDEEMPH_OVERRIDE_5_0_MASK (0x3F << 16)
#define CRI_LOADGEN_SEL(x) ((x) << 12)
#define CRI_LOADGEN_SEL_MASK (0x3 << 12)
#define MG_CLKHUB_LN0_PORT1 0x16839C
#define MG_CLKHUB_LN1_PORT1 0x16879C
#define MG_CLKHUB_LN0_PORT2 0x16939C
#define MG_CLKHUB_LN1_PORT2 0x16979C
#define MG_CLKHUB(ln, tc_port) \
MG_PHY_PORT_LN(ln, tc_port, MG_CLKHUB_LN0_PORT1, \
MG_CLKHUB_LN0_PORT2, \
MG_CLKHUB_LN1_PORT1)
#define CFG_LOW_RATE_LKREN_EN (1 << 11)
#define MG_TX_DCC_TX1LN0_PORT1 0x168110
#define MG_TX_DCC_TX1LN1_PORT1 0x168510
#define MG_TX_DCC_TX1LN0_PORT2 0x169110
#define MG_TX_DCC_TX1LN1_PORT2 0x169510
#define MG_TX1_DCC(ln, tc_port) \
MG_PHY_PORT_LN(ln, tc_port, MG_TX_DCC_TX1LN0_PORT1, \
MG_TX_DCC_TX1LN0_PORT2, \
MG_TX_DCC_TX1LN1_PORT1)
#define MG_TX_DCC_TX2LN0_PORT1 0x168090
#define MG_TX_DCC_TX2LN1_PORT1 0x168490
#define MG_TX_DCC_TX2LN0_PORT2 0x169090
#define MG_TX_DCC_TX2LN1_PORT2 0x169490
#define MG_TX2_DCC(ln, tc_port) \
MG_PHY_PORT_LN(ln, tc_port, MG_TX_DCC_TX2LN0_PORT1, \
MG_TX_DCC_TX2LN0_PORT2, \
MG_TX_DCC_TX2LN1_PORT1)
#define CFG_AMI_CK_DIV_OVERRIDE_VAL(x) ((x) << 25)
#define CFG_AMI_CK_DIV_OVERRIDE_VAL_MASK (0x3 << 25)
#define CFG_AMI_CK_DIV_OVERRIDE_EN (1 << 24)
#define MG_DP_MODE_LN0_ACU_PORT1 0x1683A0
#define MG_DP_MODE_LN1_ACU_PORT1 0x1687A0
#define MG_DP_MODE_LN0_ACU_PORT2 0x1693A0
#define MG_DP_MODE_LN1_ACU_PORT2 0x1697A0
#define MG_DP_MODE(ln, tc_port) \
MG_PHY_PORT_LN(ln, tc_port, MG_DP_MODE_LN0_ACU_PORT1, \
MG_DP_MODE_LN0_ACU_PORT2, \
MG_DP_MODE_LN1_ACU_PORT1)
#define MG_DP_MODE_CFG_DP_X2_MODE (1 << 7)
#define MG_DP_MODE_CFG_DP_X1_MODE (1 << 6)
#define FIA1_BASE 0x163000
#define FIA2_BASE 0x16E000
#define FIA3_BASE 0x16F000
#define _FIA(fia) _PICK((fia), FIA1_BASE, FIA2_BASE, FIA3_BASE)
#define _MMIO_FIA(fia, off) _MMIO(_FIA(fia) + (off))
/* ICL PHY DFLEX registers */
#define PORT_TX_DFLEXDPMLE1(fia) _MMIO_FIA((fia), 0x008C0)
#define DFLEXDPMLE1_DPMLETC_MASK(idx) (0xf << (4 * (idx)))
#define DFLEXDPMLE1_DPMLETC_ML0(idx) (1 << (4 * (idx)))
#define DFLEXDPMLE1_DPMLETC_ML1_0(idx) (3 << (4 * (idx)))
#define DFLEXDPMLE1_DPMLETC_ML3(idx) (8 << (4 * (idx)))
#define DFLEXDPMLE1_DPMLETC_ML3_2(idx) (12 << (4 * (idx)))
#define DFLEXDPMLE1_DPMLETC_ML3_0(idx) (15 << (4 * (idx)))
#define _MG_REFCLKIN_CTL_PORT1 0x16892C
#define _MG_REFCLKIN_CTL_PORT2 0x16992C
#define MG_REFCLKIN_CTL_OD_2_MUX(x) ((x) << 8)
#define MG_REFCLKIN_CTL_OD_2_MUX_MASK (0x7 << 8)
#define MG_REFCLKIN_CTL(tc_port) _MMIO_PORT((tc_port), \
_MG_REFCLKIN_CTL_PORT1, \
_MG_REFCLKIN_CTL_PORT2)
#define _MG_CLKTOP2_CORECLKCTL1_PORT1 0x1688D8
#define _MG_CLKTOP2_CORECLKCTL1_PORT2 0x1698D8
#define MG_CLKTOP2_CORECLKCTL1_B_DIVRATIO(x) ((x) << 16)
#define MG_CLKTOP2_CORECLKCTL1_B_DIVRATIO_MASK (0xff << 16)
#define MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO(x) ((x) << 8)
#define MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO_MASK (0xff << 8)
#define MG_CLKTOP2_CORECLKCTL1(tc_port) _MMIO_PORT((tc_port), \
_MG_CLKTOP2_CORECLKCTL1_PORT1, \
_MG_CLKTOP2_CORECLKCTL1_PORT2)
#define _MG_CLKTOP2_HSCLKCTL_PORT1 0x1688D4
#define _MG_CLKTOP2_HSCLKCTL_PORT2 0x1698D4
#define MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL(x) ((x) << 16)
#define MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL_MASK (0x1 << 16)
#define MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL(x) ((x) << 14)
#define MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL_MASK (0x3 << 14)
#define MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_MASK (0x3 << 12)
#define MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_2 (0 << 12)
#define MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_3 (1 << 12)
#define MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_5 (2 << 12)
#define MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_7 (3 << 12)
#define MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO(x) ((x) << 8)
#define MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_SHIFT 8
#define MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK (0xf << 8)
#define MG_CLKTOP2_HSCLKCTL(tc_port) _MMIO_PORT((tc_port), \
_MG_CLKTOP2_HSCLKCTL_PORT1, \
_MG_CLKTOP2_HSCLKCTL_PORT2)
#define _MG_PLL_DIV0_PORT1 0x168A00
#define _MG_PLL_DIV0_PORT2 0x169A00
#define MG_PLL_DIV0_FRACNEN_H (1 << 30)
#define MG_PLL_DIV0_FBDIV_FRAC_MASK (0x3fffff << 8)
#define MG_PLL_DIV0_FBDIV_FRAC_SHIFT 8
#define MG_PLL_DIV0_FBDIV_FRAC(x) ((x) << 8)
#define MG_PLL_DIV0_FBDIV_INT_MASK (0xff << 0)
#define MG_PLL_DIV0_FBDIV_INT(x) ((x) << 0)
#define MG_PLL_DIV0(tc_port) _MMIO_PORT((tc_port), _MG_PLL_DIV0_PORT1, \
_MG_PLL_DIV0_PORT2)
#define _MG_PLL_DIV1_PORT1 0x168A04
#define _MG_PLL_DIV1_PORT2 0x169A04
#define MG_PLL_DIV1_IREF_NDIVRATIO(x) ((x) << 16)
#define MG_PLL_DIV1_DITHER_DIV_1 (0 << 12)
#define MG_PLL_DIV1_DITHER_DIV_2 (1 << 12)
#define MG_PLL_DIV1_DITHER_DIV_4 (2 << 12)
#define MG_PLL_DIV1_DITHER_DIV_8 (3 << 12)
#define MG_PLL_DIV1_NDIVRATIO(x) ((x) << 4)
#define MG_PLL_DIV1_FBPREDIV_MASK (0xf << 0)
#define MG_PLL_DIV1_FBPREDIV(x) ((x) << 0)
#define MG_PLL_DIV1(tc_port) _MMIO_PORT((tc_port), _MG_PLL_DIV1_PORT1, \
_MG_PLL_DIV1_PORT2)
#define _MG_PLL_LF_PORT1 0x168A08
#define _MG_PLL_LF_PORT2 0x169A08
#define MG_PLL_LF_TDCTARGETCNT(x) ((x) << 24)
#define MG_PLL_LF_AFCCNTSEL_256 (0 << 20)
#define MG_PLL_LF_AFCCNTSEL_512 (1 << 20)
#define MG_PLL_LF_GAINCTRL(x) ((x) << 16)
#define MG_PLL_LF_INT_COEFF(x) ((x) << 8)
#define MG_PLL_LF_PROP_COEFF(x) ((x) << 0)
#define MG_PLL_LF(tc_port) _MMIO_PORT((tc_port), _MG_PLL_LF_PORT1, \
_MG_PLL_LF_PORT2)
#define _MG_PLL_FRAC_LOCK_PORT1 0x168A0C
#define _MG_PLL_FRAC_LOCK_PORT2 0x169A0C
#define MG_PLL_FRAC_LOCK_TRUELOCK_CRIT_32 (1 << 18)
#define MG_PLL_FRAC_LOCK_EARLYLOCK_CRIT_32 (1 << 16)
#define MG_PLL_FRAC_LOCK_LOCKTHRESH(x) ((x) << 11)
#define MG_PLL_FRAC_LOCK_DCODITHEREN (1 << 10)
#define MG_PLL_FRAC_LOCK_FEEDFWRDCAL_EN (1 << 8)
#define MG_PLL_FRAC_LOCK_FEEDFWRDGAIN(x) ((x) << 0)
#define MG_PLL_FRAC_LOCK(tc_port) _MMIO_PORT((tc_port), \
_MG_PLL_FRAC_LOCK_PORT1, \
_MG_PLL_FRAC_LOCK_PORT2)
#define _MG_PLL_SSC_PORT1 0x168A10
#define _MG_PLL_SSC_PORT2 0x169A10
#define MG_PLL_SSC_EN (1 << 28)
#define MG_PLL_SSC_TYPE(x) ((x) << 26)
#define MG_PLL_SSC_STEPLENGTH(x) ((x) << 16)
#define MG_PLL_SSC_STEPNUM(x) ((x) << 10)
#define MG_PLL_SSC_FLLEN (1 << 9)
#define MG_PLL_SSC_STEPSIZE(x) ((x) << 0)
#define MG_PLL_SSC(tc_port) _MMIO_PORT((tc_port), _MG_PLL_SSC_PORT1, \
_MG_PLL_SSC_PORT2)
#define _MG_PLL_BIAS_PORT1 0x168A14
#define _MG_PLL_BIAS_PORT2 0x169A14
#define MG_PLL_BIAS_BIAS_GB_SEL(x) ((x) << 30)
#define MG_PLL_BIAS_BIAS_GB_SEL_MASK (0x3 << 30)
#define MG_PLL_BIAS_INIT_DCOAMP(x) ((x) << 24)
#define MG_PLL_BIAS_INIT_DCOAMP_MASK (0x3f << 24)
#define MG_PLL_BIAS_BIAS_BONUS(x) ((x) << 16)
#define MG_PLL_BIAS_BIAS_BONUS_MASK (0xff << 16)
#define MG_PLL_BIAS_BIASCAL_EN (1 << 15)
#define MG_PLL_BIAS_CTRIM(x) ((x) << 8)
#define MG_PLL_BIAS_CTRIM_MASK (0x1f << 8)
#define MG_PLL_BIAS_VREF_RDAC(x) ((x) << 5)
#define MG_PLL_BIAS_VREF_RDAC_MASK (0x7 << 5)
#define MG_PLL_BIAS_IREFTRIM(x) ((x) << 0)
#define MG_PLL_BIAS_IREFTRIM_MASK (0x1f << 0)
#define MG_PLL_BIAS(tc_port) _MMIO_PORT((tc_port), _MG_PLL_BIAS_PORT1, \
_MG_PLL_BIAS_PORT2)
#define _MG_PLL_TDC_COLDST_BIAS_PORT1 0x168A18
#define _MG_PLL_TDC_COLDST_BIAS_PORT2 0x169A18
#define MG_PLL_TDC_COLDST_IREFINT_EN (1 << 27)
#define MG_PLL_TDC_COLDST_REFBIAS_START_PULSE_W(x) ((x) << 17)
#define MG_PLL_TDC_COLDST_COLDSTART (1 << 16)
#define MG_PLL_TDC_TDCOVCCORR_EN (1 << 2)
#define MG_PLL_TDC_TDCSEL(x) ((x) << 0)
#define MG_PLL_TDC_COLDST_BIAS(tc_port) _MMIO_PORT((tc_port), \
_MG_PLL_TDC_COLDST_BIAS_PORT1, \
_MG_PLL_TDC_COLDST_BIAS_PORT2)
#endif /* __INTEL_TC_PHY_REGS__ */

View File

@@ -226,32 +226,6 @@ struct bdb_general_features {
#define DEVICE_TYPE_DIGITAL_OUTPUT (1 << 1) #define DEVICE_TYPE_DIGITAL_OUTPUT (1 << 1)
#define DEVICE_TYPE_ANALOG_OUTPUT (1 << 0) #define DEVICE_TYPE_ANALOG_OUTPUT (1 << 0)
/*
* Bits we care about when checking for DEVICE_TYPE_eDP. Depending on the
* system, the other bits may or may not be set for eDP outputs.
*/
#define DEVICE_TYPE_eDP_BITS \
(DEVICE_TYPE_INTERNAL_CONNECTOR | \
DEVICE_TYPE_MIPI_OUTPUT | \
DEVICE_TYPE_COMPOSITE_OUTPUT | \
DEVICE_TYPE_DUAL_CHANNEL | \
DEVICE_TYPE_LVDS_SIGNALING | \
DEVICE_TYPE_TMDS_DVI_SIGNALING | \
DEVICE_TYPE_VIDEO_SIGNALING | \
DEVICE_TYPE_DISPLAYPORT_OUTPUT | \
DEVICE_TYPE_ANALOG_OUTPUT)
#define DEVICE_TYPE_DP_DUAL_MODE_BITS \
(DEVICE_TYPE_INTERNAL_CONNECTOR | \
DEVICE_TYPE_MIPI_OUTPUT | \
DEVICE_TYPE_COMPOSITE_OUTPUT | \
DEVICE_TYPE_LVDS_SIGNALING | \
DEVICE_TYPE_TMDS_DVI_SIGNALING | \
DEVICE_TYPE_VIDEO_SIGNALING | \
DEVICE_TYPE_DISPLAYPORT_OUTPUT | \
DEVICE_TYPE_DIGITAL_OUTPUT | \
DEVICE_TYPE_ANALOG_OUTPUT)
#define DEVICE_CFG_NONE 0x00 #define DEVICE_CFG_NONE 0x00
#define DEVICE_CFG_12BIT_DVOB 0x01 #define DEVICE_CFG_12BIT_DVOB 0x01
#define DEVICE_CFG_12BIT_DVOC 0x02 #define DEVICE_CFG_12BIT_DVOC 0x02

View File

@@ -341,19 +341,14 @@ bool intel_dsc_source_support(const struct intel_crtc_state *crtc_state)
const struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); const struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *i915 = to_i915(crtc->base.dev); struct drm_i915_private *i915 = to_i915(crtc->base.dev);
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
enum pipe pipe = crtc->pipe;
if (!INTEL_INFO(i915)->display.has_dsc) if (!INTEL_INFO(i915)->display.has_dsc)
return false; return false;
/* On TGL, DSC is supported on all Pipes */
if (DISPLAY_VER(i915) >= 12) if (DISPLAY_VER(i915) >= 12)
return true; return true;
if (DISPLAY_VER(i915) >= 11 && if (DISPLAY_VER(i915) >= 11 && cpu_transcoder != TRANSCODER_A)
(pipe != PIPE_A || cpu_transcoder == TRANSCODER_EDP ||
cpu_transcoder == TRANSCODER_DSI_0 ||
cpu_transcoder == TRANSCODER_DSI_1))
return true; return true;
return false; return false;

View File

@@ -7,6 +7,7 @@
#include <linux/vgaarb.h> #include <linux/vgaarb.h>
#include <drm/i915_drm.h> #include <drm/i915_drm.h>
#include <video/vga.h>
#include "i915_drv.h" #include "i915_drv.h"
#include "intel_de.h" #include "intel_de.h"
@@ -34,9 +35,9 @@ void intel_vga_disable(struct drm_i915_private *dev_priv)
/* WaEnableVGAAccessThroughIOPort:ctg,elk,ilk,snb,ivb,vlv,hsw */ /* WaEnableVGAAccessThroughIOPort:ctg,elk,ilk,snb,ivb,vlv,hsw */
vga_get_uninterruptible(pdev, VGA_RSRC_LEGACY_IO); vga_get_uninterruptible(pdev, VGA_RSRC_LEGACY_IO);
outb(SR01, VGA_SR_INDEX); outb(0x01, VGA_SEQ_I);
sr1 = inb(VGA_SR_DATA); sr1 = inb(VGA_SEQ_D);
outb(sr1 | 1 << 5, VGA_SR_DATA); outb(sr1 | VGA_SR01_SCREEN_OFF, VGA_SEQ_D);
vga_put(pdev, VGA_RSRC_LEGACY_IO); vga_put(pdev, VGA_RSRC_LEGACY_IO);
udelay(300); udelay(300);
@@ -92,7 +93,7 @@ void intel_vga_reset_io_mem(struct drm_i915_private *i915)
* and error messages. * and error messages.
*/ */
vga_get_uninterruptible(pdev, VGA_RSRC_LEGACY_IO); vga_get_uninterruptible(pdev, VGA_RSRC_LEGACY_IO);
outb(inb(VGA_MSR_READ), VGA_MSR_WRITE); outb(inb(VGA_MIS_R), VGA_MIS_W);
vga_put(pdev, VGA_RSRC_LEGACY_IO); vga_put(pdev, VGA_RSRC_LEGACY_IO);
} }

View File

@@ -961,6 +961,7 @@ static u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state,
static u32 skl_surf_address(const struct intel_plane_state *plane_state, static u32 skl_surf_address(const struct intel_plane_state *plane_state,
int color_plane) int color_plane)
{ {
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
const struct drm_framebuffer *fb = plane_state->hw.fb; const struct drm_framebuffer *fb = plane_state->hw.fb;
u32 offset = plane_state->view.color_plane[color_plane].offset; u32 offset = plane_state->view.color_plane[color_plane].offset;
@@ -969,11 +970,11 @@ static u32 skl_surf_address(const struct intel_plane_state *plane_state,
* The DPT object contains only one vma, so the VMA's offset * The DPT object contains only one vma, so the VMA's offset
* within the DPT is always 0. * within the DPT is always 0.
*/ */
WARN_ON(plane_state->dpt_vma->node.start); drm_WARN_ON(&i915->drm, plane_state->dpt_vma->node.start);
WARN_ON(offset & 0x1fffff); drm_WARN_ON(&i915->drm, offset & 0x1fffff);
return offset >> 9; return offset >> 9;
} else { } else {
WARN_ON(offset & 0xfff); drm_WARN_ON(&i915->drm, offset & 0xfff);
return offset; return offset;
} }
} }
@@ -992,6 +993,54 @@ static u32 skl_plane_surf(const struct intel_plane_state *plane_state,
return plane_surf; return plane_surf;
} }
static u32 skl_plane_aux_dist(const struct intel_plane_state *plane_state,
int color_plane)
{
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
const struct drm_framebuffer *fb = plane_state->hw.fb;
int aux_plane = skl_main_to_aux_plane(fb, color_plane);
u32 aux_dist;
if (!aux_plane)
return 0;
aux_dist = skl_surf_address(plane_state, aux_plane) -
skl_surf_address(plane_state, color_plane);
if (DISPLAY_VER(i915) < 12)
aux_dist |= PLANE_AUX_STRIDE(skl_plane_stride(plane_state, aux_plane));
return aux_dist;
}
static u32 skl_plane_keyval(const struct intel_plane_state *plane_state)
{
const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
return key->min_value;
}
static u32 skl_plane_keymax(const struct intel_plane_state *plane_state)
{
const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
u8 alpha = plane_state->hw.alpha >> 8;
return (key->max_value & 0xffffff) | PLANE_KEYMAX_ALPHA(alpha);
}
static u32 skl_plane_keymsk(const struct intel_plane_state *plane_state)
{
const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
u8 alpha = plane_state->hw.alpha >> 8;
u32 keymsk;
keymsk = key->channel_mask & 0x7ffffff;
if (alpha < 0xff)
keymsk |= PLANE_KEYMSK_ALPHA_ENABLE;
return keymsk;
}
static void icl_plane_csc_load_black(struct intel_plane *plane) static void icl_plane_csc_load_black(struct intel_plane *plane)
{ {
struct drm_i915_private *i915 = to_i915(plane->base.dev); struct drm_i915_private *i915 = to_i915(plane->base.dev);
@@ -1016,15 +1065,24 @@ static void icl_plane_csc_load_black(struct intel_plane *plane)
intel_de_write_fw(i915, PLANE_CSC_POSTOFF(pipe, plane_id, 2), 0); intel_de_write_fw(i915, PLANE_CSC_POSTOFF(pipe, plane_id, 2), 0);
} }
static int skl_plane_color_plane(const struct intel_plane_state *plane_state)
{
/* Program the UV plane on planar master */
if (plane_state->planar_linked_plane && !plane_state->planar_slave)
return 1;
else
return 0;
}
static void static void
skl_program_plane_noarm(struct intel_plane *plane, skl_plane_update_noarm(struct intel_plane *plane,
const struct intel_crtc_state *crtc_state, const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state, const struct intel_plane_state *plane_state)
int color_plane)
{ {
struct drm_i915_private *dev_priv = to_i915(plane->base.dev); struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
enum plane_id plane_id = plane->id; enum plane_id plane_id = plane->id;
enum pipe pipe = plane->pipe; enum pipe pipe = plane->pipe;
int color_plane = skl_plane_color_plane(plane_state);
u32 stride = skl_plane_stride(plane_state, color_plane); u32 stride = skl_plane_stride(plane_state, color_plane);
const struct drm_framebuffer *fb = plane_state->hw.fb; const struct drm_framebuffer *fb = plane_state->hw.fb;
int crtc_x = plane_state->uapi.dst.x1; int crtc_x = plane_state->uapi.dst.x1;
@@ -1048,11 +1106,12 @@ skl_program_plane_noarm(struct intel_plane *plane,
if (plane_state->force_black) if (plane_state->force_black)
icl_plane_csc_load_black(plane); icl_plane_csc_load_black(plane);
intel_de_write_fw(dev_priv, PLANE_STRIDE(pipe, plane_id), stride); intel_de_write_fw(dev_priv, PLANE_STRIDE(pipe, plane_id),
PLANE_STRIDE_(stride));
intel_de_write_fw(dev_priv, PLANE_POS(pipe, plane_id), intel_de_write_fw(dev_priv, PLANE_POS(pipe, plane_id),
(crtc_y << 16) | crtc_x); PLANE_POS_Y(crtc_y) | PLANE_POS_X(crtc_x));
intel_de_write_fw(dev_priv, PLANE_SIZE(pipe, plane_id), intel_de_write_fw(dev_priv, PLANE_SIZE(pipe, plane_id),
((src_h - 1) << 16) | (src_w - 1)); PLANE_HEIGHT(src_h - 1) | PLANE_WIDTH(src_w - 1));
if (intel_fb_is_rc_ccs_cc_modifier(fb->modifier)) { if (intel_fb_is_rc_ccs_cc_modifier(fb->modifier)) {
intel_de_write_fw(dev_priv, PLANE_CC_VAL(pipe, plane_id, 0), intel_de_write_fw(dev_priv, PLANE_CC_VAL(pipe, plane_id, 0),
@@ -1076,21 +1135,17 @@ skl_program_plane_noarm(struct intel_plane *plane,
} }
static void static void
skl_program_plane_arm(struct intel_plane *plane, skl_plane_update_arm(struct intel_plane *plane,
const struct intel_crtc_state *crtc_state, const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state, const struct intel_plane_state *plane_state)
int color_plane)
{ {
struct drm_i915_private *dev_priv = to_i915(plane->base.dev); struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
enum plane_id plane_id = plane->id; enum plane_id plane_id = plane->id;
enum pipe pipe = plane->pipe; enum pipe pipe = plane->pipe;
const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; int color_plane = skl_plane_color_plane(plane_state);
const struct drm_framebuffer *fb = plane_state->hw.fb;
int aux_plane = skl_main_to_aux_plane(fb, color_plane);
u32 x = plane_state->view.color_plane[color_plane].x; u32 x = plane_state->view.color_plane[color_plane].x;
u32 y = plane_state->view.color_plane[color_plane].y; u32 y = plane_state->view.color_plane[color_plane].y;
u32 keymsk, keymax, aux_dist = 0, plane_color_ctl = 0; u32 plane_color_ctl = 0;
u8 alpha = plane_state->hw.alpha >> 8;
u32 plane_ctl = plane_state->ctl; u32 plane_ctl = plane_state->ctl;
unsigned long irqflags; unsigned long irqflags;
@@ -1100,36 +1155,22 @@ skl_program_plane_arm(struct intel_plane *plane,
plane_color_ctl = plane_state->color_ctl | plane_color_ctl = plane_state->color_ctl |
glk_plane_color_ctl_crtc(crtc_state); glk_plane_color_ctl_crtc(crtc_state);
keymax = (key->max_value & 0xffffff) | PLANE_KEYMAX_ALPHA(alpha);
keymsk = key->channel_mask & 0x7ffffff;
if (alpha < 0xff)
keymsk |= PLANE_KEYMSK_ALPHA_ENABLE;
if (aux_plane) {
aux_dist = skl_surf_address(plane_state, aux_plane) -
skl_surf_address(plane_state, color_plane);
if (DISPLAY_VER(dev_priv) < 12)
aux_dist |= skl_plane_stride(plane_state, aux_plane);
}
spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
intel_de_write_fw(dev_priv, PLANE_KEYVAL(pipe, plane_id), intel_de_write_fw(dev_priv, PLANE_KEYVAL(pipe, plane_id), skl_plane_keyval(plane_state));
key->min_value); intel_de_write_fw(dev_priv, PLANE_KEYMSK(pipe, plane_id), skl_plane_keymsk(plane_state));
intel_de_write_fw(dev_priv, PLANE_KEYMSK(pipe, plane_id), keymsk); intel_de_write_fw(dev_priv, PLANE_KEYMAX(pipe, plane_id), skl_plane_keymax(plane_state));
intel_de_write_fw(dev_priv, PLANE_KEYMAX(pipe, plane_id), keymax);
intel_de_write_fw(dev_priv, PLANE_OFFSET(pipe, plane_id), intel_de_write_fw(dev_priv, PLANE_OFFSET(pipe, plane_id),
(y << 16) | x); PLANE_OFFSET_Y(y) | PLANE_OFFSET_X(x));
intel_de_write_fw(dev_priv, PLANE_AUX_DIST(pipe, plane_id), aux_dist); intel_de_write_fw(dev_priv, PLANE_AUX_DIST(pipe, plane_id),
skl_plane_aux_dist(plane_state, color_plane));
if (DISPLAY_VER(dev_priv) < 11) if (DISPLAY_VER(dev_priv) < 11)
intel_de_write_fw(dev_priv, PLANE_AUX_OFFSET(pipe, plane_id), intel_de_write_fw(dev_priv, PLANE_AUX_OFFSET(pipe, plane_id),
(plane_state->view.color_plane[1].y << 16) | PLANE_OFFSET_Y(plane_state->view.color_plane[1].y) |
plane_state->view.color_plane[1].x); PLANE_OFFSET_X(plane_state->view.color_plane[1].x));
if (DISPLAY_VER(dev_priv) >= 10) if (DISPLAY_VER(dev_priv) >= 10)
intel_de_write_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id), plane_color_ctl); intel_de_write_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id), plane_color_ctl);
@@ -1182,34 +1223,6 @@ skl_plane_async_flip(struct intel_plane *plane,
spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
} }
static void
skl_plane_update_noarm(struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
{
int color_plane = 0;
if (plane_state->planar_linked_plane && !plane_state->planar_slave)
/* Program the UV plane on planar master */
color_plane = 1;
skl_program_plane_noarm(plane, crtc_state, plane_state, color_plane);
}
static void
skl_plane_update_arm(struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
{
int color_plane = 0;
if (plane_state->planar_linked_plane && !plane_state->planar_slave)
/* Program the UV plane on planar master */
color_plane = 1;
skl_program_plane_arm(plane, crtc_state, plane_state, color_plane);
}
static bool intel_format_is_p01x(u32 format) static bool intel_format_is_p01x(u32 format)
{ {
switch (format) { switch (format) {
@@ -1338,6 +1351,7 @@ static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_s
static int skl_plane_check_nv12_rotation(const struct intel_plane_state *plane_state) static int skl_plane_check_nv12_rotation(const struct intel_plane_state *plane_state)
{ {
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
const struct drm_framebuffer *fb = plane_state->hw.fb; const struct drm_framebuffer *fb = plane_state->hw.fb;
unsigned int rotation = plane_state->hw.rotation; unsigned int rotation = plane_state->hw.rotation;
int src_w = drm_rect_width(&plane_state->uapi.src) >> 16; int src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
@@ -1347,7 +1361,7 @@ static int skl_plane_check_nv12_rotation(const struct intel_plane_state *plane_s
src_w & 3 && src_w & 3 &&
(rotation == DRM_MODE_ROTATE_270 || (rotation == DRM_MODE_ROTATE_270 ||
rotation == (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90))) { rotation == (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90))) {
DRM_DEBUG_KMS("src width must be multiple of 4 for rotated planar YUV\n"); drm_dbg_kms(&i915->drm, "src width must be multiple of 4 for rotated planar YUV\n");
return -EINVAL; return -EINVAL;
} }
@@ -1816,20 +1830,27 @@ static int skl_plane_check(struct intel_crtc_state *crtc_state,
return 0; return 0;
} }
static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv, static enum intel_fbc_id skl_fbc_id_for_pipe(enum pipe pipe)
enum pipe pipe, enum plane_id plane_id)
{ {
if (!HAS_FBC(dev_priv)) return pipe - PIPE_A + INTEL_FBC_A;
}
static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv,
enum intel_fbc_id fbc_id, enum plane_id plane_id)
{
if ((INTEL_INFO(dev_priv)->display.fbc_mask & BIT(fbc_id)) == 0)
return false; return false;
return pipe == PIPE_A && plane_id == PLANE_PRIMARY; return plane_id == PLANE_PRIMARY;
} }
static struct intel_fbc *skl_plane_fbc(struct drm_i915_private *dev_priv, static struct intel_fbc *skl_plane_fbc(struct drm_i915_private *dev_priv,
enum pipe pipe, enum plane_id plane_id) enum pipe pipe, enum plane_id plane_id)
{ {
if (skl_plane_has_fbc(dev_priv, pipe, plane_id)) enum intel_fbc_id fbc_id = skl_fbc_id_for_pipe(pipe);
return dev_priv->fbc;
if (skl_plane_has_fbc(dev_priv, fbc_id, plane_id))
return dev_priv->fbc[fbc_id];
else else
return NULL; return NULL;
} }
@@ -2282,16 +2303,17 @@ skl_get_initial_plane_config(struct intel_crtc *crtc,
val = intel_de_read(dev_priv, PLANE_CTL(pipe, plane_id)); val = intel_de_read(dev_priv, PLANE_CTL(pipe, plane_id));
if (DISPLAY_VER(dev_priv) >= 11) if (DISPLAY_VER(dev_priv) >= 11)
pixel_format = val & ICL_PLANE_CTL_FORMAT_MASK; pixel_format = val & PLANE_CTL_FORMAT_MASK_ICL;
else else
pixel_format = val & PLANE_CTL_FORMAT_MASK; pixel_format = val & PLANE_CTL_FORMAT_MASK_SKL;
if (DISPLAY_VER(dev_priv) >= 10) { if (DISPLAY_VER(dev_priv) >= 10) {
alpha = intel_de_read(dev_priv, u32 color_ctl;
PLANE_COLOR_CTL(pipe, plane_id));
alpha &= PLANE_COLOR_ALPHA_MASK; color_ctl = intel_de_read(dev_priv, PLANE_COLOR_CTL(pipe, plane_id));
alpha = REG_FIELD_GET(PLANE_COLOR_ALPHA_MASK, color_ctl);
} else { } else {
alpha = val & PLANE_CTL_ALPHA_MASK; alpha = REG_FIELD_GET(PLANE_CTL_ALPHA_MASK, val);
} }
fourcc = skl_format_to_fourcc(pixel_format, fourcc = skl_format_to_fourcc(pixel_format,
@@ -2355,22 +2377,19 @@ skl_get_initial_plane_config(struct intel_crtc *crtc,
if (drm_rotation_90_or_270(plane_config->rotation)) if (drm_rotation_90_or_270(plane_config->rotation))
goto error; goto error;
base = intel_de_read(dev_priv, PLANE_SURF(pipe, plane_id)) & 0xfffff000; base = intel_de_read(dev_priv, PLANE_SURF(pipe, plane_id)) & PLANE_SURF_ADDR_MASK;
plane_config->base = base; plane_config->base = base;
offset = intel_de_read(dev_priv, PLANE_OFFSET(pipe, plane_id)); offset = intel_de_read(dev_priv, PLANE_OFFSET(pipe, plane_id));
val = intel_de_read(dev_priv, PLANE_SIZE(pipe, plane_id)); val = intel_de_read(dev_priv, PLANE_SIZE(pipe, plane_id));
fb->height = ((val >> 16) & 0xffff) + 1; fb->height = REG_FIELD_GET(PLANE_HEIGHT_MASK, val) + 1;
fb->width = ((val >> 0) & 0xffff) + 1; fb->width = REG_FIELD_GET(PLANE_WIDTH_MASK, val) + 1;
val = intel_de_read(dev_priv, PLANE_STRIDE(pipe, plane_id)); val = intel_de_read(dev_priv, PLANE_STRIDE(pipe, plane_id));
stride_mult = skl_plane_stride_mult(fb, 0, DRM_MODE_ROTATE_0); stride_mult = skl_plane_stride_mult(fb, 0, DRM_MODE_ROTATE_0);
if (DISPLAY_VER(dev_priv) >= 13) fb->pitches[0] = REG_FIELD_GET(PLANE_STRIDE__MASK, val) * stride_mult;
fb->pitches[0] = (val & PLANE_STRIDE_MASK_XELPD) * stride_mult;
else
fb->pitches[0] = (val & PLANE_STRIDE_MASK) * stride_mult;
aligned_height = intel_fb_align_height(fb, 0, fb->height); aligned_height = intel_fb_align_height(fb, 0, fb->height);

View File

@@ -74,7 +74,8 @@ static void i915_gem_unmap_dma_buf(struct dma_buf_attachment *attachment,
kfree(sg); kfree(sg);
} }
static int i915_gem_dmabuf_vmap(struct dma_buf *dma_buf, struct dma_buf_map *map) static int i915_gem_dmabuf_vmap(struct dma_buf *dma_buf,
struct iosys_map *map)
{ {
struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf); struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
void *vaddr; void *vaddr;
@@ -83,12 +84,13 @@ static int i915_gem_dmabuf_vmap(struct dma_buf *dma_buf, struct dma_buf_map *map
if (IS_ERR(vaddr)) if (IS_ERR(vaddr))
return PTR_ERR(vaddr); return PTR_ERR(vaddr);
dma_buf_map_set_vaddr(map, vaddr); iosys_map_set_vaddr(map, vaddr);
return 0; return 0;
} }
static void i915_gem_dmabuf_vunmap(struct dma_buf *dma_buf, struct dma_buf_map *map) static void i915_gem_dmabuf_vunmap(struct dma_buf *dma_buf,
struct iosys_map *map)
{ {
struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf); struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);

View File

@@ -23,9 +23,11 @@
#include "pxp/intel_pxp.h" #include "pxp/intel_pxp.h"
#include "i915_cmd_parser.h"
#include "i915_drv.h" #include "i915_drv.h"
#include "i915_gem_clflush.h" #include "i915_gem_clflush.h"
#include "i915_gem_context.h" #include "i915_gem_context.h"
#include "i915_gem_evict.h"
#include "i915_gem_ioctls.h" #include "i915_gem_ioctls.h"
#include "i915_trace.h" #include "i915_trace.h"
#include "i915_user_extensions.h" #include "i915_user_extensions.h"

View File

@@ -14,6 +14,7 @@
#include "gem/i915_gem_region.h" #include "gem/i915_gem_region.h"
#include "i915_drv.h" #include "i915_drv.h"
#include "i915_gem_stolen.h" #include "i915_gem_stolen.h"
#include "i915_reg.h"
#include "i915_vgpu.h" #include "i915_vgpu.h"
/* /*

View File

@@ -12,6 +12,8 @@
#include "i915_gem_ioctls.h" #include "i915_gem_ioctls.h"
#include "i915_gem_mman.h" #include "i915_gem_mman.h"
#include "i915_gem_object.h" #include "i915_gem_object.h"
#include "i915_gem_tiling.h"
#include "i915_reg.h"
/** /**
* DOC: buffer object tiling * DOC: buffer object tiling

View File

@@ -0,0 +1,18 @@
/* SPDX-License-Identifier: MIT */
/*
* Copyright © 2022 Intel Corporation
*/
#ifndef __I915_GEM_TILING_H__
#define __I915_GEM_TILING_H__
#include <linux/types.h>
struct drm_i915_private;
u32 i915_gem_fence_size(struct drm_i915_private *i915, u32 size,
unsigned int tiling, unsigned int stride);
u32 i915_gem_fence_alignment(struct drm_i915_private *i915, u32 size,
unsigned int tiling, unsigned int stride);
#endif /* __I915_GEM_TILING_H__ */

Some files were not shown because too many files have changed in this diff Show More