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)
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCAAdFiEEbSBwaO7dZQkcLOKj+mJfZA7rE8oFAmIChLkACgkQ+mJfZA7r
 E8rDOgf9GdgD5PIqly1zCjfpN0z15KXS6kn6lDlthcZMQ2INpAjfo7sOhpAdcb5h
 ptoKkBxD0p+VlLWTR14+N1/DXV8lvxgdfbee2XHdG2+750eBjcjdYNakDj+lGZJ6
 AVO5pNJRa6WEMd4pesm53CJMHlgSzydRCl66PobHrqqeHahO4VGh4Y9jqoJ3JzvD
 unO1iWrss/i9HvJrefcrUKPGkpb9u59dzsiM9Q3rCNSsPg3ik7Mz1LLPEyHEHyUi
 7vs8ugjN2UiZZELnMJIiCBwHs1xN0O3oS4YkjjTzZXMWc+cvY9mFpGbIWMffYpMY
 qijXJLO8Fh57SN0G6EPaCjNyQbm8Gw==
 =/7VU
 -----END PGP SIGNATURE-----

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
commit e7a09cea64
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
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
=========================

View file

@ -128,15 +128,6 @@ Kernel Functions and Structures Reference
.. kernel-doc:: include/linux/dma-buf.h
:internal:
Buffer Mapping Helpers
~~~~~~~~~~~~~~~~~~~~~~
.. kernel-doc:: include/linux/dma-buf-map.h
:doc: overview
.. kernel-doc:: include/linux/dma-buf-map.h
:internal:
Reservation Objects
-------------------

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
atomic modesetting and GEM vmap support. Historically, generic fbdev emulation
expected the framebuffer in system memory or system-like memory. By employing
struct dma_buf_map, drivers with frambuffers in I/O memory can be supported
struct iosys_map, drivers with frambuffers in I/O memory can be supported
as well.
Contact: Maintainer of the driver you plan to convert
@ -234,7 +234,7 @@ Reimplement functions in drm_fbdev_fb_ops without fbdev
A number of callback functions in drm_fbdev_fb_ops could benefit from
being rewritten without dependencies on the fbdev module. Some of the
helpers could further benefit from using struct dma_buf_map instead of
helpers could further benefit from using struct iosys_map instead of
raw pointers.
Contact: Thomas Zimmermann <tzimmermann@suse.de>, Daniel Vetter
@ -434,19 +434,19 @@ Contact: Emil Velikov, respective driver maintainers
Level: Intermediate
Use struct dma_buf_map throughout codebase
------------------------------------------
Use struct iosys_map throughout codebase
----------------------------------------
Pointers to shared device memory are stored in struct dma_buf_map. Each
Pointers to shared device memory are stored in struct iosys_map. Each
instance knows whether it refers to system or I/O memory. Most of the DRM-wide
interface have been converted to use struct dma_buf_map, but implementations
interface have been converted to use struct iosys_map, but implementations
often still use raw pointers.
The task is to use struct dma_buf_map where it makes sense.
The task is to use struct iosys_map where it makes sense.
* Memory managers should use struct dma_buf_map for dma-buf-imported buffers.
* TTM might benefit from using struct dma_buf_map internally.
* Framebuffer copying and blitting helpers should operate on struct dma_buf_map.
* Memory managers should use struct iosys_map for dma-buf-imported buffers.
* TTM might benefit from using struct iosys_map internally.
* Framebuffer copying and blitting helpers should operate on struct iosys_map.
Contact: Thomas Zimmermann <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: drivers/dma-buf/
F: include/linux/*fence.h
F: include/linux/dma-buf*
F: include/linux/dma-buf.h
F: include/linux/dma-resv.h
K: \bdma_(?:buf|fence|resv)\b
@ -10050,6 +10050,13 @@ F: include/linux/iova.h
F: include/linux/of_iommu.h
F: include/uapi/linux/iommu.h
IOSYS-MAP HELPERS
M: Thomas Zimmermann <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
M: Jens Axboe <axboe@kernel.dk>
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_ADLS_IDS(&gen11_early_ops),
INTEL_ADLP_IDS(&gen11_early_ops),
INTEL_ADLN_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::
*
* void \*dma_buf_vmap(struct dma_buf \*dmabuf, struct dma_buf_map \*map)
* void dma_buf_vunmap(struct dma_buf \*dmabuf, struct dma_buf_map \*map)
* void \*dma_buf_vmap(struct dma_buf \*dmabuf, struct iosys_map \*map)
* void dma_buf_vunmap(struct dma_buf \*dmabuf, struct iosys_map \*map)
*
* The vmap call can fail if there is no vmap support in the exporter, or if
* it runs out of vmalloc space. Note that the dma-buf layer keeps a reference
@ -1260,12 +1260,12 @@ EXPORT_SYMBOL_NS_GPL(dma_buf_mmap, DMA_BUF);
*
* Returns 0 on success, or a negative errno code otherwise.
*/
int dma_buf_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map)
int dma_buf_vmap(struct dma_buf *dmabuf, struct iosys_map *map)
{
struct dma_buf_map ptr;
struct iosys_map ptr;
int ret = 0;
dma_buf_map_clear(map);
iosys_map_clear(map);
if (WARN_ON(!dmabuf))
return -EINVAL;
@ -1276,12 +1276,12 @@ int dma_buf_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map)
mutex_lock(&dmabuf->lock);
if (dmabuf->vmapping_counter) {
dmabuf->vmapping_counter++;
BUG_ON(dma_buf_map_is_null(&dmabuf->vmap_ptr));
BUG_ON(iosys_map_is_null(&dmabuf->vmap_ptr));
*map = dmabuf->vmap_ptr;
goto out_unlock;
}
BUG_ON(dma_buf_map_is_set(&dmabuf->vmap_ptr));
BUG_ON(iosys_map_is_set(&dmabuf->vmap_ptr));
ret = dmabuf->ops->vmap(dmabuf, &ptr);
if (WARN_ON_ONCE(ret))
@ -1303,20 +1303,20 @@ EXPORT_SYMBOL_NS_GPL(dma_buf_vmap, DMA_BUF);
* @dmabuf: [in] buffer to vunmap
* @map: [in] vmap pointer to vunmap
*/
void dma_buf_vunmap(struct dma_buf *dmabuf, struct dma_buf_map *map)
void dma_buf_vunmap(struct dma_buf *dmabuf, struct iosys_map *map)
{
if (WARN_ON(!dmabuf))
return;
BUG_ON(dma_buf_map_is_null(&dmabuf->vmap_ptr));
BUG_ON(iosys_map_is_null(&dmabuf->vmap_ptr));
BUG_ON(dmabuf->vmapping_counter == 0);
BUG_ON(!dma_buf_map_is_equal(&dmabuf->vmap_ptr, map));
BUG_ON(!iosys_map_is_equal(&dmabuf->vmap_ptr, map));
mutex_lock(&dmabuf->lock);
if (--dmabuf->vmapping_counter == 0) {
if (dmabuf->ops->vunmap)
dmabuf->ops->vunmap(dmabuf, map);
dma_buf_map_clear(&dmabuf->vmap_ptr);
iosys_map_clear(&dmabuf->vmap_ptr);
}
mutex_unlock(&dmabuf->lock);
}

View file

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

View file

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

View file

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

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

View file

@ -28,10 +28,10 @@
* 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/highmem.h>
#include <linux/cc_platform.h>
#include <linux/iosys-map.h>
#include <xen/xen.h>
#include <drm/drm_cache.h>
@ -214,14 +214,14 @@ bool drm_need_swiotlb(int dma_bits)
}
EXPORT_SYMBOL(drm_need_swiotlb);
static void memcpy_fallback(struct dma_buf_map *dst,
const struct dma_buf_map *src,
static void memcpy_fallback(struct iosys_map *dst,
const struct iosys_map *src,
unsigned long len)
{
if (!dst->is_iomem && !src->is_iomem) {
memcpy(dst->vaddr, src->vaddr, len);
} else if (!src->is_iomem) {
dma_buf_map_memcpy_to(dst, src->vaddr, len);
iosys_map_memcpy_to(dst, src->vaddr, len);
} else if (!dst->is_iomem) {
memcpy_fromio(dst->vaddr, src->vaddr_iomem, len);
} else {
@ -305,8 +305,8 @@ static void __drm_memcpy_from_wc(void *dst, const void *src, unsigned long len)
* Tries an arch optimized memcpy for prefetching reading out of a WC region,
* and if no such beast is available, falls back to a normal memcpy.
*/
void drm_memcpy_from_wc(struct dma_buf_map *dst,
const struct dma_buf_map *src,
void drm_memcpy_from_wc(struct iosys_map *dst,
const struct iosys_map *src,
unsigned long len)
{
if (WARN_ON(in_interrupt())) {
@ -343,8 +343,8 @@ void drm_memcpy_init_early(void)
static_branch_enable(&has_movntdqa);
}
#else
void drm_memcpy_from_wc(struct dma_buf_map *dst,
const struct dma_buf_map *src,
void drm_memcpy_from_wc(struct iosys_map *dst,
const struct iosys_map *src,
unsigned long len)
{
WARN_ON(in_interrupt());

View file

@ -3,7 +3,7 @@
* Copyright 2018 Noralf Trønnes
*/
#include <linux/dma-buf-map.h>
#include <linux/iosys-map.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/mutex.h>
@ -309,9 +309,10 @@ drm_client_buffer_create(struct drm_client_dev *client, u32 width, u32 height, u
* 0 on success, or a negative errno code otherwise.
*/
int
drm_client_buffer_vmap(struct drm_client_buffer *buffer, struct dma_buf_map *map_copy)
drm_client_buffer_vmap(struct drm_client_buffer *buffer,
struct iosys_map *map_copy)
{
struct dma_buf_map *map = &buffer->map;
struct iosys_map *map = &buffer->map;
int ret;
/*
@ -342,7 +343,7 @@ EXPORT_SYMBOL(drm_client_buffer_vmap);
*/
void drm_client_buffer_vunmap(struct drm_client_buffer *buffer)
{
struct dma_buf_map *map = &buffer->map;
struct iosys_map *map = &buffer->map;
drm_gem_vunmap(buffer->gem, map);
}

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

View file

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

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)
{
struct drm_gem_object *gem_obj = &cma_obj->base;
struct dma_buf_map map = DMA_BUF_MAP_INIT_VADDR(cma_obj->vaddr);
struct iosys_map map = IOSYS_MAP_INIT_VADDR(cma_obj->vaddr);
if (gem_obj->import_attach) {
if (cma_obj->vaddr)
@ -480,9 +480,10 @@ EXPORT_SYMBOL_GPL(drm_gem_cma_prime_import_sg_table);
* Returns:
* 0 on success, or a negative error code otherwise.
*/
int drm_gem_cma_vmap(struct drm_gem_cma_object *cma_obj, struct dma_buf_map *map)
int drm_gem_cma_vmap(struct drm_gem_cma_object *cma_obj,
struct iosys_map *map)
{
dma_buf_map_set_vaddr(map, cma_obj->vaddr);
iosys_map_set_vaddr(map, cma_obj->vaddr);
return 0;
}
@ -557,7 +558,7 @@ drm_gem_cma_prime_import_sg_table_vmap(struct drm_device *dev,
{
struct drm_gem_cma_object *cma_obj;
struct drm_gem_object *obj;
struct dma_buf_map map;
struct iosys_map map;
int ret;
ret = dma_buf_vmap(attach->dmabuf, &map);

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
*
* This function maps all buffer objects of the given framebuffer into
* kernel address space and stores them in struct dma_buf_map. If the
* kernel address space and stores them in struct iosys_map. If the
* mapping operation fails for one of the BOs, the function unmaps the
* already established mappings automatically.
*
@ -335,8 +335,8 @@ EXPORT_SYMBOL_GPL(drm_gem_fb_create_with_dirty);
* 0 on success, or a negative errno code otherwise.
*/
int drm_gem_fb_vmap(struct drm_framebuffer *fb,
struct dma_buf_map map[static DRM_FORMAT_MAX_PLANES],
struct dma_buf_map data[DRM_FORMAT_MAX_PLANES])
struct iosys_map map[static DRM_FORMAT_MAX_PLANES],
struct iosys_map data[DRM_FORMAT_MAX_PLANES])
{
struct drm_gem_object *obj;
unsigned int i;
@ -345,7 +345,7 @@ int drm_gem_fb_vmap(struct drm_framebuffer *fb,
for (i = 0; i < DRM_FORMAT_MAX_PLANES; ++i) {
obj = drm_gem_fb_get_obj(fb, i);
if (!obj) {
dma_buf_map_clear(&map[i]);
iosys_map_clear(&map[i]);
continue;
}
ret = drm_gem_vmap(obj, &map[i]);
@ -356,9 +356,9 @@ int drm_gem_fb_vmap(struct drm_framebuffer *fb,
if (data) {
for (i = 0; i < DRM_FORMAT_MAX_PLANES; ++i) {
memcpy(&data[i], &map[i], sizeof(data[i]));
if (dma_buf_map_is_null(&data[i]))
if (iosys_map_is_null(&data[i]))
continue;
dma_buf_map_incr(&data[i], fb->offsets[i]);
iosys_map_incr(&data[i], fb->offsets[i]);
}
}
@ -386,7 +386,7 @@ EXPORT_SYMBOL(drm_gem_fb_vmap);
* See drm_gem_fb_vmap() for more information.
*/
void drm_gem_fb_vunmap(struct drm_framebuffer *fb,
struct dma_buf_map map[static DRM_FORMAT_MAX_PLANES])
struct iosys_map map[static DRM_FORMAT_MAX_PLANES])
{
unsigned int i = DRM_FORMAT_MAX_PLANES;
struct drm_gem_object *obj;
@ -396,7 +396,7 @@ void drm_gem_fb_vunmap(struct drm_framebuffer *fb,
obj = drm_gem_fb_get_obj(fb, i);
if (!obj)
continue;
if (dma_buf_map_is_null(&map[i]))
if (iosys_map_is_null(&map[i]))
continue;
drm_gem_vunmap(obj, &map[i]);
}

View file

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

View file

@ -61,7 +61,7 @@ EXPORT_SYMBOL(drm_gem_ttm_print_info);
* 0 on success, or a negative errno code otherwise.
*/
int drm_gem_ttm_vmap(struct drm_gem_object *gem,
struct dma_buf_map *map)
struct iosys_map *map)
{
struct ttm_buffer_object *bo = drm_gem_ttm_of_gem(gem);
@ -78,7 +78,7 @@ EXPORT_SYMBOL(drm_gem_ttm_vmap);
* &drm_gem_object_funcs.vmap callback.
*/
void drm_gem_ttm_vunmap(struct drm_gem_object *gem,
struct dma_buf_map *map)
struct iosys_map *map)
{
struct ttm_buffer_object *bo = drm_gem_ttm_of_gem(gem);

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include <linux/dma-buf-map.h>
#include <linux/iosys-map.h>
#include <linux/module.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(dma_buf_map_is_set(&gbo->map));
WARN_ON(iosys_map_is_set(&gbo->map));
drm_gem_object_release(&gbo->bo.base);
}
@ -365,7 +365,7 @@ int drm_gem_vram_unpin(struct drm_gem_vram_object *gbo)
EXPORT_SYMBOL(drm_gem_vram_unpin);
static int drm_gem_vram_kmap_locked(struct drm_gem_vram_object *gbo,
struct dma_buf_map *map)
struct iosys_map *map)
{
int ret;
@ -377,7 +377,7 @@ static int drm_gem_vram_kmap_locked(struct drm_gem_vram_object *gbo,
* page mapping might still be around. Only vmap if the there's
* no mapping present.
*/
if (dma_buf_map_is_null(&gbo->map)) {
if (iosys_map_is_null(&gbo->map)) {
ret = ttm_bo_vmap(&gbo->bo, &gbo->map);
if (ret)
return ret;
@ -391,14 +391,14 @@ static int drm_gem_vram_kmap_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;
if (drm_WARN_ON_ONCE(dev, !gbo->vmap_use_count))
return;
if (drm_WARN_ON_ONCE(dev, !dma_buf_map_is_equal(&gbo->map, map)))
if (drm_WARN_ON_ONCE(dev, !iosys_map_is_equal(&gbo->map, map)))
return; /* BUG: map not mapped from this BO */
if (--gbo->vmap_use_count > 0)
@ -428,7 +428,7 @@ static void drm_gem_vram_kunmap_locked(struct drm_gem_vram_object *gbo,
* Returns:
* 0 on success, or a negative error code otherwise.
*/
int drm_gem_vram_vmap(struct drm_gem_vram_object *gbo, struct dma_buf_map *map)
int drm_gem_vram_vmap(struct drm_gem_vram_object *gbo, struct iosys_map *map)
{
int ret;
@ -463,7 +463,8 @@ EXPORT_SYMBOL(drm_gem_vram_vmap);
* A call to drm_gem_vram_vunmap() unmaps and unpins a GEM VRAM buffer. See
* the documentation for drm_gem_vram_vmap() for more information.
*/
void drm_gem_vram_vunmap(struct drm_gem_vram_object *gbo, struct dma_buf_map *map)
void drm_gem_vram_vunmap(struct drm_gem_vram_object *gbo,
struct iosys_map *map)
{
int ret;
@ -567,7 +568,7 @@ static void drm_gem_vram_bo_driver_move_notify(struct drm_gem_vram_object *gbo)
return;
ttm_bo_vunmap(bo, &gbo->map);
dma_buf_map_clear(&gbo->map); /* explicitly clear mapping for next vmap call */
iosys_map_clear(&gbo->map); /* explicitly clear mapping for next vmap call */
}
static int drm_gem_vram_bo_driver_move(struct drm_gem_vram_object *gbo,
@ -802,7 +803,8 @@ static void drm_gem_vram_object_unpin(struct drm_gem_object *gem)
* Returns:
* 0 on success, or a negative error code otherwise.
*/
static int drm_gem_vram_object_vmap(struct drm_gem_object *gem, struct dma_buf_map *map)
static int drm_gem_vram_object_vmap(struct drm_gem_object *gem,
struct iosys_map *map)
{
struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem);
@ -815,7 +817,8 @@ static int drm_gem_vram_object_vmap(struct drm_gem_object *gem, struct dma_buf_m
* @gem: The GEM object to unmap
* @map: Kernel virtual address where the VRAM GEM object was mapped
*/
static void drm_gem_vram_object_vunmap(struct drm_gem_object *gem, struct dma_buf_map *map)
static void drm_gem_vram_object_vunmap(struct drm_gem_object *gem,
struct iosys_map *map)
{
struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem);

View file

@ -33,7 +33,7 @@
struct dentry;
struct dma_buf;
struct dma_buf_map;
struct iosys_map;
struct drm_connector;
struct drm_crtc;
struct drm_framebuffer;
@ -174,8 +174,8 @@ void drm_gem_print_info(struct drm_printer *p, unsigned int indent,
int drm_gem_pin(struct drm_gem_object *obj);
void drm_gem_unpin(struct drm_gem_object *obj);
int drm_gem_vmap(struct drm_gem_object *obj, struct dma_buf_map *map);
void drm_gem_vunmap(struct drm_gem_object *obj, struct dma_buf_map *map);
int drm_gem_vmap(struct drm_gem_object *obj, struct iosys_map *map);
void drm_gem_vunmap(struct drm_gem_object *obj, struct iosys_map *map);
int drm_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev,
u32 handle);

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

View file

@ -180,6 +180,12 @@ static const struct dmi_system_id orientation_data[] = {
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MicroPC"),
},
.driver_data = (void *)&lcd720x1280_rightside_up,
}, { /* GPD Win Max */
.matches = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "GPD"),
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "G1619-01"),
},
.driver_data = (void *)&lcd800x1280_rightside_up,
}, { /*
* GPD Pocket, note that the the DMI data is less generic then
* it seems, devices with a board-vendor of "AMI Corporation"

View file

@ -674,7 +674,7 @@ EXPORT_SYMBOL(drm_gem_unmap_dma_buf);
*
* Returns 0 on success or a negative errno code otherwise.
*/
int drm_gem_dmabuf_vmap(struct dma_buf *dma_buf, struct dma_buf_map *map)
int drm_gem_dmabuf_vmap(struct dma_buf *dma_buf, struct iosys_map *map)
{
struct drm_gem_object *obj = dma_buf->priv;
@ -690,7 +690,7 @@ EXPORT_SYMBOL(drm_gem_dmabuf_vmap);
* Releases a kernel virtual mapping. This can be used as the
* &dma_buf_ops.vunmap callback. Calls into &drm_gem_object_funcs.vunmap for device specific handling.
*/
void drm_gem_dmabuf_vunmap(struct dma_buf *dma_buf, struct dma_buf_map *map)
void drm_gem_dmabuf_vunmap(struct dma_buf *dma_buf, struct iosys_map *map)
{
struct drm_gem_object *obj = dma_buf->priv;

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

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

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

View file

@ -19,7 +19,7 @@
#include "hyperv_drm.h"
static int hyperv_blit_to_vram_rect(struct drm_framebuffer *fb,
const struct dma_buf_map *map,
const struct iosys_map *map,
struct drm_rect *rect)
{
struct hyperv_drm_device *hv = to_hv(fb->dev);
@ -38,7 +38,8 @@ static int hyperv_blit_to_vram_rect(struct drm_framebuffer *fb,
return 0;
}
static int hyperv_blit_to_vram_fullscreen(struct drm_framebuffer *fb, const struct dma_buf_map *map)
static int hyperv_blit_to_vram_fullscreen(struct drm_framebuffer *fb,
const struct iosys_map *map)
{
struct drm_rect fullscreen = {
.x1 = 0,

View file

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

View file

@ -18,6 +18,7 @@
#include "intel_fifo_underrun.h"
#include "intel_hdmi.h"
#include "intel_hotplug.h"
#include "intel_pch_display.h"
#include "intel_pps.h"
#include "vlv_sideband.h"
@ -333,6 +334,21 @@ static bool intel_dp_get_hw_state(struct intel_encoder *encoder,
return ret;
}
static void g4x_dp_get_m_n(struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
if (crtc_state->has_pch_encoder) {
intel_pch_transcoder_get_m1_n1(crtc, &crtc_state->dp_m_n);
intel_pch_transcoder_get_m2_n2(crtc, &crtc_state->dp_m2_n2);
} else {
intel_cpu_transcoder_get_m1_n1(crtc, crtc_state->cpu_transcoder,
&crtc_state->dp_m_n);
intel_cpu_transcoder_get_m2_n2(crtc, crtc_state->cpu_transcoder,
&crtc_state->dp_m2_n2);
}
}
static void intel_dp_get_config(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config)
{
@ -384,7 +400,7 @@ static void intel_dp_get_config(struct intel_encoder *encoder,
pipe_config->lane_count =
((tmp & DP_PORT_WIDTH_MASK) >> DP_PORT_WIDTH_SHIFT) + 1;
intel_dp_get_m_n(crtc, pipe_config);
g4x_dp_get_m_n(pipe_config);
if (port == PORT_A) {
if ((intel_de_read(dev_priv, DP_A) & DP_PLL_FREQ_MASK) == DP_PLL_FREQ_162MHZ)

View file

@ -8,7 +8,7 @@
#include <linux/types.h>
#include "i915_reg.h"
#include "i915_reg_defs.h"
enum port;
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)
{
if (i9xx_plane_has_fbc(dev_priv, i9xx_plane))
return dev_priv->fbc;
return dev_priv->fbc[INTEL_FBC_A];
else
return NULL;
}
@ -155,51 +155,51 @@ static u32 i9xx_plane_ctl(const struct intel_crtc_state *crtc_state,
unsigned int rotation = plane_state->hw.rotation;
u32 dspcntr;
dspcntr = DISPLAY_PLANE_ENABLE;
dspcntr = DISP_ENABLE;
if (IS_G4X(dev_priv) || IS_IRONLAKE(dev_priv) ||
IS_SANDYBRIDGE(dev_priv) || IS_IVYBRIDGE(dev_priv))
dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
dspcntr |= DISP_TRICKLE_FEED_DISABLE;
switch (fb->format->format) {
case DRM_FORMAT_C8:
dspcntr |= DISPPLANE_8BPP;
dspcntr |= DISP_FORMAT_8BPP;
break;
case DRM_FORMAT_XRGB1555:
dspcntr |= DISPPLANE_BGRX555;
dspcntr |= DISP_FORMAT_BGRX555;
break;
case DRM_FORMAT_ARGB1555:
dspcntr |= DISPPLANE_BGRA555;
dspcntr |= DISP_FORMAT_BGRA555;
break;
case DRM_FORMAT_RGB565:
dspcntr |= DISPPLANE_BGRX565;
dspcntr |= DISP_FORMAT_BGRX565;
break;
case DRM_FORMAT_XRGB8888:
dspcntr |= DISPPLANE_BGRX888;
dspcntr |= DISP_FORMAT_BGRX888;
break;
case DRM_FORMAT_XBGR8888:
dspcntr |= DISPPLANE_RGBX888;
dspcntr |= DISP_FORMAT_RGBX888;
break;
case DRM_FORMAT_ARGB8888:
dspcntr |= DISPPLANE_BGRA888;
dspcntr |= DISP_FORMAT_BGRA888;
break;
case DRM_FORMAT_ABGR8888:
dspcntr |= DISPPLANE_RGBA888;
dspcntr |= DISP_FORMAT_RGBA888;
break;
case DRM_FORMAT_XRGB2101010:
dspcntr |= DISPPLANE_BGRX101010;
dspcntr |= DISP_FORMAT_BGRX101010;
break;
case DRM_FORMAT_XBGR2101010:
dspcntr |= DISPPLANE_RGBX101010;
dspcntr |= DISP_FORMAT_RGBX101010;
break;
case DRM_FORMAT_ARGB2101010:
dspcntr |= DISPPLANE_BGRA101010;
dspcntr |= DISP_FORMAT_BGRA101010;
break;
case DRM_FORMAT_ABGR2101010:
dspcntr |= DISPPLANE_RGBA101010;
dspcntr |= DISP_FORMAT_RGBA101010;
break;
case DRM_FORMAT_XBGR16161616F:
dspcntr |= DISPPLANE_RGBX161616;
dspcntr |= DISP_FORMAT_RGBX161616;
break;
default:
MISSING_CASE(fb->format->format);
@ -208,13 +208,13 @@ static u32 i9xx_plane_ctl(const struct intel_crtc_state *crtc_state,
if (DISPLAY_VER(dev_priv) >= 4 &&
fb->modifier == I915_FORMAT_MOD_X_TILED)
dspcntr |= DISPPLANE_TILED;
dspcntr |= DISP_TILED;
if (rotation & DRM_MODE_ROTATE_180)
dspcntr |= DISPPLANE_ROTATE_180;
dspcntr |= DISP_ROTATE_180;
if (rotation & DRM_MODE_REFLECT_X)
dspcntr |= DISPPLANE_MIRROR;
dspcntr |= DISP_MIRROR;
return dspcntr;
}
@ -354,13 +354,13 @@ static u32 i9xx_plane_ctl_crtc(const struct intel_crtc_state *crtc_state)
u32 dspcntr = 0;
if (crtc_state->gamma_enable)
dspcntr |= DISPPLANE_GAMMA_ENABLE;
dspcntr |= DISP_PIPE_GAMMA_ENABLE;
if (crtc_state->csc_enable)
dspcntr |= DISPPLANE_PIPE_CSC_ENABLE;
dspcntr |= DISP_PIPE_CSC_ENABLE;
if (DISPLAY_VER(dev_priv) < 5)
dspcntr |= DISPPLANE_SEL_PIPE(crtc->pipe);
dspcntr |= DISP_PIPE_SEL(crtc->pipe);
return dspcntr;
}
@ -437,9 +437,9 @@ static void i9xx_plane_update_noarm(struct intel_plane *plane,
* program whatever is there.
*/
intel_de_write_fw(dev_priv, DSPPOS(i9xx_plane),
(crtc_y << 16) | crtc_x);
DISP_POS_Y(crtc_y) | DISP_POS_X(crtc_x));
intel_de_write_fw(dev_priv, DSPSIZE(i9xx_plane),
((crtc_h - 1) << 16) | (crtc_w - 1));
DISP_HEIGHT(crtc_h - 1) | DISP_WIDTH(crtc_w - 1));
}
spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
@ -474,20 +474,20 @@ static void i9xx_plane_update_arm(struct intel_plane *plane,
int crtc_h = drm_rect_height(&plane_state->uapi.dst);
intel_de_write_fw(dev_priv, PRIMPOS(i9xx_plane),
(crtc_y << 16) | crtc_x);
PRIM_POS_Y(crtc_y) | PRIM_POS_X(crtc_x));
intel_de_write_fw(dev_priv, PRIMSIZE(i9xx_plane),
((crtc_h - 1) << 16) | (crtc_w - 1));
PRIM_HEIGHT(crtc_h - 1) | PRIM_WIDTH(crtc_w - 1));
intel_de_write_fw(dev_priv, PRIMCNSTALPHA(i9xx_plane), 0);
}
if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
intel_de_write_fw(dev_priv, DSPOFFSET(i9xx_plane),
(y << 16) | x);
DISP_OFFSET_Y(y) | DISP_OFFSET_X(x));
} else if (DISPLAY_VER(dev_priv) >= 4) {
intel_de_write_fw(dev_priv, DSPLINOFF(i9xx_plane),
linear_offset);
intel_de_write_fw(dev_priv, DSPTILEOFF(i9xx_plane),
(y << 16) | x);
DISP_OFFSET_Y(y) | DISP_OFFSET_X(x));
}
/*
@ -564,7 +564,7 @@ g4x_primary_async_flip(struct intel_plane *plane,
unsigned long irqflags;
if (async_flip)
dspcntr |= DISPPLANE_ASYNC_FLIP;
dspcntr |= DISP_ASYNC_FLIP;
spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
intel_de_write_fw(dev_priv, DSPCNTR(i9xx_plane), dspcntr);
@ -696,13 +696,12 @@ static bool i9xx_plane_get_hw_state(struct intel_plane *plane,
val = intel_de_read(dev_priv, DSPCNTR(i9xx_plane));
ret = val & DISPLAY_PLANE_ENABLE;
ret = val & DISP_ENABLE;
if (DISPLAY_VER(dev_priv) >= 5)
*pipe = plane->pipe;
else
*pipe = (val & DISPPLANE_SEL_PIPE_MASK) >>
DISPPLANE_SEL_PIPE_SHIFT;
*pipe = REG_FIELD_GET(DISP_PIPE_SEL_MASK, val);
intel_display_power_put(dev_priv, power_domain, wakeref);
@ -958,32 +957,32 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
static int i9xx_format_to_fourcc(int format)
{
switch (format) {
case DISPPLANE_8BPP:
case DISP_FORMAT_8BPP:
return DRM_FORMAT_C8;
case DISPPLANE_BGRA555:
case DISP_FORMAT_BGRA555:
return DRM_FORMAT_ARGB1555;
case DISPPLANE_BGRX555:
case DISP_FORMAT_BGRX555:
return DRM_FORMAT_XRGB1555;
case DISPPLANE_BGRX565:
case DISP_FORMAT_BGRX565:
return DRM_FORMAT_RGB565;
default:
case DISPPLANE_BGRX888:
case DISP_FORMAT_BGRX888:
return DRM_FORMAT_XRGB8888;
case DISPPLANE_RGBX888:
case DISP_FORMAT_RGBX888:
return DRM_FORMAT_XBGR8888;
case DISPPLANE_BGRA888:
case DISP_FORMAT_BGRA888:
return DRM_FORMAT_ARGB8888;
case DISPPLANE_RGBA888:
case DISP_FORMAT_RGBA888:
return DRM_FORMAT_ABGR8888;
case DISPPLANE_BGRX101010:
case DISP_FORMAT_BGRX101010:
return DRM_FORMAT_XRGB2101010;
case DISPPLANE_RGBX101010:
case DISP_FORMAT_RGBX101010:
return DRM_FORMAT_XBGR2101010;
case DISPPLANE_BGRA101010:
case DISP_FORMAT_BGRA101010:
return DRM_FORMAT_ARGB2101010;
case DISPPLANE_RGBA101010:
case DISP_FORMAT_RGBA101010:
return DRM_FORMAT_ABGR2101010;
case DISPPLANE_RGBX161616:
case DISP_FORMAT_RGBX161616:
return DRM_FORMAT_XBGR16161616F;
}
}
@ -1021,26 +1020,26 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
val = intel_de_read(dev_priv, DSPCNTR(i9xx_plane));
if (DISPLAY_VER(dev_priv) >= 4) {
if (val & DISPPLANE_TILED) {
if (val & DISP_TILED) {
plane_config->tiling = I915_TILING_X;
fb->modifier = I915_FORMAT_MOD_X_TILED;
}
if (val & DISPPLANE_ROTATE_180)
if (val & DISP_ROTATE_180)
plane_config->rotation = DRM_MODE_ROTATE_180;
}
if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B &&
val & DISPPLANE_MIRROR)
val & DISP_MIRROR)
plane_config->rotation |= DRM_MODE_REFLECT_X;
pixel_format = val & DISPPLANE_PIXFORMAT_MASK;
pixel_format = val & DISP_FORMAT_MASK;
fourcc = i9xx_format_to_fourcc(pixel_format);
fb->format = drm_format_info(fourcc);
if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
offset = intel_de_read(dev_priv, DSPOFFSET(i9xx_plane));
base = intel_de_read(dev_priv, DSPSURF(i9xx_plane)) & 0xfffff000;
base = intel_de_read(dev_priv, DSPSURF(i9xx_plane)) & DISP_ADDR_MASK;
} else if (DISPLAY_VER(dev_priv) >= 4) {
if (plane_config->tiling)
offset = intel_de_read(dev_priv,
@ -1048,15 +1047,15 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
else
offset = intel_de_read(dev_priv,
DSPLINOFF(i9xx_plane));
base = intel_de_read(dev_priv, DSPSURF(i9xx_plane)) & 0xfffff000;
base = intel_de_read(dev_priv, DSPSURF(i9xx_plane)) & DISP_ADDR_MASK;
} else {
base = intel_de_read(dev_priv, DSPADDR(i9xx_plane));
}
plane_config->base = base;
val = intel_de_read(dev_priv, PIPESRC(pipe));
fb->width = ((val >> 16) & 0xfff) + 1;
fb->height = ((val >> 0) & 0xfff) + 1;
fb->width = REG_FIELD_GET(PIPESRC_WIDTH_MASK, val) + 1;
fb->height = REG_FIELD_GET(PIPESRC_HEIGHT_MASK, val) + 1;
val = intel_de_read(dev_priv, DSPSTRIDE(i9xx_plane));
fb->pitches[0] = val & 0xffffffc0;

View file

@ -32,6 +32,7 @@
#include "intel_atomic.h"
#include "intel_backlight.h"
#include "intel_combo_phy.h"
#include "intel_combo_phy_regs.h"
#include "intel_connector.h"
#include "intel_crtc.h"
#include "intel_ddi.h"
@ -1050,7 +1051,7 @@ static void gen11_dsi_enable_transcoder(struct intel_encoder *encoder)
/* wait for transcoder to be enabled */
if (intel_de_wait_for_set(dev_priv, PIPECONF(dsi_trans),
I965_PIPECONF_ACTIVE, 10))
PIPECONF_STATE_ENABLE, 10))
drm_err(&dev_priv->drm,
"DSI transcoder not enabled\n");
}
@ -1232,8 +1233,6 @@ static void gen11_dsi_pre_enable(struct intel_atomic_state *state,
intel_dsc_dsi_pps_write(encoder, pipe_config);
intel_dsc_enable(pipe_config);
/* step6c: configure transcoder timings */
gen11_dsi_set_transcoder_timings(encoder, pipe_config);
}
@ -1320,7 +1319,7 @@ static void gen11_dsi_disable_transcoder(struct intel_encoder *encoder)
/* wait for transcoder to be disabled */
if (intel_de_wait_for_clear(dev_priv, PIPECONF(dsi_trans),
I965_PIPECONF_ACTIVE, 50))
PIPECONF_STATE_ENABLE, 50))
drm_err(&dev_priv->drm,
"DSI trancoder not disabled\n");
}

View file

@ -34,6 +34,8 @@
#include <drm/drm_fourcc.h>
#include <drm/drm_plane_helper.h>
#include "i915_drv.h"
#include "i915_reg.h"
#include "intel_atomic.h"
#include "intel_cdclk.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->dpt_vma = NULL;
intel_state->flags = 0;
intel_state->do_async_flip = false;
/* add reference to fb */
if (intel_state->hw.fb)
@ -491,7 +492,7 @@ void intel_plane_update_arm(struct intel_plane *plane,
trace_intel_plane_update_arm(&plane->base, crtc);
if (crtc_state->uapi.async_flip && plane->async_flip)
if (plane_state->do_async_flip)
plane->async_flip(plane, crtc_state, plane_state, true);
else
plane->update_arm(plane, crtc_state, plane_state);
@ -601,6 +602,7 @@ int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state,
int min_scale, int max_scale,
bool can_position)
{
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
struct drm_framebuffer *fb = plane_state->hw.fb;
struct drm_rect *src = &plane_state->uapi.src;
struct drm_rect *dst = &plane_state->uapi.dst;
@ -619,7 +621,7 @@ int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state,
hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
if (hscale < 0 || vscale < 0) {
DRM_DEBUG_KMS("Invalid scaling of plane\n");
drm_dbg_kms(&i915->drm, "Invalid scaling of plane\n");
drm_rect_debug_print("src: ", src, true);
drm_rect_debug_print("dst: ", dst, false);
return -ERANGE;
@ -644,7 +646,7 @@ int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state,
if (!can_position && plane_state->uapi.visible &&
!drm_rect_equals(dst, &clip)) {
DRM_DEBUG_KMS("Plane must cover entire CRTC\n");
drm_dbg_kms(&i915->drm, "Plane must cover entire CRTC\n");
drm_rect_debug_print("dst: ", dst, false);
drm_rect_debug_print("clip: ", &clip, false);
return -EINVAL;

View file

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

View file

@ -13,6 +13,7 @@
#include "intel_dp_aux_backlight.h"
#include "intel_dsi_dcs_backlight.h"
#include "intel_panel.h"
#include "intel_pci_config.h"
/**
* scale - scale values from one range to another
@ -433,6 +434,8 @@ static void ext_pwm_disable_backlight(const struct drm_connector_state *old_conn
struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
struct intel_panel *panel = &connector->panel;
intel_backlight_set_pwm_level(old_conn_state, level);
panel->backlight.pwm_state.enabled = false;
pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state);
}

View file

@ -32,6 +32,7 @@
#include "display/intel_gmbus.h"
#include "i915_drv.h"
#include "i915_reg.h"
#define _INTEL_BIOS_PRIVATE
#include "intel_vbt_defs.h"
@ -905,26 +906,6 @@ parse_psr(struct drm_i915_private *i915, const struct bdb_header *bdb)
i915->vbt.psr.idle_frames = psr_table->idle_frames < 0 ? 0 :
psr_table->idle_frames > 15 ? 15 : psr_table->idle_frames;
switch (psr_table->lines_to_wait) {
case 0:
i915->vbt.psr.lines_to_wait = PSR_0_LINES_TO_WAIT;
break;
case 1:
i915->vbt.psr.lines_to_wait = PSR_1_LINE_TO_WAIT;
break;
case 2:
i915->vbt.psr.lines_to_wait = PSR_4_LINES_TO_WAIT;
break;
case 3:
i915->vbt.psr.lines_to_wait = PSR_8_LINES_TO_WAIT;
break;
default:
drm_dbg_kms(&i915->drm,
"VBT has unknown PSR lines to wait %u\n",
psr_table->lines_to_wait);
break;
}
/*
* New psr options 0=500us, 1=100us, 2=2500us, 3=0us
* Old decimal value is wake up time in multiples of 100 us.
@ -2073,14 +2054,16 @@ static void parse_ddi_port(struct drm_i915_private *i915,
i915->vbt.ports[port] = devdata;
}
static bool has_ddi_port_info(struct drm_i915_private *i915)
{
return DISPLAY_VER(i915) >= 5 || IS_G4X(i915);
}
static void parse_ddi_ports(struct drm_i915_private *i915)
{
struct intel_bios_encoder_data *devdata;
if (!HAS_DDI(i915) && !IS_CHERRYVIEW(i915))
return;
if (i915->vbt.version < 155)
if (!has_ddi_port_info(i915))
return;
list_for_each_entry(devdata, &i915->vbt.display_devices, node)
@ -2335,6 +2318,63 @@ bool intel_bios_is_valid_vbt(const void *buf, size_t size)
return vbt;
}
static struct vbt_header *spi_oprom_get_vbt(struct drm_i915_private *i915)
{
u32 count, data, found, store = 0;
u32 static_region, oprom_offset;
u32 oprom_size = 0x200000;
u16 vbt_size;
u32 *vbt;
static_region = intel_uncore_read(&i915->uncore, SPI_STATIC_REGIONS);
static_region &= OPTIONROM_SPI_REGIONID_MASK;
intel_uncore_write(&i915->uncore, PRIMARY_SPI_REGIONID, static_region);
oprom_offset = intel_uncore_read(&i915->uncore, OROM_OFFSET);
oprom_offset &= OROM_OFFSET_MASK;
for (count = 0; count < oprom_size; count += 4) {
intel_uncore_write(&i915->uncore, PRIMARY_SPI_ADDRESS, oprom_offset + count);
data = intel_uncore_read(&i915->uncore, PRIMARY_SPI_TRIGGER);
if (data == *((const u32 *)"$VBT")) {
found = oprom_offset + count;
break;
}
}
if (count >= oprom_size)
goto err_not_found;
/* Get VBT size and allocate space for the VBT */
intel_uncore_write(&i915->uncore, PRIMARY_SPI_ADDRESS, found +
offsetof(struct vbt_header, vbt_size));
vbt_size = intel_uncore_read(&i915->uncore, PRIMARY_SPI_TRIGGER);
vbt_size &= 0xffff;
vbt = kzalloc(round_up(vbt_size, 4), GFP_KERNEL);
if (!vbt)
goto err_not_found;
for (count = 0; count < vbt_size; count += 4) {
intel_uncore_write(&i915->uncore, PRIMARY_SPI_ADDRESS, found + count);
data = intel_uncore_read(&i915->uncore, PRIMARY_SPI_TRIGGER);
*(vbt + store++) = data;
}
if (!intel_bios_is_valid_vbt(vbt, vbt_size))
goto err_free_vbt;
drm_dbg_kms(&i915->drm, "Found valid VBT in SPI flash\n");
return (struct vbt_header *)vbt;
err_free_vbt:
kfree(vbt);
err_not_found:
return NULL;
}
static struct vbt_header *oprom_get_vbt(struct drm_i915_private *i915)
{
struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
@ -2384,6 +2424,8 @@ static struct vbt_header *oprom_get_vbt(struct drm_i915_private *i915)
pci_unmap_rom(pdev, oprom);
drm_dbg_kms(&i915->drm, "Found valid VBT in PCI ROM\n");
return vbt;
err_free_vbt:
@ -2418,17 +2460,23 @@ void intel_bios_init(struct drm_i915_private *i915)
init_vbt_defaults(i915);
/* If the OpRegion does not have VBT, look in PCI ROM. */
/*
* If the OpRegion does not have VBT, look in SPI flash through MMIO or
* PCI mapping
*/
if (!vbt && IS_DGFX(i915)) {
oprom_vbt = spi_oprom_get_vbt(i915);
vbt = oprom_vbt;
}
if (!vbt) {
oprom_vbt = oprom_get_vbt(i915);
if (!oprom_vbt)
goto out;
vbt = oprom_vbt;
drm_dbg_kms(&i915->drm, "Found valid VBT in PCI ROM\n");
}
if (!vbt)
goto out;
bdb = get_bdb_header(vbt);
i915->vbt.version = bdb->version;
@ -2596,37 +2644,10 @@ bool intel_bios_is_lvds_present(struct drm_i915_private *i915, u8 *i2c_pin)
*/
bool intel_bios_is_port_present(struct drm_i915_private *i915, enum port port)
{
const struct intel_bios_encoder_data *devdata;
const struct child_device_config *child;
static const struct {
u16 dp, hdmi;
} port_mapping[] = {
[PORT_B] = { DVO_PORT_DPB, DVO_PORT_HDMIB, },
[PORT_C] = { DVO_PORT_DPC, DVO_PORT_HDMIC, },
[PORT_D] = { DVO_PORT_DPD, DVO_PORT_HDMID, },
[PORT_E] = { DVO_PORT_DPE, DVO_PORT_HDMIE, },
[PORT_F] = { DVO_PORT_DPF, DVO_PORT_HDMIF, },
};
if (WARN_ON(!has_ddi_port_info(i915)))
return true;
if (HAS_DDI(i915))
return i915->vbt.ports[port];
/* FIXME maybe deal with port A as well? */
if (drm_WARN_ON(&i915->drm,
port == PORT_A) || port >= ARRAY_SIZE(port_mapping))
return false;
list_for_each_entry(devdata, &i915->vbt.display_devices, node) {
child = &devdata->child;
if ((child->dvo_port == port_mapping[port].dp ||
child->dvo_port == port_mapping[port].hdmi) &&
(child->device_type & (DEVICE_TYPE_TMDS_DVI_SIGNALING |
DEVICE_TYPE_DISPLAYPORT_OUTPUT)))
return true;
}
return false;
return i915->vbt.ports[port];
}
/**
@ -2638,40 +2659,18 @@ bool intel_bios_is_port_present(struct drm_i915_private *i915, enum port port)
*/
bool intel_bios_is_port_edp(struct drm_i915_private *i915, enum port port)
{
const struct intel_bios_encoder_data *devdata;
const struct child_device_config *child;
static const short port_mapping[] = {
[PORT_B] = DVO_PORT_DPB,
[PORT_C] = DVO_PORT_DPC,
[PORT_D] = DVO_PORT_DPD,
[PORT_E] = DVO_PORT_DPE,
[PORT_F] = DVO_PORT_DPF,
};
const struct intel_bios_encoder_data *devdata =
intel_bios_encoder_data_lookup(i915, port);
if (HAS_DDI(i915)) {
const struct intel_bios_encoder_data *devdata;
devdata = intel_bios_encoder_data_lookup(i915, port);
return devdata && intel_bios_encoder_supports_edp(devdata);
}
list_for_each_entry(devdata, &i915->vbt.display_devices, node) {
child = &devdata->child;
if (child->dvo_port == port_mapping[port] &&
(child->device_type & DEVICE_TYPE_eDP_BITS) ==
(DEVICE_TYPE_eDP & DEVICE_TYPE_eDP_BITS))
return true;
}
return false;
return devdata && intel_bios_encoder_supports_edp(devdata);
}
static bool child_dev_is_dp_dual_mode(const struct child_device_config *child)
static bool intel_bios_encoder_supports_dp_dual_mode(const struct intel_bios_encoder_data *devdata)
{
if ((child->device_type & DEVICE_TYPE_DP_DUAL_MODE_BITS) !=
(DEVICE_TYPE_DP_DUAL_MODE & DEVICE_TYPE_DP_DUAL_MODE_BITS))
const struct child_device_config *child = &devdata->child;
if (!intel_bios_encoder_supports_dp(devdata) ||
!intel_bios_encoder_supports_hdmi(devdata))
return false;
if (dvo_port_type(child->dvo_port) == DVO_PORT_DPA)
@ -2688,40 +2687,10 @@ static bool child_dev_is_dp_dual_mode(const struct child_device_config *child)
bool intel_bios_is_port_dp_dual_mode(struct drm_i915_private *i915,
enum port port)
{
static const struct {
u16 dp, hdmi;
} port_mapping[] = {
/*
* Buggy VBTs may declare DP ports as having
* HDMI type dvo_port :( So let's check both.
*/
[PORT_B] = { DVO_PORT_DPB, DVO_PORT_HDMIB, },
[PORT_C] = { DVO_PORT_DPC, DVO_PORT_HDMIC, },
[PORT_D] = { DVO_PORT_DPD, DVO_PORT_HDMID, },
[PORT_E] = { DVO_PORT_DPE, DVO_PORT_HDMIE, },
[PORT_F] = { DVO_PORT_DPF, DVO_PORT_HDMIF, },
};
const struct intel_bios_encoder_data *devdata;
const struct intel_bios_encoder_data *devdata =
intel_bios_encoder_data_lookup(i915, port);
if (HAS_DDI(i915)) {
const struct intel_bios_encoder_data *devdata;
devdata = intel_bios_encoder_data_lookup(i915, port);
return devdata && child_dev_is_dp_dual_mode(&devdata->child);
}
if (port == PORT_A || port >= ARRAY_SIZE(port_mapping))
return false;
list_for_each_entry(devdata, &i915->vbt.display_devices, node) {
if ((devdata->child.dvo_port == port_mapping[port].dp ||
devdata->child.dvo_port == port_mapping[port].hdmi) &&
child_dev_is_dp_dual_mode(&devdata->child))
return true;
}
return false;
return devdata && intel_bios_encoder_supports_dp_dual_mode(devdata);
}
/**

View file

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

View file

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

View file

@ -8,7 +8,6 @@
#include <linux/types.h>
#include "i915_drv.h"
#include "intel_display.h"
#include "intel_global_state.h"
@ -16,6 +15,11 @@ struct drm_i915_private;
struct intel_atomic_state;
struct intel_crtc_state;
struct intel_cdclk_config {
unsigned int cdclk, vco, ref, bypass;
u8 voltage_level;
};
struct intel_cdclk_state {
struct intel_global_state base;
@ -58,7 +62,8 @@ bool intel_cdclk_needs_modeset(const struct intel_cdclk_config *a,
const struct intel_cdclk_config *b);
void intel_set_cdclk_pre_plane_update(struct intel_atomic_state *state);
void intel_set_cdclk_post_plane_update(struct intel_atomic_state *state);
void intel_dump_cdclk_config(const struct intel_cdclk_config *cdclk_config,
void intel_cdclk_dump_config(struct drm_i915_private *i915,
const struct intel_cdclk_config *cdclk_config,
const char *context);
int intel_modeset_calc_cdclk(struct intel_atomic_state *state);
void intel_cdclk_get_cdclk(struct drm_i915_private *dev_priv,

View file

@ -4,6 +4,7 @@
*/
#include "intel_combo_phy.h"
#include "intel_combo_phy_regs.h"
#include "intel_de.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__
#define __INTEL_CRT_H__
#include "i915_reg.h"
#include "i915_reg_defs.h"
enum pipe;
struct drm_encoder;

View file

@ -12,6 +12,7 @@
#include <drm/drm_plane_helper.h>
#include <drm/drm_vblank_work.h>
#include "i915_irq.h"
#include "i915_vgpu.h"
#include "i9xx_plane.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;
if (x < 0) {
pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT;
pos |= CURSOR_POS_X_SIGN;
x = -x;
}
pos |= x << CURSOR_X_SHIFT;
pos |= CURSOR_POS_X(x);
if (y < 0) {
pos |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT;
pos |= CURSOR_POS_Y_SIGN;
y = -y;
}
pos |= y << CURSOR_Y_SHIFT;
pos |= CURSOR_POS_Y(y);
return pos;
}
@ -180,7 +180,7 @@ static u32 i845_cursor_ctl_crtc(const struct intel_crtc_state *crtc_state)
u32 cntl = 0;
if (crtc_state->gamma_enable)
cntl |= CURSOR_GAMMA_ENABLE;
cntl |= CURSOR_PIPE_GAMMA_ENABLE;
return cntl;
}
@ -264,7 +264,7 @@ static void i845_cursor_update_arm(struct intel_plane *plane,
cntl = plane_state->ctl |
i845_cursor_ctl_crtc(crtc_state);
size = (height << 12) | width;
size = CURSOR_HEIGHT(height) | CURSOR_WIDTH(width);
base = intel_cursor_base(plane_state);
pos = intel_cursor_position(plane_state);
@ -280,7 +280,7 @@ static void i845_cursor_update_arm(struct intel_plane *plane,
plane->cursor.cntl != cntl) {
intel_de_write_fw(dev_priv, CURCNTR(PIPE_A), 0);
intel_de_write_fw(dev_priv, CURBASE(PIPE_A), base);
intel_de_write_fw(dev_priv, CURSIZE, size);
intel_de_write_fw(dev_priv, CURSIZE(PIPE_A), size);
intel_de_write_fw(dev_priv, CURPOS(PIPE_A), pos);
intel_de_write_fw(dev_priv, CURCNTR(PIPE_A), cntl);
@ -340,13 +340,13 @@ static u32 i9xx_cursor_ctl_crtc(const struct intel_crtc_state *crtc_state)
return cntl;
if (crtc_state->gamma_enable)
cntl = MCURSOR_GAMMA_ENABLE;
cntl = MCURSOR_PIPE_GAMMA_ENABLE;
if (crtc_state->csc_enable)
cntl |= MCURSOR_PIPE_CSC_ENABLE;
if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv))
cntl |= MCURSOR_PIPE_SELECT(crtc->pipe);
cntl |= MCURSOR_PIPE_SEL(crtc->pipe);
return cntl;
}
@ -502,7 +502,7 @@ static void i9xx_cursor_update_arm(struct intel_plane *plane,
i9xx_cursor_ctl_crtc(crtc_state);
if (width != height)
fbc_ctl = CUR_FBC_CTL_EN | (height - 1);
fbc_ctl = CUR_FBC_EN | CUR_FBC_HEIGHT(height - 1);
base = intel_cursor_base(plane_state);
pos = intel_cursor_position(plane_state);
@ -586,13 +586,12 @@ static bool i9xx_cursor_get_hw_state(struct intel_plane *plane,
val = intel_de_read(dev_priv, CURCNTR(plane->pipe));
ret = val & MCURSOR_MODE;
ret = val & MCURSOR_MODE_MASK;
if (DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv))
*pipe = plane->pipe;
else
*pipe = (val & MCURSOR_PIPE_SELECT_MASK) >>
MCURSOR_PIPE_SELECT_SHIFT;
*pipe = REG_FIELD_GET(MCURSOR_PIPE_SEL_MASK, val);
intel_display_power_put(dev_priv, power_domain, wakeref);

View file

@ -32,6 +32,7 @@
#include "intel_audio.h"
#include "intel_backlight.h"
#include "intel_combo_phy.h"
#include "intel_combo_phy_regs.h"
#include "intel_connector.h"
#include "intel_crtc.h"
#include "intel_ddi.h"
@ -56,6 +57,7 @@
#include "intel_snps_phy.h"
#include "intel_sprite.h"
#include "intel_tc.h"
#include "intel_tc_phy_regs.h"
#include "intel_vdsc.h"
#include "intel_vrr.h"
#include "skl_scaler.h"
@ -2287,116 +2289,6 @@ static void intel_ddi_mso_configure(const struct intel_crtc_state *crtc_state)
OVERLAP_PIXELS_MASK, dss1);
}
static void dg2_ddi_pre_enable_dp(struct intel_atomic_state *state,
struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state)
{
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST);
intel_dp_set_link_params(intel_dp, crtc_state->port_clock,
crtc_state->lane_count);
/*
* We only configure what the register value will be here. Actual
* enabling happens during link training farther down.
*/
intel_ddi_init_dp_buf_reg(encoder, crtc_state);
/*
* 1. Enable Power Wells
*
* This was handled at the beginning of intel_atomic_commit_tail(),
* before we called down into this function.
*/
/* 2. Enable Panel Power if PPS is required */
intel_pps_on(intel_dp);
/*
* 3. Enable the port PLL.
*/
intel_ddi_enable_clock(encoder, crtc_state);
/* 4. Enable IO power */
if (!intel_tc_port_in_tbt_alt_mode(dig_port))
dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv,
dig_port->ddi_io_power_domain);
/*
* 5. The rest of the below are substeps under the bspec's "Enable and
* Train Display Port" step. Note that steps that are specific to
* MST will be handled by intel_mst_pre_enable_dp() before/after it
* calls into this function. Also intel_mst_pre_enable_dp() only calls
* us when active_mst_links==0, so any steps designated for "single
* stream or multi-stream master transcoder" can just be performed
* unconditionally here.
*/
/*
* 5.a Configure Transcoder Clock Select to direct the Port clock to the
* Transcoder.
*/
intel_ddi_enable_pipe_clock(encoder, crtc_state);
/* 5.b Configure transcoder for DP 2.0 128b/132b */
intel_ddi_config_transcoder_dp2(encoder, crtc_state);
/*
* 5.c Configure TRANS_DDI_FUNC_CTL DDI Select, DDI Mode Select & MST
* Transport Select
*/
intel_ddi_config_transcoder_func(encoder, crtc_state);
/*
* 5.d Configure & enable DP_TP_CTL with link training pattern 1
* selected
*
* This will be handled by the intel_dp_start_link_train() farther
* down this function.
*/
/* 5.e Configure voltage swing and related IO settings */
encoder->set_signal_levels(encoder, crtc_state);
if (!is_mst)
intel_dp_set_power(intel_dp, DP_SET_POWER_D0);
intel_dp_configure_protocol_converter(intel_dp, crtc_state);
intel_dp_sink_set_decompression_state(intel_dp, crtc_state, true);
/*
* DDI FEC: "anticipates enabling FEC encoding sets the FEC_READY bit
* in the FEC_CONFIGURATION register to 1 before initiating link
* training
*/
intel_dp_sink_set_fec_ready(intel_dp, crtc_state);
intel_dp_check_frl_training(intel_dp);
intel_dp_pcon_dsc_configure(intel_dp, crtc_state);
/*
* 5.h Follow DisplayPort specification training sequence (see notes for
* failure handling)
* 5.i If DisplayPort multi-stream - Set DP_TP_CTL link training to Idle
* Pattern, wait for 5 idle patterns (DP_TP_STATUS Min_Idles_Sent)
* (timeout after 800 us)
*/
intel_dp_start_link_train(intel_dp, crtc_state);
/* 5.j Set DP_TP_CTL link training to Normal */
if (!is_trans_port_sync_mode(crtc_state))
intel_dp_stop_link_train(intel_dp, crtc_state);
/* 5.k Configure and enable FEC if needed */
intel_ddi_enable_fec(encoder, crtc_state);
intel_dsc_dp_pps_write(encoder, crtc_state);
intel_dsc_enable(crtc_state);
}
static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
@ -2470,6 +2362,9 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
*/
intel_ddi_enable_pipe_clock(encoder, crtc_state);
if (HAS_DP20(dev_priv))
intel_ddi_config_transcoder_dp2(encoder, crtc_state);
/*
* 7.b Configure TRANS_DDI_FUNC_CTL DDI Select, DDI Mode Select & MST
* Transport Select
@ -2530,9 +2425,6 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
intel_ddi_enable_fec(encoder, crtc_state);
intel_dsc_dp_pps_write(encoder, crtc_state);
if (!crtc_state->bigjoiner)
intel_dsc_enable(crtc_state);
}
static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
@ -2598,9 +2490,6 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
intel_ddi_enable_pipe_clock(encoder, crtc_state);
intel_dsc_dp_pps_write(encoder, crtc_state);
if (!crtc_state->bigjoiner)
intel_dsc_enable(crtc_state);
}
static void intel_ddi_pre_enable_dp(struct intel_atomic_state *state,
@ -2610,9 +2499,7 @@ static void intel_ddi_pre_enable_dp(struct intel_atomic_state *state,
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
if (IS_DG2(dev_priv))
dg2_ddi_pre_enable_dp(state, encoder, crtc_state, conn_state);
else if (DISPLAY_VER(dev_priv) >= 12)
if (DISPLAY_VER(dev_priv) >= 12)
tgl_ddi_pre_enable_dp(state, encoder, crtc_state, conn_state);
else
hsw_ddi_pre_enable_dp(state, encoder, crtc_state, conn_state);
@ -2620,11 +2507,8 @@ static void intel_ddi_pre_enable_dp(struct intel_atomic_state *state,
/* MST will call a setting of MSA after an allocating of Virtual Channel
* from MST encoder pre_enable callback.
*/
if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) {
if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST))
intel_ddi_set_dp_msa(crtc_state, conn_state);
intel_dp_set_m_n(crtc_state, M1_N1);
}
}
static void intel_ddi_pre_enable_hdmi(struct intel_atomic_state *state,
@ -3471,7 +3355,11 @@ static void intel_ddi_read_func_ctl(struct intel_encoder *encoder,
pipe_config->output_types |= BIT(INTEL_OUTPUT_DP);
pipe_config->lane_count =
((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
intel_dp_get_m_n(crtc, pipe_config);
intel_cpu_transcoder_get_m1_n1(crtc, cpu_transcoder,
&pipe_config->dp_m_n);
intel_cpu_transcoder_get_m2_n2(crtc, cpu_transcoder,
&pipe_config->dp_m2_n2);
if (DISPLAY_VER(dev_priv) >= 11) {
i915_reg_t dp_tp_ctl = dp_tp_ctl_reg(encoder, pipe_config);
@ -3508,7 +3396,8 @@ static void intel_ddi_read_func_ctl(struct intel_encoder *encoder,
pipe_config->mst_master_transcoder =
REG_FIELD_GET(TRANS_DDI_MST_TRANSPORT_SELECT_MASK, temp);
intel_dp_get_m_n(crtc, pipe_config);
intel_cpu_transcoder_get_m1_n1(crtc, cpu_transcoder,
&pipe_config->dp_m_n);
pipe_config->infoframes.enable |=
intel_hdmi_infoframes_enabled(encoder, pipe_config);
@ -3797,8 +3686,8 @@ static bool m_n_equal(const struct intel_link_m_n *m_n_1,
const struct intel_link_m_n *m_n_2)
{
return m_n_1->tu == m_n_2->tu &&
m_n_1->gmch_m == m_n_2->gmch_m &&
m_n_1->gmch_n == m_n_2->gmch_n &&
m_n_1->data_m == m_n_2->data_m &&
m_n_1->data_n == m_n_2->data_n &&
m_n_1->link_m == m_n_2->link_m &&
m_n_1->link_n == m_n_2->link_n;
}

View file

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

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

View file

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

File diff suppressed because it is too large Load diff

View file

@ -27,7 +27,8 @@
#include <drm/drm_util.h>
enum link_m_n_set;
#include "i915_reg_defs.h"
enum drm_scaling_filter;
struct dpll;
struct drm_connector;
@ -317,8 +318,8 @@ enum aux_ch {
/* Used by dp and fdi links */
struct intel_link_m_n {
u32 tu;
u32 gmch_m;
u32 gmch_n;
u32 data_m;
u32 data_n;
u32 link_m;
u32 link_n;
};
@ -605,12 +606,29 @@ bool intel_fuzzy_clock_check(int clock1, int clock2);
void intel_display_prepare_reset(struct drm_i915_private *dev_priv);
void intel_display_finish_reset(struct drm_i915_private *dev_priv);
void intel_dp_get_m_n(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config);
void intel_dp_set_m_n(const struct intel_crtc_state *crtc_state,
enum link_m_n_set m_n);
void ilk_get_fdi_m_n_config(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config);
void intel_zero_m_n(struct intel_link_m_n *m_n);
void intel_set_m_n(struct drm_i915_private *i915,
const struct intel_link_m_n *m_n,
i915_reg_t data_m_reg, i915_reg_t data_n_reg,
i915_reg_t link_m_reg, i915_reg_t link_n_reg);
void intel_get_m_n(struct drm_i915_private *i915,
struct intel_link_m_n *m_n,
i915_reg_t data_m_reg, i915_reg_t data_n_reg,
i915_reg_t link_m_reg, i915_reg_t link_n_reg);
bool intel_cpu_transcoder_has_m2_n2(struct drm_i915_private *dev_priv,
enum transcoder transcoder);
void intel_cpu_transcoder_set_m1_n1(struct intel_crtc *crtc,
enum transcoder cpu_transcoder,
const struct intel_link_m_n *m_n);
void intel_cpu_transcoder_set_m2_n2(struct intel_crtc *crtc,
enum transcoder cpu_transcoder,
const struct intel_link_m_n *m_n);
void intel_cpu_transcoder_get_m1_n1(struct intel_crtc *crtc,
enum transcoder cpu_transcoder,
struct intel_link_m_n *m_n);
void intel_cpu_transcoder_get_m2_n2(struct intel_crtc *crtc,
enum transcoder cpu_transcoder,
struct intel_link_m_n *m_n);
void i9xx_crtc_clock_get(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config);
int intel_dotclock_calculate(int link_freq, const struct intel_link_m_n *m_n);

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)
{
if (crtc->debugfs_entry)
crtc_updates_add(crtc);
if (!crtc->debugfs_entry)
return;
crtc_updates_add(crtc);
intel_fbc_crtc_debugfs_add(to_intel_crtc(crtc));
}

View file

@ -7,6 +7,7 @@
#include "i915_irq.h"
#include "intel_cdclk.h"
#include "intel_combo_phy.h"
#include "intel_combo_phy_regs.h"
#include "intel_crt.h"
#include "intel_de.h"
#include "intel_display_power.h"
@ -682,9 +683,8 @@ static void icl_tc_cold_exit(struct drm_i915_private *i915)
int ret, tries = 0;
while (1) {
ret = sandybridge_pcode_write_timeout(i915,
ICL_PCODE_EXIT_TCCOLD,
0, 250, 1);
ret = snb_pcode_write_timeout(i915, ICL_PCODE_EXIT_TCCOLD, 0,
250, 1);
if (ret != -EAGAIN || ++tries == 3)
break;
msleep(1);
@ -4052,8 +4052,7 @@ tgl_tc_cold_request(struct drm_i915_private *i915, bool block)
* Spec states that we should timeout the request after 200us
* but the function below will timeout after 500us
*/
ret = sandybridge_pcode_read(i915, TGL_PCODE_TCCOLD, &low_val,
&high_val);
ret = snb_pcode_read(i915, TGL_PCODE_TCCOLD, &low_val, &high_val);
if (ret == 0) {
if (block &&
(low_val & TGL_PCODE_EXIT_TCCOLD_DATA_L_EXIT_FAILED))
@ -5468,8 +5467,7 @@ static u32 hsw_read_dcomp(struct drm_i915_private *dev_priv)
static void hsw_write_dcomp(struct drm_i915_private *dev_priv, u32 val)
{
if (IS_HASWELL(dev_priv)) {
if (sandybridge_pcode_write(dev_priv,
GEN6_PCODE_WRITE_D_COMP, val))
if (snb_pcode_write(dev_priv, GEN6_PCODE_WRITE_D_COMP, val))
drm_dbg_kms(&dev_priv->drm,
"Failed to write to D_COMP\n");
} else {
@ -5582,7 +5580,7 @@ static void hsw_restore_lcpll(struct drm_i915_private *dev_priv)
intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL);
intel_update_cdclk(dev_priv);
intel_dump_cdclk_config(&dev_priv->cdclk.hw, "Current CDCLK");
intel_cdclk_dump_config(dev_priv, &dev_priv->cdclk.hw, "Current CDCLK");
}
/*
@ -6215,6 +6213,37 @@ void intel_power_domains_driver_remove(struct drm_i915_private *i915)
intel_runtime_pm_put(&i915->runtime_pm, wakeref);
}
/**
* intel_power_domains_sanitize_state - sanitize power domains state
* @i915: i915 device instance
*
* Sanitize the power domains state during driver loading and system resume.
* The function will disable all display power wells that BIOS has enabled
* without a user for it (any user for a power well has taken a reference
* on it by the time this function is called, after the state of all the
* pipe, encoder, etc. HW resources have been sanitized).
*/
void intel_power_domains_sanitize_state(struct drm_i915_private *i915)
{
struct i915_power_domains *power_domains = &i915->power_domains;
struct i915_power_well *power_well;
mutex_lock(&power_domains->lock);
for_each_power_well_reverse(i915, power_well) {
if (power_well->desc->always_on || power_well->count ||
!power_well->desc->ops->is_enabled(i915, power_well))
continue;
drm_dbg_kms(&i915->drm,
"BIOS left unused %s power well enabled, disabling it\n",
power_well->desc->name);
intel_power_well_disable(i915, power_well);
}
mutex_unlock(&power_domains->lock);
}
/**
* intel_power_domains_enable - enable toggling of display power wells
* @i915: i915 device instance

View file

@ -7,7 +7,6 @@
#define __INTEL_DISPLAY_POWER_H__
#include "intel_runtime_pm.h"
#include "i915_reg.h"
enum dpio_channel;
enum dpio_phy;
@ -219,6 +218,7 @@ void intel_power_domains_disable(struct drm_i915_private *dev_priv);
void intel_power_domains_suspend(struct drm_i915_private *dev_priv,
enum i915_drm_suspend_mode);
void intel_power_domains_resume(struct drm_i915_private *dev_priv);
void intel_power_domains_sanitize_state(struct drm_i915_private *dev_priv);
void intel_display_power_suspend_late(struct drm_i915_private *i915);
void intel_display_power_resume_early(struct drm_i915_private *i915);

View file

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

View file

@ -634,6 +634,9 @@ struct intel_plane_state {
struct intel_fb_view view;
/* Indicates if async flip is required */
bool do_async_flip;
/* Plane pxp decryption state */
bool decrypt;
@ -1442,25 +1445,6 @@ struct intel_hdmi {
};
struct intel_dp_mst_encoder;
/*
* enum link_m_n_set:
* When platform provides two set of M_N registers for dp, we can
* program them and switch between them incase of DRRS.
* But When only one such register is provided, we have to program the
* required divider value on that registers itself based on the DRRS state.
*
* M1_N1 : Program dp_m_n on M1_N1 registers
* dp_m2_n2 on M2_N2 registers (If supported)
*
* M2_N2 : Program dp_m2_n2 on M1_N1 registers
* M2_N2 registers are not supported
*/
enum link_m_n_set {
/* Sets the m1_n1 and m2_n2 */
M1_N1 = 0,
M2_N2
};
struct intel_dp_compliance_data {
unsigned long edid;

View file

@ -43,9 +43,9 @@
__stringify(major) "_" \
__stringify(minor) ".bin"
#define GEN12_DMC_MAX_FW_SIZE ICL_DMC_MAX_FW_SIZE
#define DISPLAY_VER13_DMC_MAX_FW_SIZE 0x20000
#define GEN13_DMC_MAX_FW_SIZE 0x20000
#define DISPLAY_VER12_DMC_MAX_FW_SIZE ICL_DMC_MAX_FW_SIZE
#define ADLP_DMC_PATH DMC_PATH(adlp, 2, 14)
#define ADLP_DMC_VERSION_REQUIRED DMC_VERSION(2, 14)
@ -684,23 +684,23 @@ void intel_dmc_ucode_init(struct drm_i915_private *dev_priv)
if (IS_ALDERLAKE_P(dev_priv)) {
dmc->fw_path = ADLP_DMC_PATH;
dmc->required_version = ADLP_DMC_VERSION_REQUIRED;
dmc->max_fw_size = GEN13_DMC_MAX_FW_SIZE;
dmc->max_fw_size = DISPLAY_VER13_DMC_MAX_FW_SIZE;
} else if (IS_ALDERLAKE_S(dev_priv)) {
dmc->fw_path = ADLS_DMC_PATH;
dmc->required_version = ADLS_DMC_VERSION_REQUIRED;
dmc->max_fw_size = GEN12_DMC_MAX_FW_SIZE;
dmc->max_fw_size = DISPLAY_VER12_DMC_MAX_FW_SIZE;
} else if (IS_DG1(dev_priv)) {
dmc->fw_path = DG1_DMC_PATH;
dmc->required_version = DG1_DMC_VERSION_REQUIRED;
dmc->max_fw_size = GEN12_DMC_MAX_FW_SIZE;
dmc->max_fw_size = DISPLAY_VER12_DMC_MAX_FW_SIZE;
} else if (IS_ROCKETLAKE(dev_priv)) {
dmc->fw_path = RKL_DMC_PATH;
dmc->required_version = RKL_DMC_VERSION_REQUIRED;
dmc->max_fw_size = GEN12_DMC_MAX_FW_SIZE;
dmc->max_fw_size = DISPLAY_VER12_DMC_MAX_FW_SIZE;
} else if (DISPLAY_VER(dev_priv) >= 12) {
dmc->fw_path = TGL_DMC_PATH;
dmc->required_version = TGL_DMC_VERSION_REQUIRED;
dmc->max_fw_size = GEN12_DMC_MAX_FW_SIZE;
dmc->max_fw_size = DISPLAY_VER12_DMC_MAX_FW_SIZE;
} else if (DISPLAY_VER(dev_priv) == 11) {
dmc->fw_path = ICL_DMC_PATH;
dmc->required_version = ICL_DMC_VERSION_REQUIRED;

View file

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

View file

@ -46,6 +46,7 @@
#include "intel_atomic.h"
#include "intel_audio.h"
#include "intel_backlight.h"
#include "intel_combo_phy_regs.h"
#include "intel_connector.h"
#include "intel_crtc.h"
#include "intel_ddi.h"
@ -72,8 +73,6 @@
#include "intel_vdsc.h"
#include "intel_vrr.h"
#define DP_DPRX_ESI_LEN 14
/* DP DSC throughput values used for slice count calculations KPixels/s */
#define DP_DSC_PEAK_PIXEL_RATE 2720000
#define DP_DSC_MAX_ENC_THROUGHPUT_0 340000
@ -705,7 +704,7 @@ static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,
i915->max_cdclk_freq * 48 /
intel_dp_mode_to_fec_clock(mode_clock);
DRM_DEBUG_KMS("Max big joiner bpp: %u\n", max_bpp_bigjoiner);
drm_dbg_kms(&i915->drm, "Max big joiner bpp: %u\n", max_bpp_bigjoiner);
bits_per_pixel = min(bits_per_pixel, max_bpp_bigjoiner);
}
@ -1167,14 +1166,13 @@ static bool intel_dp_hdmi_tmds_clock_valid(struct intel_dp *intel_dp,
return true;
}
static bool intel_dp_hdmi_deep_color_possible(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state,
int bpc)
static bool intel_dp_hdmi_bpc_possible(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state,
int bpc)
{
return intel_hdmi_deep_color_possible(crtc_state, bpc,
intel_dp->has_hdmi_sink,
intel_dp_hdmi_ycbcr420(intel_dp, crtc_state)) &&
return intel_hdmi_bpc_possible(crtc_state, bpc, intel_dp->has_hdmi_sink,
intel_dp_hdmi_ycbcr420(intel_dp, crtc_state)) &&
intel_dp_hdmi_tmds_clock_valid(intel_dp, crtc_state, bpc);
}
@ -1192,7 +1190,7 @@ static int intel_dp_max_bpp(struct intel_dp *intel_dp,
if (intel_dp->dfp.min_tmds_clock) {
for (; bpc >= 10; bpc -= 2) {
if (intel_dp_hdmi_deep_color_possible(intel_dp, crtc_state, bpc))
if (intel_dp_hdmi_bpc_possible(intel_dp, crtc_state, bpc))
break;
}
}
@ -1897,7 +1895,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
/* FIXME: abstract this better */
if (pipe_config->splitter.enable)
pipe_config->dp_m_n.gmch_m *= pipe_config->splitter.link_count;
pipe_config->dp_m_n.data_m *= pipe_config->splitter.link_count;
if (!HAS_DDI(dev_priv))
g4x_dp_set_clock(encoder, pipe_config);
@ -2813,11 +2811,22 @@ intel_dp_configure_mst(struct intel_dp *intel_dp)
}
static bool
intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *sink_irq_vector)
intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *esi)
{
return drm_dp_dpcd_read(&intel_dp->aux, DP_SINK_COUNT_ESI,
sink_irq_vector, DP_DPRX_ESI_LEN) ==
DP_DPRX_ESI_LEN;
return drm_dp_dpcd_read(&intel_dp->aux, DP_SINK_COUNT_ESI, esi, 4) == 4;
}
static bool intel_dp_ack_sink_irq_esi(struct intel_dp *intel_dp, u8 esi[4])
{
int retry;
for (retry = 0; retry < 3; retry++) {
if (drm_dp_dpcd_write(&intel_dp->aux, DP_SINK_COUNT_ESI + 1,
&esi[1], 3) == 3)
return true;
}
return false;
}
bool
@ -2909,7 +2918,8 @@ static ssize_t intel_dp_vsc_sdp_pack(const struct drm_dp_vsc_sdp *vsc,
}
static ssize_t
intel_dp_hdr_metadata_infoframe_sdp_pack(const struct hdmi_drm_infoframe *drm_infoframe,
intel_dp_hdr_metadata_infoframe_sdp_pack(struct drm_i915_private *i915,
const struct hdmi_drm_infoframe *drm_infoframe,
struct dp_sdp *sdp,
size_t size)
{
@ -2925,12 +2935,12 @@ intel_dp_hdr_metadata_infoframe_sdp_pack(const struct hdmi_drm_infoframe *drm_in
len = hdmi_drm_infoframe_pack_only(drm_infoframe, buf, sizeof(buf));
if (len < 0) {
DRM_DEBUG_KMS("buffer size is smaller than hdr metadata infoframe\n");
drm_dbg_kms(&i915->drm, "buffer size is smaller than hdr metadata infoframe\n");
return -ENOSPC;
}
if (len != infoframe_size) {
DRM_DEBUG_KMS("wrong static hdr metadata size\n");
drm_dbg_kms(&i915->drm, "wrong static hdr metadata size\n");
return -ENOSPC;
}
@ -3003,7 +3013,8 @@ static void intel_write_dp_sdp(struct intel_encoder *encoder,
sizeof(sdp));
break;
case HDMI_PACKET_TYPE_GAMUT_METADATA:
len = intel_dp_hdr_metadata_infoframe_sdp_pack(&crtc_state->infoframes.drm.drm,
len = intel_dp_hdr_metadata_infoframe_sdp_pack(dev_priv,
&crtc_state->infoframes.drm.drm,
&sdp, sizeof(sdp));
break;
default:
@ -3411,22 +3422,22 @@ static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp,
switch (data->phy_pattern) {
case DP_PHY_TEST_PATTERN_NONE:
DRM_DEBUG_KMS("Disable Phy Test Pattern\n");
drm_dbg_kms(&dev_priv->drm, "Disable Phy Test Pattern\n");
intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), 0x0);
break;
case DP_PHY_TEST_PATTERN_D10_2:
DRM_DEBUG_KMS("Set D10.2 Phy Test Pattern\n");
drm_dbg_kms(&dev_priv->drm, "Set D10.2 Phy Test Pattern\n");
intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe),
DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_D10_2);
break;
case DP_PHY_TEST_PATTERN_ERROR_COUNT:
DRM_DEBUG_KMS("Set Error Count Phy Test Pattern\n");
drm_dbg_kms(&dev_priv->drm, "Set Error Count Phy Test Pattern\n");
intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe),
DDI_DP_COMP_CTL_ENABLE |
DDI_DP_COMP_CTL_SCRAMBLED_0);
break;
case DP_PHY_TEST_PATTERN_PRBS7:
DRM_DEBUG_KMS("Set PRBS7 Phy Test Pattern\n");
drm_dbg_kms(&dev_priv->drm, "Set PRBS7 Phy Test Pattern\n");
intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe),
DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_PRBS7);
break;
@ -3436,7 +3447,8 @@ static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp,
* current firmware of DPR-100 could not set it, so hardcoding
* now for complaince test.
*/
DRM_DEBUG_KMS("Set 80Bit Custom Phy Test Pattern 0x3e0f83e0 0x0f83e0f8 0x0000f83e\n");
drm_dbg_kms(&dev_priv->drm,
"Set 80Bit Custom Phy Test Pattern 0x3e0f83e0 0x0f83e0f8 0x0000f83e\n");
pattern_val = 0x3e0f83e0;
intel_de_write(dev_priv, DDI_DP_COMP_PAT(pipe, 0), pattern_val);
pattern_val = 0x0f83e0f8;
@ -3453,7 +3465,7 @@ static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp,
* current firmware of DPR-100 could not set it, so hardcoding
* now for complaince test.
*/
DRM_DEBUG_KMS("Set HBR2 compliance Phy Test Pattern\n");
drm_dbg_kms(&dev_priv->drm, "Set HBR2 compliance Phy Test Pattern\n");
pattern_val = 0xFB;
intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe),
DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_HBR2 |
@ -3522,13 +3534,14 @@ intel_dp_autotest_phy_ddi_enable(struct intel_dp *intel_dp,
static void intel_dp_process_phy_request(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
struct drm_dp_phy_test_params *data =
&intel_dp->compliance.test_data.phytest;
u8 link_status[DP_LINK_STATUS_SIZE];
if (drm_dp_dpcd_read_phy_link_status(&intel_dp->aux, DP_PHY_DPRX,
link_status) < 0) {
DRM_DEBUG_KMS("failed to get link status\n");
drm_dbg_kms(&i915->drm, "failed to get link status\n");
return;
}
@ -3553,11 +3566,12 @@ static void intel_dp_process_phy_request(struct intel_dp *intel_dp,
static u8 intel_dp_autotest_phy_pattern(struct intel_dp *intel_dp)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
struct drm_dp_phy_test_params *data =
&intel_dp->compliance.test_data.phytest;
if (drm_dp_get_phy_test_pattern(&intel_dp->aux, data)) {
DRM_DEBUG_KMS("DP Phy Test pattern AUX read failure\n");
drm_dbg_kms(&i915->drm, "DP Phy Test pattern AUX read failure\n");
return DP_TEST_NAK;
}
@ -3615,14 +3629,43 @@ static void intel_dp_handle_test_request(struct intel_dp *intel_dp)
}
static void
intel_dp_mst_hpd_irq(struct intel_dp *intel_dp, u8 *esi, bool *handled)
intel_dp_mst_hpd_irq(struct intel_dp *intel_dp, u8 *esi, u8 *ack)
{
drm_dp_mst_hpd_irq(&intel_dp->mst_mgr, esi, handled);
bool handled = false;
if (esi[1] & DP_CP_IRQ) {
intel_hdcp_handle_cp_irq(intel_dp->attached_connector);
*handled = true;
}
drm_dp_mst_hpd_irq(&intel_dp->mst_mgr, esi, &handled);
if (handled)
ack[1] |= esi[1] & (DP_DOWN_REP_MSG_RDY | DP_UP_REQ_MSG_RDY);
if (esi[1] & DP_CP_IRQ) {
intel_hdcp_handle_cp_irq(intel_dp->attached_connector);
ack[1] |= DP_CP_IRQ;
}
}
static bool intel_dp_mst_link_status(struct intel_dp *intel_dp)
{
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
u8 link_status[DP_LINK_STATUS_SIZE] = {};
const size_t esi_link_status_size = DP_LINK_STATUS_SIZE - 2;
if (drm_dp_dpcd_read(&intel_dp->aux, DP_LANE0_1_STATUS_ESI, link_status,
esi_link_status_size) != esi_link_status_size) {
drm_err(&i915->drm,
"[ENCODER:%d:%s] Failed to read link status\n",
encoder->base.base.id, encoder->base.name);
return false;
}
if (!drm_dp_channel_eq_ok(link_status, intel_dp->lane_count)) {
drm_dbg_kms(&i915->drm,
"[ENCODER:%d:%s] channel EQ not ok, retraining\n",
encoder->base.base.id, encoder->base.name);
return false;
}
return true;
}
/**
@ -3647,20 +3690,8 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp)
drm_WARN_ON_ONCE(&i915->drm, intel_dp->active_mst_links < 0);
for (;;) {
/*
* The +2 is because DP_DPRX_ESI_LEN is 14, but we then
* pass in "esi+10" to drm_dp_channel_eq_ok(), which
* takes a 6-byte array. So we actually need 16 bytes
* here.
*
* Somebody who knows what the limits actually are
* should check this, but for now this is at least
* harmless and avoids a valid compiler warning about
* using more of the array than we have allocated.
*/
u8 esi[DP_DPRX_ESI_LEN+2] = {};
bool handled;
int retry;
u8 esi[4] = {};
u8 ack[4] = {};
if (!intel_dp_get_sink_irq_esi(intel_dp, esi)) {
drm_dbg_kms(&i915->drm,
@ -3670,30 +3701,22 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp)
break;
}
/* check link status - esi[10] = 0x200c */
drm_dbg_kms(&i915->drm, "DPRX ESI: %4ph\n", esi);
if (intel_dp->active_mst_links > 0 && link_ok &&
!drm_dp_channel_eq_ok(&esi[10], intel_dp->lane_count)) {
drm_dbg_kms(&i915->drm,
"channel EQ not ok, retraining\n");
link_ok = false;
esi[3] & LINK_STATUS_CHANGED) {
if (!intel_dp_mst_link_status(intel_dp))
link_ok = false;
ack[3] |= LINK_STATUS_CHANGED;
}
drm_dbg_kms(&i915->drm, "got esi %3ph\n", esi);
intel_dp_mst_hpd_irq(intel_dp, esi, ack);
intel_dp_mst_hpd_irq(intel_dp, esi, &handled);
if (!handled)
if (!memchr_inv(ack, 0, sizeof(ack)))
break;
for (retry = 0; retry < 3; retry++) {
int wret;
wret = drm_dp_dpcd_write(&intel_dp->aux,
DP_SINK_COUNT_ESI+1,
&esi[1], 3);
if (wret == 3)
break;
}
if (!intel_dp_ack_sink_irq_esi(intel_dp, ack))
drm_dbg_kms(&i915->drm, "Failed to ack ESI\n");
}
return link_ok;
@ -4974,6 +4997,14 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
mutex_lock(&dev->mode_config.mutex);
edid = drm_get_edid(connector, &intel_dp->aux.ddc);
if (!edid) {
/* Fallback to EDID from ACPI OpRegion, if any */
edid = intel_opregion_get_edid(intel_connector);
if (edid)
drm_dbg_kms(&dev_priv->drm,
"[CONNECTOR:%d:%s] Using OpRegion EDID\n",
connector->base.id, connector->name);
}
if (edid) {
if (drm_add_edid_modes(connector, edid)) {
drm_connector_update_edid_property(connector, edid);
@ -5048,8 +5079,8 @@ static void intel_dp_modeset_retry_work_fn(struct work_struct *work)
intel_connector = container_of(work, typeof(*intel_connector),
modeset_retry_work);
connector = &intel_connector->base;
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id,
connector->name);
drm_dbg_kms(connector->dev, "[CONNECTOR:%d:%s]\n", connector->base.id,
connector->name);
/* Grab the locks before changing connector property*/
mutex_lock(&connector->dev->mode_config.mutex);

View file

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

View file

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

View file

@ -6,12 +6,8 @@
#ifndef __INTEL_DP_AUX_H__
#define __INTEL_DP_AUX_H__
#include <linux/types.h>
struct intel_dp;
u32 intel_dp_pack_aux(const u8 *src, int src_bytes);
void intel_dp_aux_fini(struct intel_dp *intel_dp);
void intel_dp_aux_init(struct intel_dp *intel_dp);

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_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,

View file

@ -28,6 +28,7 @@
#include "intel_dpll_mgr.h"
#include "intel_pch_refclk.h"
#include "intel_tc.h"
#include "intel_tc_phy_regs.h"
/**
* DOC: Display PLLs
@ -49,6 +50,41 @@
* commit phase.
*/
/* platform specific hooks for managing DPLLs */
struct intel_shared_dpll_funcs {
/*
* Hook for enabling the pll, called from intel_enable_shared_dpll() if
* the pll is not already enabled.
*/
void (*enable)(struct drm_i915_private *i915,
struct intel_shared_dpll *pll);
/*
* Hook for disabling the pll, called from intel_disable_shared_dpll()
* only when it is safe to disable the pll, i.e., there are no more
* tracked users for it.
*/
void (*disable)(struct drm_i915_private *i915,
struct intel_shared_dpll *pll);
/*
* Hook for reading the values currently programmed to the DPLL
* registers. This is used for initial hw state readout and state
* verification after a mode set.
*/
bool (*get_hw_state)(struct drm_i915_private *i915,
struct intel_shared_dpll *pll,
struct intel_dpll_hw_state *hw_state);
/*
* Hook for calculating the pll's output frequency based on its passed
* in state.
*/
int (*get_freq)(struct drm_i915_private *i915,
const struct intel_shared_dpll *pll,
const struct intel_dpll_hw_state *pll_state);
};
struct intel_dpll_mgr {
const struct dpll_info *dpll_info;

View file

@ -44,6 +44,7 @@ struct intel_crtc;
struct intel_crtc_state;
struct intel_encoder;
struct intel_shared_dpll;
struct intel_shared_dpll_funcs;
/**
* enum intel_dpll_id - possible DPLL ids
@ -251,51 +252,6 @@ struct intel_shared_dpll_state {
struct intel_dpll_hw_state hw_state;
};
/**
* struct intel_shared_dpll_funcs - platform specific hooks for managing DPLLs
*/
struct intel_shared_dpll_funcs {
/**
* @enable:
*
* Hook for enabling the pll, called from intel_enable_shared_dpll()
* if the pll is not already enabled.
*/
void (*enable)(struct drm_i915_private *dev_priv,
struct intel_shared_dpll *pll);
/**
* @disable:
*
* Hook for disabling the pll, called from intel_disable_shared_dpll()
* only when it is safe to disable the pll, i.e., there are no more
* tracked users for it.
*/
void (*disable)(struct drm_i915_private *dev_priv,
struct intel_shared_dpll *pll);
/**
* @get_hw_state:
*
* Hook for reading the values currently programmed to the DPLL
* registers. This is used for initial hw state readout and state
* verification after a mode set.
*/
bool (*get_hw_state)(struct drm_i915_private *dev_priv,
struct intel_shared_dpll *pll,
struct intel_dpll_hw_state *hw_state);
/**
* @get_freq:
*
* Hook for calculating the pll's output frequency based on its
* passed in state.
*/
int (*get_freq)(struct drm_i915_private *i915,
const struct intel_shared_dpll *pll,
const struct intel_dpll_hw_state *pll_state);
};
/**
* struct dpll_info - display PLL platform specific info
*/

View file

@ -47,17 +47,13 @@
* requested by userspace.
*/
void
intel_drrs_compute_config(struct intel_dp *intel_dp,
struct intel_crtc_state *pipe_config,
int output_bpp, bool constant_n)
static bool can_enable_drrs(struct intel_connector *connector,
const struct intel_crtc_state *pipe_config)
{
struct intel_connector *intel_connector = intel_dp->attached_connector;
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
int pixel_clock;
const struct drm_i915_private *i915 = to_i915(connector->base.dev);
if (pipe_config->vrr.enable)
return;
return false;
/*
* DRRS and PSR can't be enable together, so giving preference to PSR
@ -66,15 +62,30 @@ intel_drrs_compute_config(struct intel_dp *intel_dp,
* after intel_psr_compute_config().
*/
if (pipe_config->has_psr)
return;
return false;
if (!intel_connector->panel.downclock_mode ||
dev_priv->drrs.type != SEAMLESS_DRRS_SUPPORT)
return connector->panel.downclock_mode &&
i915->drrs.type == SEAMLESS_DRRS_SUPPORT;
}
void
intel_drrs_compute_config(struct intel_dp *intel_dp,
struct intel_crtc_state *pipe_config,
int output_bpp, bool constant_n)
{
struct intel_connector *connector = intel_dp->attached_connector;
struct drm_i915_private *i915 = to_i915(connector->base.dev);
int pixel_clock;
if (!can_enable_drrs(connector, pipe_config)) {
if (intel_cpu_transcoder_has_m2_n2(i915, pipe_config->cpu_transcoder))
intel_zero_m_n(&pipe_config->dp_m2_n2);
return;
}
pipe_config->has_drrs = true;
pixel_clock = intel_connector->panel.downclock_mode->clock;
pixel_clock = connector->panel.downclock_mode->clock;
if (pipe_config->splitter.enable)
pixel_clock /= pipe_config->splitter.link_count;
@ -84,7 +95,42 @@ intel_drrs_compute_config(struct intel_dp *intel_dp,
/* FIXME: abstract this better */
if (pipe_config->splitter.enable)
pipe_config->dp_m2_n2.gmch_m *= pipe_config->splitter.link_count;
pipe_config->dp_m2_n2.data_m *= pipe_config->splitter.link_count;
}
static void
intel_drrs_set_refresh_rate_pipeconf(const struct intel_crtc_state *crtc_state,
enum drrs_refresh_rate_type refresh_type)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
u32 val, bit;
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
bit = PIPECONF_EDP_RR_MODE_SWITCH_VLV;
else
bit = PIPECONF_EDP_RR_MODE_SWITCH;
val = intel_de_read(dev_priv, PIPECONF(cpu_transcoder));
if (refresh_type == DRRS_LOW_RR)
val |= bit;
else
val &= ~bit;
intel_de_write(dev_priv, PIPECONF(cpu_transcoder), val);
}
static void
intel_drrs_set_refresh_rate_m_n(const struct intel_crtc_state *crtc_state,
enum drrs_refresh_rate_type refresh_type)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
intel_cpu_transcoder_set_m1_n1(crtc, crtc_state->cpu_transcoder,
refresh_type == DRRS_LOW_RR ?
&crtc_state->dp_m2_n2 : &crtc_state->dp_m_n);
}
static void intel_drrs_set_state(struct drm_i915_private *dev_priv,
@ -120,37 +166,10 @@ static void intel_drrs_set_state(struct drm_i915_private *dev_priv,
return;
}
if (DISPLAY_VER(dev_priv) >= 8 && !IS_CHERRYVIEW(dev_priv)) {
switch (refresh_type) {
case DRRS_HIGH_RR:
intel_dp_set_m_n(crtc_state, M1_N1);
break;
case DRRS_LOW_RR:
intel_dp_set_m_n(crtc_state, M2_N2);
break;
case DRRS_MAX_RR:
default:
drm_err(&dev_priv->drm,
"Unsupported refreshrate type\n");
}
} else if (DISPLAY_VER(dev_priv) > 6) {
i915_reg_t reg = PIPECONF(crtc_state->cpu_transcoder);
u32 val;
val = intel_de_read(dev_priv, reg);
if (refresh_type == DRRS_LOW_RR) {
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
val |= PIPECONF_EDP_RR_MODE_SWITCH_VLV;
else
val |= PIPECONF_EDP_RR_MODE_SWITCH;
} else {
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
val &= ~PIPECONF_EDP_RR_MODE_SWITCH_VLV;
else
val &= ~PIPECONF_EDP_RR_MODE_SWITCH;
}
intel_de_write(dev_priv, reg, val);
}
if (DISPLAY_VER(dev_priv) >= 8 && !IS_CHERRYVIEW(dev_priv))
intel_drrs_set_refresh_rate_m_n(crtc_state, refresh_type);
else if (DISPLAY_VER(dev_priv) > 6)
intel_drrs_set_refresh_rate_pipeconf(crtc_state, refresh_type);
dev_priv->drrs.refresh_rate_type = refresh_type;
@ -405,6 +424,7 @@ intel_drrs_init(struct intel_connector *connector,
struct drm_display_mode *fixed_mode)
{
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
struct intel_encoder *encoder = connector->encoder;
struct drm_display_mode *downclock_mode = NULL;
INIT_DELAYED_WORK(&dev_priv->drrs.work, intel_drrs_downclock_work);
@ -416,6 +436,13 @@ intel_drrs_init(struct intel_connector *connector,
return NULL;
}
if ((DISPLAY_VER(dev_priv) < 8 && !HAS_GMCH(dev_priv)) &&
encoder->port != PORT_A) {
drm_dbg_kms(&dev_priv->drm,
"DRRS only supported on eDP port A\n");
return NULL;
}
if (dev_priv->vbt.drrs_type != SEAMLESS_DRRS_SUPPORT) {
drm_dbg_kms(&dev_priv->drm, "VBT doesn't support DRRS\n");
return NULL;

View file

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

View file

@ -39,6 +39,7 @@
#include <video/mipi_display.h>
#include "i915_drv.h"
#include "i915_reg.h"
#include "intel_display_types.h"
#include "intel_dsi.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)
{
struct drm_device *drm_dev = intel_dsi->base.base.dev;
struct device *dev = drm_dev->dev;
struct acpi_device *acpi_dev;
struct list_head resource_list;
struct i2c_adapter_lookup lookup;
struct acpi_device *adev = ACPI_COMPANION(drm_dev->dev);
struct i2c_adapter_lookup lookup = {
.slave_addr = slave_addr,
.intel_dsi = intel_dsi,
.dev_handle = acpi_device_handle(adev),
};
LIST_HEAD(resource_list);
acpi_dev = ACPI_COMPANION(dev);
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_get_resources(adev, &resource_list, i2c_adapter_lookup, &lookup);
acpi_dev_free_resource_list(&resource_list);
}
#else
static inline void i2c_acpi_find_adapter(struct intel_dsi *intel_dsi,

View file

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

View file

@ -49,6 +49,14 @@
#include "intel_fbc.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 {
void (*activate)(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_llb;
enum intel_fbc_id id;
u8 limit;
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 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);
intel_de_write(i915, ILK_DPFC_CONTROL,
intel_de_write(i915, ILK_DPFC_CONTROL(fbc->id),
DPFC_CTL_EN | g4x_dpfc_ctl(fbc));
}
@ -467,28 +477,28 @@ static void ilk_fbc_deactivate(struct intel_fbc *fbc)
u32 dpfc_ctl;
/* 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) {
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)
{
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)
{
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)
{
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 = {
@ -524,8 +534,8 @@ static void snb_fbc_nuke(struct intel_fbc *fbc)
{
struct drm_i915_private *i915 = fbc->i915;
intel_de_write(i915, MSG_FBC_REND_STATE, FBC_REND_NUKE);
intel_de_posting_read(i915, MSG_FBC_REND_STATE);
intel_de_write(i915, MSG_FBC_REND_STATE(fbc->id), FBC_REND_NUKE);
intel_de_posting_read(i915, MSG_FBC_REND_STATE(fbc->id));
}
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 |
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)
@ -598,19 +608,19 @@ static void ivb_fbc_activate(struct intel_fbc *fbc)
if (i915->ggtt.num_fences)
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));
}
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,
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);
}
@ -810,16 +820,16 @@ static void __intel_fbc_cleanup_cfb(struct intel_fbc *fbc)
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);
__intel_fbc_cleanup_cfb(fbc);
mutex_unlock(&fbc->lock);
mutex_lock(&fbc->lock);
__intel_fbc_cleanup_cfb(fbc);
mutex_unlock(&fbc->lock);
kfree(fbc);
kfree(fbc);
}
}
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;
}
void intel_fbc_invalidate(struct drm_i915_private *i915,
unsigned int frontbuffer_bits,
enum fb_op_origin origin)
static void __intel_fbc_invalidate(struct intel_fbc *fbc,
unsigned int frontbuffer_bits,
enum fb_op_origin origin)
{
struct intel_fbc *fbc = i915->fbc;
if (!fbc)
return;
if (origin == ORIGIN_FLIP || origin == ORIGIN_CURSOR_UPDATE)
return;
@ -1327,14 +1332,22 @@ void intel_fbc_invalidate(struct drm_i915_private *i915,
mutex_unlock(&fbc->lock);
}
void intel_fbc_flush(struct drm_i915_private *i915,
unsigned int frontbuffer_bits, enum fb_op_origin origin)
void intel_fbc_invalidate(struct drm_i915_private *i915,
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)
return;
for_each_intel_fbc(i915, fbc, fbc_id)
__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);
fbc->busy_bits &= ~frontbuffer_bits;
@ -1354,6 +1367,17 @@ void intel_fbc_flush(struct drm_i915_private *i915,
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)
{
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)
{
struct intel_fbc *fbc = i915->fbc;
struct intel_fbc *fbc;
enum intel_fbc_id fbc_id;
if (!fbc)
return;
mutex_lock(&fbc->lock);
if (fbc->state.plane)
__intel_fbc_disable(fbc);
mutex_unlock(&fbc->lock);
for_each_intel_fbc(i915, fbc, fbc_id) {
mutex_lock(&fbc->lock);
if (fbc->state.plane)
__intel_fbc_disable(fbc);
mutex_unlock(&fbc->lock);
}
}
static void intel_fbc_underrun_work_fn(struct work_struct *work)
@ -1516,19 +1540,9 @@ static void intel_fbc_underrun_work_fn(struct work_struct *work)
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)
static void __intel_fbc_reset_underrun(struct intel_fbc *fbc)
{
struct intel_fbc *fbc = i915->fbc;
if (!fbc)
return;
struct drm_i915_private *i915 = fbc->i915;
cancel_work_sync(&fbc->underrun_work);
@ -1544,6 +1558,38 @@ void intel_fbc_reset_underrun(struct drm_i915_private *i915)
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
* @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)
{
struct intel_fbc *fbc = i915->fbc;
struct intel_fbc *fbc;
enum intel_fbc_id fbc_id;
if (!fbc)
return;
/* 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);
for_each_intel_fbc(i915, fbc, fbc_id)
__intel_fbc_handle_fifo_underrun_irq(fbc);
}
/*
@ -1622,7 +1658,8 @@ void intel_fbc_add_plane(struct intel_fbc *fbc, struct intel_plane *plane)
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;
@ -1630,6 +1667,7 @@ static struct intel_fbc *intel_fbc_create(struct drm_i915_private *i915)
if (!fbc)
return NULL;
fbc->id = fbc_id;
fbc->i915 = i915;
INIT_WORK(&fbc->underrun_work, intel_fbc_underrun_work_fn);
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)
{
struct intel_fbc *fbc;
enum intel_fbc_id fbc_id;
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))
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);
drm_dbg_kms(&i915->drm, "Sanitized enable_fbc value: %d\n",
i915->params.enable_fbc);
if (!HAS_FBC(i915))
return;
for_each_fbc_id(i915, fbc_id) {
struct intel_fbc *fbc;
fbc = intel_fbc_create(i915);
if (!fbc)
return;
fbc = intel_fbc_create(i915, fbc_id);
if (!fbc)
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
* matches the hardware state. */
if (intel_fbc_hw_is_active(fbc))
intel_fbc_hw_deactivate(fbc);
/*
* 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 matches the hardware state.
*/
if (intel_fbc_hw_is_active(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)
@ -1759,25 +1800,32 @@ DEFINE_SIMPLE_ATTRIBUTE(intel_fbc_debugfs_false_color_fops,
intel_fbc_debugfs_false_color_set,
"%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;
struct drm_minor *minor = i915->drm.primary;
debugfs_create_file("i915_fbc_status", 0444,
minor->debugfs_root, fbc,
&intel_fbc_debugfs_status_fops);
debugfs_create_file("i915_fbc_status", 0444, parent,
fbc, &intel_fbc_debugfs_status_fops);
if (fbc->funcs->set_false_color)
debugfs_create_file("i915_fbc_false_color", 0644,
minor->debugfs_root, fbc,
&intel_fbc_debugfs_false_color_fops);
debugfs_create_file("i915_fbc_false_color", 0644, parent,
fbc, &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)
{
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)
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_state;
enum intel_fbc_id {
INTEL_FBC_A,
I915_MAX_FBCS,
};
int intel_fbc_atomic_check(struct intel_atomic_state *state);
bool intel_fbc_pre_update(struct intel_atomic_state *state,
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_handle_fifo_underrun_irq(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);
#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;
}
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)
{
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 *
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);
bool intel_gmbus_is_forced_bit(struct i2c_adapter *adapter);
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.
*/
if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv)) {
ret = sandybridge_pcode_write(dev_priv,
SKL_PCODE_LOAD_HDCP_KEYS, 1);
ret = snb_pcode_write(dev_priv, SKL_PCODE_LOAD_HDCP_KEYS, 1);
if (ret) {
drm_err(&dev_priv->drm,
"Failed to initiate HDCP key load (%d)\n",

View file

@ -2002,17 +2002,14 @@ intel_hdmi_mode_valid(struct drm_connector *connector,
return intel_mode_valid_max_plane_size(dev_priv, mode, false);
}
bool intel_hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
int bpc, bool has_hdmi_sink, bool ycbcr420_output)
bool intel_hdmi_bpc_possible(const struct intel_crtc_state *crtc_state,
int bpc, bool has_hdmi_sink, bool ycbcr420_output)
{
struct drm_atomic_state *state = crtc_state->uapi.state;
struct drm_connector_state *connector_state;
struct drm_connector *connector;
int i;
if (crtc_state->pipe_bpp < bpc * 3)
return false;
for_each_new_connector_in_state(state, connector, connector_state, i) {
if (connector_state->crtc != crtc_state->uapi.crtc)
continue;
@ -2024,8 +2021,7 @@ bool intel_hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
return true;
}
static bool hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
int bpc)
static bool hdmi_bpc_possible(const struct intel_crtc_state *crtc_state, int bpc)
{
struct drm_i915_private *dev_priv =
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
* 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;
/* 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)
return false;
return intel_hdmi_deep_color_possible(crtc_state, bpc,
crtc_state->has_hdmi_sink,
intel_hdmi_is_ycbcr420(crtc_state));
return intel_hdmi_bpc_possible(crtc_state, bpc, crtc_state->has_hdmi_sink,
intel_hdmi_is_ycbcr420(crtc_state));
}
static int intel_hdmi_compute_bpc(struct intel_encoder *encoder,
struct intel_crtc_state *crtc_state,
int clock)
int clock, bool respect_downstream_limits)
{
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
bool ycbcr420_output = intel_hdmi_is_ycbcr420(crtc_state);
int bpc;
for (bpc = 12; bpc >= 10; bpc -= 2) {
if (hdmi_deep_color_possible(crtc_state, bpc) &&
hdmi_port_clock_valid(intel_hdmi,
intel_hdmi_tmds_clock(clock, bpc, ycbcr420_output),
true, crtc_state->has_hdmi_sink) == MODE_OK)
/*
* pipe_bpp could already be below 8bpc due to FDI
* bandwidth constraints. HDMI minimum is 8bpc however.
*/
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 8;
return -EINVAL;
}
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 intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
const struct drm_display_mode *adjusted_mode =
&crtc_state->hw.adjusted_mode;
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)
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,
intel_hdmi_is_ycbcr420(crtc_state));
crtc_state->port_clock =
intel_hdmi_tmds_clock(clock, bpc, intel_hdmi_is_ycbcr420(crtc_state));
/*
* pipe_bpp could already be below 8bpc due to
* 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 = bpc * 3;
crtc_state->pipe_bpp = min(crtc_state->pipe_bpp, bpc * 3);
drm_dbg_kms(&i915->drm,
"picking %d bpc for HDMI output (pipe bpp: %d)\n",
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;
}
@ -2170,7 +2175,8 @@ intel_hdmi_output_format(struct intel_connector *connector,
static int intel_hdmi_compute_output_format(struct intel_encoder *encoder,
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);
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;
}
ret = intel_hdmi_compute_clock(encoder, crtc_state);
ret = intel_hdmi_compute_clock(encoder, crtc_state, respect_downstream_limits);
if (ret) {
if (intel_hdmi_is_ycbcr420(crtc_state) ||
!connector->base.ycbcr_420_allowed ||
@ -2195,7 +2201,7 @@ static int intel_hdmi_compute_output_format(struct intel_encoder *encoder,
return ret;
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;
@ -2231,9 +2237,19 @@ int intel_hdmi_compute_config(struct intel_encoder *encoder,
pipe_config->has_audio =
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)
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;
}
if (intel_hdmi_is_ycbcr420(pipe_config)) {
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",
drm_dp_get_dual_mode_type_name(type),
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

View file

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

View file

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

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)
{
struct intel_dp *dp = lspcon_to_intel_dp(lspcon);
struct drm_i915_private *i915 = dp_to_i915(dp);
struct drm_dp_dpcd_ident *ident;
u32 vendor_oui;
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;
}
@ -93,16 +94,16 @@ static bool lspcon_detect_vendor(struct intel_lspcon *lspcon)
switch (vendor_oui) {
case LSPCON_VENDOR_MCA_OUI:
lspcon->vendor = LSPCON_VENDOR_MCA;
DRM_DEBUG_KMS("Vendor: Mega Chips\n");
drm_dbg_kms(&i915->drm, "Vendor: Mega Chips\n");
break;
case LSPCON_VENDOR_PARADE_OUI:
lspcon->vendor = LSPCON_VENDOR_PARADE;
DRM_DEBUG_KMS("Vendor: Parade Tech\n");
drm_dbg_kms(&i915->drm, "Vendor: Parade Tech\n");
break;
default:
DRM_ERROR("Invalid/Unknown vendor OUI\n");
drm_err(&i915->drm, "Invalid/Unknown vendor OUI\n");
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)
{
struct intel_digital_port *dig_port =
container_of(lspcon, struct intel_digital_port, lspcon);
struct drm_device *dev = dig_port->base.base.dev;
struct intel_dp *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);
u8 hdr_caps;
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);
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;
} 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;
}
}
@ -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)
{
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;
struct i2c_adapter *adapter = &intel_dp->aux.ddc;
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 current_mode;
@ -154,22 +154,24 @@ 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,
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;
current_mode = lspcon_get_current_mode(lspcon);
if (current_mode == mode)
goto out;
DRM_DEBUG_KMS("Waiting for LSPCON mode %s to settle\n",
lspcon_mode_name(mode));
drm_dbg_kms(&i915->drm, "Waiting for LSPCON mode %s to settle\n",
lspcon_mode_name(mode));
wait_for((current_mode = lspcon_get_current_mode(lspcon)) == mode, 400);
if (current_mode != mode)
DRM_ERROR("LSPCON mode hasn't settled\n");
drm_err(&i915->drm, "LSPCON mode hasn't settled\n");
out:
DRM_DEBUG_KMS("Current LSPCON mode %s\n",
lspcon_mode_name(current_mode));
drm_dbg_kms(&i915->drm, "Current LSPCON mode %s\n",
lspcon_mode_name(current_mode));
return current_mode;
}
@ -178,44 +180,47 @@ static int lspcon_change_mode(struct intel_lspcon *lspcon,
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);
int err;
enum drm_lspcon_mode current_mode;
struct i2c_adapter *adapter = &intel_dp->aux.ddc;
err = drm_lspcon_get_mode(intel_dp->aux.drm_dev, adapter, &current_mode);
if (err) {
DRM_ERROR("Error reading LSPCON mode\n");
drm_err(&i915->drm, "Error reading LSPCON mode\n");
return err;
}
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;
}
err = drm_lspcon_set_mode(intel_dp->aux.drm_dev, adapter, mode);
if (err < 0) {
DRM_ERROR("LSPCON mode change failed\n");
drm_err(&i915->drm, "LSPCON mode change failed\n");
return err;
}
lspcon->mode = mode;
DRM_DEBUG_KMS("LSPCON mode changed done\n");
drm_dbg_kms(&i915->drm, "LSPCON mode changed done\n");
return 0;
}
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;
if (drm_dp_dpcd_readb(&lspcon_to_intel_dp(lspcon)->aux, DP_DPCD_REV,
&rev) != 1) {
DRM_DEBUG_KMS("Native AUX CH down\n");
drm_dbg_kms(&i915->drm, "Native AUX CH down\n");
return false;
}
DRM_DEBUG_KMS("Native AUX CH up, DPCD version: %d.%d\n",
rev >> 4, rev & 0xf);
drm_dbg_kms(&i915->drm, "Native AUX CH up, DPCD version: %d.%d\n",
rev >> 4, rev & 0xf);
return true;
}
@ -225,6 +230,7 @@ static bool lspcon_probe(struct intel_lspcon *lspcon)
int retry;
enum drm_dp_dual_mode_type adaptor_type;
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;
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) {
DRM_DEBUG_KMS("No LSPCON detected, found %s\n",
drm_dp_get_dual_mode_type_name(adaptor_type));
drm_dbg_kms(&i915->drm, "No LSPCON detected, found %s\n",
drm_dp_get_dual_mode_type_name(adaptor_type));
return false;
}
/* 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);
/*
@ -258,7 +264,7 @@ static bool lspcon_probe(struct intel_lspcon *lspcon)
*/
if (lspcon->mode != DRM_LSPCON_MODE_PCON) {
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;
}
}
@ -268,13 +274,14 @@ static bool lspcon_probe(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 drm_i915_private *i915 = dp_to_i915(intel_dp);
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
unsigned long start = jiffies;
while (1) {
if (intel_digital_port_connected(&dig_port->base)) {
DRM_DEBUG_KMS("LSPCON recovering in PCON mode after %u ms\n",
jiffies_to_msecs(jiffies - start));
drm_dbg_kms(&i915->drm, "LSPCON recovering in PCON mode after %u ms\n",
jiffies_to_msecs(jiffies - start));
return;
}
@ -284,7 +291,7 @@ static void lspcon_resume_in_pcon_wa(struct intel_lspcon *lspcon)
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)
@ -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,
&avi_if_ctrl, 1);
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;
}
@ -309,7 +316,7 @@ static bool lspcon_parade_fw_ready(struct drm_dp_aux *aux)
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;
}
@ -324,8 +331,8 @@ static bool _lspcon_parade_write_infoframe_blocks(struct drm_dp_aux *aux,
while (block_count < 4) {
if (!lspcon_parade_fw_ready(aux)) {
DRM_DEBUG_KMS("LSPCON FW not ready, block %d\n",
block_count);
drm_dbg_kms(aux->drm_dev, "LSPCON FW not ready, block %d\n",
block_count);
return false;
}
@ -333,8 +340,8 @@ static bool _lspcon_parade_write_infoframe_blocks(struct drm_dp_aux *aux,
data = avi_buf + block_count * 8;
ret = drm_dp_dpcd_write(aux, reg, data, 8);
if (ret < 0) {
DRM_ERROR("Failed to write AVI IF block %d\n",
block_count);
drm_err(aux->drm_dev, "Failed to write AVI IF block %d\n",
block_count);
return false;
}
@ -348,15 +355,15 @@ static bool _lspcon_parade_write_infoframe_blocks(struct drm_dp_aux *aux,
avi_if_ctrl = LSPCON_PARADE_AVI_IF_KICKOFF | block_count;
ret = drm_dp_dpcd_write(aux, reg, &avi_if_ctrl, 1);
if (ret < 0) {
DRM_ERROR("Failed to update (0x%x), block %d\n",
reg, block_count);
drm_err(aux->drm_dev, "Failed to update (0x%x), block %d\n",
reg, block_count);
return false;
}
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;
}
@ -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) {
DRM_ERROR("Invalid length of infoframes\n");
drm_err(aux->drm_dev, "Invalid length of infoframes\n");
return false;
}
memcpy(&avi_if[1], frame, len);
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;
}
@ -412,7 +419,7 @@ static bool _lspcon_write_avi_infoframe_mca(struct drm_dp_aux *aux,
mdelay(50);
continue;
} 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;
}
}
@ -423,7 +430,7 @@ static bool _lspcon_write_avi_infoframe_mca(struct drm_dp_aux *aux,
reg = LSPCON_MCA_AVI_IF_CTRL;
ret = drm_dp_dpcd_read(aux, reg, &val, 1);
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;
}
@ -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);
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;
}
val = 0;
ret = drm_dp_dpcd_read(aux, reg, &val, 1);
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;
}
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;
}
@ -457,6 +464,7 @@ void lspcon_write_infoframe(struct intel_encoder *encoder,
{
bool ret = true;
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);
switch (type) {
@ -469,7 +477,7 @@ void lspcon_write_infoframe(struct intel_encoder *encoder,
frame, len);
break;
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 */
hsw_write_infoframe(encoder, crtc_state, type, frame, len);
break;
@ -478,7 +486,7 @@ void lspcon_write_infoframe(struct intel_encoder *encoder,
}
if (!ret) {
DRM_ERROR("Failed to write infoframes\n");
drm_err(&i915->drm, "Failed to write infoframes\n");
return;
}
}
@ -504,11 +512,12 @@ void lspcon_set_infoframes(struct intel_encoder *encoder,
u8 buf[VIDEO_DIP_DATA_SIZE];
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
struct intel_lspcon *lspcon = &dig_port->lspcon;
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
const struct drm_display_mode *adjusted_mode =
&crtc_state->hw.adjusted_mode;
if (!lspcon->active) {
DRM_ERROR("Writing infoframes while LSPCON disabled ?\n");
drm_err(&i915->drm, "Writing infoframes while LSPCON disabled ?\n");
return;
}
@ -518,7 +527,7 @@ void lspcon_set_infoframes(struct intel_encoder *encoder,
conn_state->connector,
adjusted_mode);
if (ret < 0) {
DRM_ERROR("couldn't fill AVI infoframe\n");
drm_err(&i915->drm, "couldn't fill AVI infoframe\n");
return;
}
@ -559,7 +568,7 @@ void lspcon_set_infoframes(struct intel_encoder *encoder,
ret = hdmi_infoframe_pack(&frame, buf, sizeof(buf));
if (ret < 0) {
DRM_ERROR("Failed to pack AVI IF\n");
drm_err(&i915->drm, "Failed to pack AVI IF\n");
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);
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;
}
@ -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);
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;
}
@ -634,31 +643,32 @@ void lspcon_wait_pcon_mode(struct intel_lspcon *lspcon)
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 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->mode = DRM_LSPCON_MODE_INVALID;
if (!lspcon_probe(lspcon)) {
DRM_ERROR("Failed to probe lspcon\n");
drm_err(&i915->drm, "Failed to probe lspcon\n");
return false;
}
if (drm_dp_read_dpcd_caps(&dp->aux, dp->dpcd) != 0) {
DRM_ERROR("LSPCON DPCD read failed\n");
if (drm_dp_read_dpcd_caps(&intel_dp->aux, intel_dp->dpcd) != 0) {
drm_err(&i915->drm, "LSPCON DPCD read failed\n");
return false;
}
if (!lspcon_detect_vendor(lspcon)) {
DRM_ERROR("LSPCON vendor detection failed\n");
drm_err(&i915->drm, "LSPCON vendor detection failed\n");
return false;
}
connector->ycbcr_420_allowed = true;
lspcon->active = true;
DRM_DEBUG_KMS("Success: LSPCON init\n");
drm_dbg_kms(&i915->drm, "Success: LSPCON init\n");
return true;
}
@ -674,16 +684,16 @@ void lspcon_resume(struct intel_digital_port *dig_port)
{
struct intel_lspcon *lspcon = &dig_port->lspcon;
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;
if (!intel_bios_is_lspcon_present(dev_priv, dig_port->base.port))
if (!intel_bios_is_lspcon_present(i915, dig_port->base.port))
return;
if (!lspcon->active) {
if (!lspcon_init(dig_port)) {
DRM_ERROR("LSPCON init failed on port %c\n",
port_name(dig_port->base.port));
drm_err(&i915->drm, "LSPCON init failed on port %c\n",
port_name(dig_port->base.port));
return;
}
}
@ -699,7 +709,7 @@ void lspcon_resume(struct intel_digital_port *dig_port)
return;
if (lspcon_change_mode(lspcon, DRM_LSPCON_MODE_PCON))
DRM_ERROR("LSPCON resume failed\n");
drm_err(&i915->drm, "LSPCON resume failed\n");
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 "i915_reg.h"
#include "i915_reg_defs.h"
enum pipe;
struct drm_i915_private;

View file

@ -35,6 +35,7 @@
#include "intel_backlight.h"
#include "intel_display_types.h"
#include "intel_opregion.h"
#include "intel_pci_config.h"
#define OPREGION_HEADER_OFFSET 0
#define OPREGION_ACPI_OFFSET 0x100
@ -195,6 +196,8 @@ struct opregion_asle_ext {
#define ASLE_IUER_WINDOWS_BTN (1 << 1)
#define ASLE_IUER_POWER_BTN (1 << 0)
#define ASLE_PHED_EDID_VALID_MASK 0x3
/* Software System Control Interrupt (SWSCI) */
#define SWSCI_SCIC_INDICATOR (1 << 0)
#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;
}
if (mboxes & MBOX_ASLE_EXT)
if (mboxes & MBOX_ASLE_EXT) {
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)
goto out;
@ -1036,6 +1041,54 @@ intel_opregion_get_panel_type(struct drm_i915_private *dev_priv)
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)
{
struct intel_opregion *opregion = &i915->opregion;
@ -1129,6 +1182,7 @@ void intel_opregion_unregister(struct drm_i915_private *i915)
opregion->acpi = NULL;
opregion->swsci = NULL;
opregion->asle = NULL;
opregion->asle_ext = NULL;
opregion->vbt = NULL;
opregion->lid_state = NULL;
}

View file

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

View file

@ -38,6 +38,7 @@
#include "intel_display_types.h"
#include "intel_frontbuffer.h"
#include "intel_overlay.h"
#include "intel_pci_config.h"
/* Limits for overlay size. According to intel doc, the real limits are:
* 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 =
overlay->crtc->config;
if (rec->dst_height == 0 || rec->dst_width == 0)
return -EINVAL;
if (rec->dst_x < pipe_config->pipe_src_w &&
rec->dst_x + rec->dst_width <= pipe_config->pipe_src_w &&
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));
}
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,
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;
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
val |= PIPECONF_8BPC;
val |= PIPECONF_BPC_8;
else
val |= pipeconf_val & PIPECONF_BPC_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) &&
intel_crtc_has_type(crtc_state, INTEL_OUTPUT_SDVO))
val |= TRANS_LEGACY_INTERLACED_ILK;
val |= TRANS_INTERLACE_LEGACY_VSYNC_IBX;
else
val |= TRANS_INTERLACED;
val |= TRANS_INTERLACE_INTERLACED;
} else {
val |= TRANS_PROGRESSIVE;
val |= TRANS_INTERLACE_PROGRESSIVE;
}
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:
* - PCH PLLs
@ -264,6 +322,10 @@ void ilk_pch_enable(struct intel_atomic_state *state,
/* set transcoder timing, panel must allow it */
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);
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 &= ~(TRANS_DP_PORT_SEL_MASK |
TRANS_DP_SYNC_MASK |
TRANS_DP_VSYNC_ACTIVE_HIGH |
TRANS_DP_HSYNC_ACTIVE_HIGH |
TRANS_DP_BPC_MASK);
temp |= TRANS_DP_OUTPUT_ENABLE;
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) >>
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)) {
/*
@ -422,11 +486,10 @@ static void lpt_enable_pch_transcoder(struct drm_i915_private *dev_priv,
val = TRANS_ENABLE;
pipeconf_val = intel_de_read(dev_priv, PIPECONF(cpu_transcoder));
if ((pipeconf_val & PIPECONF_INTERLACE_MASK_HSW) ==
PIPECONF_INTERLACED_ILK)
val |= TRANS_INTERLACED;
if ((pipeconf_val & PIPECONF_INTERLACE_MASK_HSW) == PIPECONF_INTERLACE_IF_ID_ILK)
val |= TRANS_INTERLACE_INTERLACED;
else
val |= TRANS_PROGRESSIVE;
val |= TRANS_INTERLACE_PROGRESSIVE;
intel_de_write(dev_priv, LPT_TRANSCONF, val);
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) >>
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);
}

View file

@ -9,7 +9,10 @@
struct intel_atomic_state;
struct intel_crtc;
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,
struct intel_crtc *crtc);
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);
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

View file

@ -1131,16 +1131,20 @@ intel_pps_readout_hw_state(struct intel_dp *intel_dp, struct edp_power_seq *seq)
}
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",
state_name,
seq->t1_t3, seq->t8, seq->t9, seq->t10, seq->t11_t12);
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,
seq->t1_t3, seq->t8, seq->t9, seq->t10, seq->t11_t12);
}
static void
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 *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 ||
hw.t10 != sw->t10 || hw.t11_t12 != sw->t11_t12) {
DRM_ERROR("PPS state mismatch\n");
intel_pps_dump_state("sw", sw);
intel_pps_dump_state("hw", &hw);
drm_err(&i915->drm, "PPS state mismatch\n");
intel_pps_dump_state(intel_dp, "sw", sw);
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_dump_state("cur", &cur);
intel_pps_dump_state(intel_dp, "cur", &cur);
vbt = dev_priv->vbt.edp.pps;
/* 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. */
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
* unset, fall back to the spec limits. */

View file

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

View file

@ -10,6 +10,7 @@
#include "intel_de.h"
#include "intel_display_types.h"
#include "intel_snps_phy.h"
#include "intel_snps_phy_regs.h"
/**
* DOC: Synopsis PHY support
@ -23,18 +24,18 @@
* 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;
for_each_phy_masked(phy, ~0) {
if (!intel_phy_is_snps(dev_priv, phy))
if (!intel_phy_is_snps(i915, phy))
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))
DRM_ERROR("SNPS PHY %c failed to calibrate after 25ms.\n",
phy);
drm_err(&i915->drm, "SNPS PHY %c failed to calibrate after 25ms.\n",
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,
struct intel_encoder *encoder)
{
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
const struct intel_mpllb_state * const *tables;
int i;
@ -786,8 +788,8 @@ int intel_mpllb_calc_state(struct intel_crtc_state *crtc_state,
* until we have a proper algorithm under a valid
* license.
*/
DRM_DEBUG_KMS("Can't support HDMI link rate %d\n",
crtc_state->port_clock);
drm_dbg_kms(&i915->drm, "Can't support HDMI link rate %d\n",
crtc_state->port_clock);
return -EINVAL;
}
}
@ -854,7 +856,7 @@ void intel_mpllb_enable(struct intel_encoder *encoder,
* dp_mpllb_state interface signal.
*/
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
@ -867,8 +869,8 @@ void intel_mpllb_enable(struct intel_encoder *encoder,
void intel_mpllb_disable(struct intel_encoder *encoder)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
enum phy phy = intel_port_to_phy(i915, encoder->port);
i915_reg_t enable_reg = (phy <= PHY_D ?
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" */
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".
* 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);
/*
* 5. Software polls DPLL_ENABLE [PLL Lock] for PHY acknowledgment
* (dp_txX_ack) that the new transmitter setting request is completed.
*/
if (intel_de_wait_for_clear(dev_priv, enable_reg, PLL_LOCK, 5))
DRM_ERROR("Port %c PLL not locked\n", phy_name(phy));
if (intel_de_wait_for_clear(i915, enable_reg, PLL_LOCK, 5))
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

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)
{
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
const struct drm_framebuffer *fb = plane_state->hw.fb;
struct drm_rect *src = &plane_state->uapi.src;
u32 src_x, src_y, src_w, src_h, hsub, vsub;
@ -94,14 +95,14 @@ int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state)
hsub = vsub = max(hsub, vsub);
if (src_x % hsub || src_w % hsub) {
DRM_DEBUG_KMS("src x/w (%u, %u) must be a multiple of %u (rotated: %s)\n",
src_x, src_w, hsub, yesno(rotated));
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));
return -EINVAL;
}
if (src_y % vsub || src_h % vsub) {
DRM_DEBUG_KMS("src y/h (%u, %u) must be a multiple of %u (rotated: %s)\n",
src_y, src_h, vsub, yesno(rotated));
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));
return -EINVAL;
}
@ -313,7 +314,7 @@ static u32 vlv_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
u32 sprctl = 0;
if (crtc_state->gamma_enable)
sprctl |= SP_GAMMA_ENABLE;
sprctl |= SP_PIPE_GAMMA_ENABLE;
return sprctl;
}
@ -436,9 +437,9 @@ vlv_sprite_update_noarm(struct intel_plane *plane,
intel_de_write_fw(dev_priv, SPSTRIDE(pipe, plane_id),
plane_state->view.color_plane[0].mapping_stride);
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),
((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);
}
@ -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, 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
@ -700,7 +702,7 @@ static u32 ivb_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
u32 sprctl = 0;
if (crtc_state->gamma_enable)
sprctl |= SPRITE_GAMMA_ENABLE;
sprctl |= SPRITE_PIPE_GAMMA_ENABLE;
if (crtc_state->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))
sprctl |= SPRITE_INT_GAMMA_DISABLE;
sprctl |= SPRITE_PLANE_GAMMA_DISABLE;
if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709)
sprctl |= SPRITE_YUV_TO_RGB_CSC_FORMAT_BT709;
@ -863,14 +865,18 @@ ivb_sprite_update_noarm(struct intel_plane *plane,
unsigned long irqflags;
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);
intel_de_write_fw(dev_priv, SPRSTRIDE(pipe),
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, SPRSIZE(pipe), ((crtc_h - 1) << 16) | (crtc_w - 1));
intel_de_write_fw(dev_priv, SPRPOS(pipe),
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))
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
* register */
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 {
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;
if (crtc_state->gamma_enable)
dvscntr |= DVS_GAMMA_ENABLE;
dvscntr |= DVS_PIPE_GAMMA_ENABLE;
if (crtc_state->csc_enable)
dvscntr |= DVS_PIPE_CSC_ENABLE;
@ -1199,14 +1207,18 @@ g4x_sprite_update_noarm(struct intel_plane *plane,
unsigned long irqflags;
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);
intel_de_write_fw(dev_priv, DVSSTRIDE(pipe),
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, DVSSIZE(pipe), ((crtc_h - 1) << 16) | (crtc_w - 1));
intel_de_write_fw(dev_priv, DVSPOS(pipe),
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);
spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
@ -1321,6 +1333,7 @@ static int
g4x_sprite_check_scaling(struct intel_crtc_state *crtc_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_rect *src = &plane_state->uapi.src;
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 (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;
}
min_height = 6;
@ -1358,20 +1371,20 @@ g4x_sprite_check_scaling(struct intel_crtc_state *crtc_state,
if (src_w < min_width || src_h < min_height ||
src_w > 2048 || src_h > 2048) {
DRM_DEBUG_KMS("Source dimensions (%dx%d) exceed hardware limits (%dx%d - %dx%d)\n",
src_w, src_h, min_width, min_height, 2048, 2048);
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);
return -EINVAL;
}
if (width_bytes > 4096) {
DRM_DEBUG_KMS("Fetch width (%d) exceeds hardware max with scaling (%u)\n",
width_bytes, 4096);
drm_dbg_kms(&i915->drm, "Fetch width (%d) exceeds hardware max with scaling (%u)\n",
width_bytes, 4096);
return -EINVAL;
}
if (stride > 4096) {
DRM_DEBUG_KMS("Stride (%u) exceeds hardware max with scaling (%u)\n",
stride, 4096);
drm_dbg_kms(&i915->drm, "Stride (%u) exceeds hardware max with scaling (%u)\n",
stride, 4096);
return -EINVAL;
}

View file

@ -4,10 +4,12 @@
*/
#include "i915_drv.h"
#include "i915_reg.h"
#include "intel_display.h"
#include "intel_display_types.h"
#include "intel_dp_mst.h"
#include "intel_tc.h"
#include "intel_tc_phy_regs.h"
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)
{
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;
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) {
drm_dbg_kms(&i915->drm,
"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_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_12BIT_DVOB 0x01
#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);
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
enum pipe pipe = crtc->pipe;
if (!INTEL_INFO(i915)->display.has_dsc)
return false;
/* On TGL, DSC is supported on all Pipes */
if (DISPLAY_VER(i915) >= 12)
return true;
if (DISPLAY_VER(i915) >= 11 &&
(pipe != PIPE_A || cpu_transcoder == TRANSCODER_EDP ||
cpu_transcoder == TRANSCODER_DSI_0 ||
cpu_transcoder == TRANSCODER_DSI_1))
if (DISPLAY_VER(i915) >= 11 && cpu_transcoder != TRANSCODER_A)
return true;
return false;

View file

@ -7,6 +7,7 @@
#include <linux/vgaarb.h>
#include <drm/i915_drm.h>
#include <video/vga.h>
#include "i915_drv.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 */
vga_get_uninterruptible(pdev, VGA_RSRC_LEGACY_IO);
outb(SR01, VGA_SR_INDEX);
sr1 = inb(VGA_SR_DATA);
outb(sr1 | 1 << 5, VGA_SR_DATA);
outb(0x01, VGA_SEQ_I);
sr1 = inb(VGA_SEQ_D);
outb(sr1 | VGA_SR01_SCREEN_OFF, VGA_SEQ_D);
vga_put(pdev, VGA_RSRC_LEGACY_IO);
udelay(300);
@ -92,7 +93,7 @@ void intel_vga_reset_io_mem(struct drm_i915_private *i915)
* and error messages.
*/
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);
}

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,
int color_plane)
{
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
const struct drm_framebuffer *fb = plane_state->hw.fb;
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
* within the DPT is always 0.
*/
WARN_ON(plane_state->dpt_vma->node.start);
WARN_ON(offset & 0x1fffff);
drm_WARN_ON(&i915->drm, plane_state->dpt_vma->node.start);
drm_WARN_ON(&i915->drm, offset & 0x1fffff);
return offset >> 9;
} else {
WARN_ON(offset & 0xfff);
drm_WARN_ON(&i915->drm, offset & 0xfff);
return offset;
}
}
@ -992,6 +993,54 @@ static u32 skl_plane_surf(const struct intel_plane_state *plane_state,
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)
{
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);
}
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
skl_program_plane_noarm(struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state,
int color_plane)
skl_plane_update_noarm(struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
{
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
enum plane_id plane_id = plane->id;
enum pipe pipe = plane->pipe;
int color_plane = skl_plane_color_plane(plane_state);
u32 stride = skl_plane_stride(plane_state, color_plane);
const struct drm_framebuffer *fb = plane_state->hw.fb;
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)
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),
(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),
((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)) {
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
skl_program_plane_arm(struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state,
int color_plane)
skl_plane_update_arm(struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
{
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
enum plane_id plane_id = plane->id;
enum pipe pipe = plane->pipe;
const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
const struct drm_framebuffer *fb = plane_state->hw.fb;
int aux_plane = skl_main_to_aux_plane(fb, color_plane);
int color_plane = skl_plane_color_plane(plane_state);
u32 x = plane_state->view.color_plane[color_plane].x;
u32 y = plane_state->view.color_plane[color_plane].y;
u32 keymsk, keymax, aux_dist = 0, plane_color_ctl = 0;
u8 alpha = plane_state->hw.alpha >> 8;
u32 plane_color_ctl = 0;
u32 plane_ctl = plane_state->ctl;
unsigned long irqflags;
@ -1100,36 +1155,22 @@ skl_program_plane_arm(struct intel_plane *plane,
plane_color_ctl = plane_state->color_ctl |
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);
intel_de_write_fw(dev_priv, PLANE_KEYVAL(pipe, plane_id),
key->min_value);
intel_de_write_fw(dev_priv, PLANE_KEYMSK(pipe, plane_id), keymsk);
intel_de_write_fw(dev_priv, PLANE_KEYMAX(pipe, plane_id), keymax);
intel_de_write_fw(dev_priv, PLANE_KEYVAL(pipe, plane_id), skl_plane_keyval(plane_state));
intel_de_write_fw(dev_priv, PLANE_KEYMSK(pipe, plane_id), skl_plane_keymsk(plane_state));
intel_de_write_fw(dev_priv, PLANE_KEYMAX(pipe, plane_id), skl_plane_keymax(plane_state));
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)
intel_de_write_fw(dev_priv, PLANE_AUX_OFFSET(pipe, plane_id),
(plane_state->view.color_plane[1].y << 16) |
plane_state->view.color_plane[1].x);
PLANE_OFFSET_Y(plane_state->view.color_plane[1].y) |
PLANE_OFFSET_X(plane_state->view.color_plane[1].x));
if (DISPLAY_VER(dev_priv) >= 10)
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);
}
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)
{
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)
{
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
const struct drm_framebuffer *fb = plane_state->hw.fb;
unsigned int rotation = plane_state->hw.rotation;
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 &&
(rotation == DRM_MODE_ROTATE_270 ||
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;
}
@ -1816,20 +1830,27 @@ static int skl_plane_check(struct intel_crtc_state *crtc_state,
return 0;
}
static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv,
enum pipe pipe, enum plane_id plane_id)
static enum intel_fbc_id skl_fbc_id_for_pipe(enum pipe pipe)
{
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 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,
enum pipe pipe, enum plane_id plane_id)
{
if (skl_plane_has_fbc(dev_priv, pipe, plane_id))
return dev_priv->fbc;
enum intel_fbc_id fbc_id = skl_fbc_id_for_pipe(pipe);
if (skl_plane_has_fbc(dev_priv, fbc_id, plane_id))
return dev_priv->fbc[fbc_id];
else
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));
if (DISPLAY_VER(dev_priv) >= 11)
pixel_format = val & ICL_PLANE_CTL_FORMAT_MASK;
pixel_format = val & PLANE_CTL_FORMAT_MASK_ICL;
else
pixel_format = val & PLANE_CTL_FORMAT_MASK;
pixel_format = val & PLANE_CTL_FORMAT_MASK_SKL;
if (DISPLAY_VER(dev_priv) >= 10) {
alpha = intel_de_read(dev_priv,
PLANE_COLOR_CTL(pipe, plane_id));
alpha &= PLANE_COLOR_ALPHA_MASK;
u32 color_ctl;
color_ctl = intel_de_read(dev_priv, PLANE_COLOR_CTL(pipe, plane_id));
alpha = REG_FIELD_GET(PLANE_COLOR_ALPHA_MASK, color_ctl);
} else {
alpha = val & PLANE_CTL_ALPHA_MASK;
alpha = REG_FIELD_GET(PLANE_CTL_ALPHA_MASK, val);
}
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))
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;
offset = intel_de_read(dev_priv, PLANE_OFFSET(pipe, plane_id));
val = intel_de_read(dev_priv, PLANE_SIZE(pipe, plane_id));
fb->height = ((val >> 16) & 0xffff) + 1;
fb->width = ((val >> 0) & 0xffff) + 1;
fb->height = REG_FIELD_GET(PLANE_HEIGHT_MASK, val) + 1;
fb->width = REG_FIELD_GET(PLANE_WIDTH_MASK, val) + 1;
val = intel_de_read(dev_priv, PLANE_STRIDE(pipe, plane_id));
stride_mult = skl_plane_stride_mult(fb, 0, DRM_MODE_ROTATE_0);
if (DISPLAY_VER(dev_priv) >= 13)
fb->pitches[0] = (val & PLANE_STRIDE_MASK_XELPD) * stride_mult;
else
fb->pitches[0] = (val & PLANE_STRIDE_MASK) * stride_mult;
fb->pitches[0] = REG_FIELD_GET(PLANE_STRIDE__MASK, val) * stride_mult;
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);
}
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);
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))
return PTR_ERR(vaddr);
dma_buf_map_set_vaddr(map, vaddr);
iosys_map_set_vaddr(map, vaddr);
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);

View file

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

View file

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

View file

@ -12,6 +12,8 @@
#include "i915_gem_ioctls.h"
#include "i915_gem_mman.h"
#include "i915_gem_object.h"
#include "i915_gem_tiling.h"
#include "i915_reg.h"
/**
* 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