mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
Merge tag 'drm-intel-next-2025-11-14' of https://gitlab.freedesktop.org/drm/i915/kernel into drm-next
drm/i915 feature pull #2 for v6.19: Features and functionality: - Add initial display support for Xe3p_LPD, display version 35 (Sai Teja, Matt R, Gustavo, Matt A, Ankit, Juha-pekka, Luca, Ravi Kumar) - Compute LT PHY HDMI params when port clock not in predefined tables (Suraj) Refactoring and cleanups: - Refactor intel_frontbuffer split between i915, xe, and display (Ville) - Clean up intel_de_wait_custom() usage (Ville) - Unify display register polling interfaces (Ville) - Finish removal of the expensive format info lookups (Ville) - Cursor code cleanups (Ville) - Convert intel_rom interfaces to struct drm_device (Jani) Fixes: - Fix uninitialized variable in DSI exec packet (Jonathan) - Fix PIPEDMC logging (Alok Tiwari) - Fix PSR pipe to vblank conversion (Jani) - Fix intel_frontbuffer lifetime handling (Ville) - Disable Panel Replay on DP MST for the time being (Imre) Merges: - Backmerge drm-next to get the drm_print.h changes (Jani) Signed-off-by: Dave Airlie <airlied@redhat.com> From: Jani Nikula <jani.nikula@intel.com> Link: https://patch.msgid.link/b131309bb7310ab749f1770aa6e36fa8d6a82fa5@intel.com
This commit is contained in:
@@ -156,6 +156,7 @@ gem-y += \
|
||||
gem/i915_gem_lmem.o \
|
||||
gem/i915_gem_mman.o \
|
||||
gem/i915_gem_object.o \
|
||||
gem/i915_gem_object_frontbuffer.o \
|
||||
gem/i915_gem_pages.o \
|
||||
gem/i915_gem_phys.o \
|
||||
gem/i915_gem_pm.o \
|
||||
|
||||
@@ -56,7 +56,7 @@ static void hsw_ips_enable(const struct intel_crtc_state *crtc_state)
|
||||
* the HW state readout code will complain that the expected
|
||||
* IPS_CTL value is not the one we read.
|
||||
*/
|
||||
if (intel_de_wait_for_set(display, IPS_CTL, IPS_ENABLE, 50))
|
||||
if (intel_de_wait_for_set_ms(display, IPS_CTL, IPS_ENABLE, 50))
|
||||
drm_err(display->drm,
|
||||
"Timed out waiting for IPS enable\n");
|
||||
}
|
||||
@@ -78,7 +78,7 @@ bool hsw_ips_disable(const struct intel_crtc_state *crtc_state)
|
||||
* 42ms timeout value leads to occasional timeouts so use 100ms
|
||||
* instead.
|
||||
*/
|
||||
if (intel_de_wait_for_clear(display, IPS_CTL, IPS_ENABLE, 100))
|
||||
if (intel_de_wait_for_clear_ms(display, IPS_CTL, IPS_ENABLE, 100))
|
||||
drm_err(display->drm,
|
||||
"Timed out waiting for IPS disable\n");
|
||||
} else {
|
||||
|
||||
@@ -754,10 +754,9 @@ static bool i9xx_plane_get_hw_state(struct intel_plane *plane,
|
||||
|
||||
static unsigned int
|
||||
hsw_primary_max_stride(struct intel_plane *plane,
|
||||
u32 pixel_format, u64 modifier,
|
||||
unsigned int rotation)
|
||||
const struct drm_format_info *info,
|
||||
u64 modifier, unsigned int rotation)
|
||||
{
|
||||
const struct drm_format_info *info = drm_format_info(pixel_format);
|
||||
int cpp = info->cpp[0];
|
||||
|
||||
/* Limit to 8k pixels to guarantee OFFSET.x doesn't get too big. */
|
||||
@@ -766,10 +765,9 @@ hsw_primary_max_stride(struct intel_plane *plane,
|
||||
|
||||
static unsigned int
|
||||
ilk_primary_max_stride(struct intel_plane *plane,
|
||||
u32 pixel_format, u64 modifier,
|
||||
unsigned int rotation)
|
||||
const struct drm_format_info *info,
|
||||
u64 modifier, unsigned int rotation)
|
||||
{
|
||||
const struct drm_format_info *info = drm_format_info(pixel_format);
|
||||
int cpp = info->cpp[0];
|
||||
|
||||
/* Limit to 4k pixels to guarantee TILEOFF.x doesn't get too big. */
|
||||
@@ -781,10 +779,9 @@ ilk_primary_max_stride(struct intel_plane *plane,
|
||||
|
||||
unsigned int
|
||||
i965_plane_max_stride(struct intel_plane *plane,
|
||||
u32 pixel_format, u64 modifier,
|
||||
unsigned int rotation)
|
||||
const struct drm_format_info *info,
|
||||
u64 modifier, unsigned int rotation)
|
||||
{
|
||||
const struct drm_format_info *info = drm_format_info(pixel_format);
|
||||
int cpp = info->cpp[0];
|
||||
|
||||
/* Limit to 4k pixels to guarantee TILEOFF.x doesn't get too big. */
|
||||
@@ -796,8 +793,8 @@ i965_plane_max_stride(struct intel_plane *plane,
|
||||
|
||||
static unsigned int
|
||||
i915_plane_max_stride(struct intel_plane *plane,
|
||||
u32 pixel_format, u64 modifier,
|
||||
unsigned int rotation)
|
||||
const struct drm_format_info *info,
|
||||
u64 modifier, unsigned int rotation)
|
||||
{
|
||||
if (modifier == I915_FORMAT_MOD_X_TILED)
|
||||
return 8 * 1024;
|
||||
@@ -807,8 +804,8 @@ i915_plane_max_stride(struct intel_plane *plane,
|
||||
|
||||
static unsigned int
|
||||
i8xx_plane_max_stride(struct intel_plane *plane,
|
||||
u32 pixel_format, u64 modifier,
|
||||
unsigned int rotation)
|
||||
const struct drm_format_info *info,
|
||||
u64 modifier, unsigned int rotation)
|
||||
{
|
||||
if (plane->i9xx_plane == PLANE_C)
|
||||
return 4 * 1024;
|
||||
@@ -1191,10 +1188,8 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
|
||||
val = intel_de_read(display, DSPCNTR(display, i9xx_plane));
|
||||
|
||||
if (DISPLAY_VER(display) >= 4) {
|
||||
if (val & DISP_TILED) {
|
||||
plane_config->tiling = I915_TILING_X;
|
||||
if (val & DISP_TILED)
|
||||
fb->modifier = I915_FORMAT_MOD_X_TILED;
|
||||
}
|
||||
|
||||
if (val & DISP_ROTATE_180)
|
||||
plane_config->rotation = DRM_MODE_ROTATE_180;
|
||||
@@ -1206,14 +1201,15 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
|
||||
|
||||
pixel_format = val & DISP_FORMAT_MASK;
|
||||
fourcc = i9xx_format_to_fourcc(pixel_format);
|
||||
fb->format = drm_format_info(fourcc);
|
||||
|
||||
fb->format = drm_get_format_info(display->drm, fourcc, fb->modifier);
|
||||
|
||||
if (display->platform.haswell || display->platform.broadwell) {
|
||||
offset = intel_de_read(display,
|
||||
DSPOFFSET(display, i9xx_plane));
|
||||
base = intel_de_read(display, DSPSURF(display, i9xx_plane)) & DISP_ADDR_MASK;
|
||||
} else if (DISPLAY_VER(display) >= 4) {
|
||||
if (plane_config->tiling)
|
||||
if (fb->modifier == I915_FORMAT_MOD_X_TILED)
|
||||
offset = intel_de_read(display,
|
||||
DSPTILEOFF(display, i9xx_plane));
|
||||
else
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <linux/types.h>
|
||||
|
||||
enum pipe;
|
||||
struct drm_format_info;
|
||||
struct drm_framebuffer;
|
||||
struct intel_crtc;
|
||||
struct intel_display;
|
||||
@@ -18,8 +19,8 @@ struct intel_plane_state;
|
||||
|
||||
#ifdef I915
|
||||
unsigned int i965_plane_max_stride(struct intel_plane *plane,
|
||||
u32 pixel_format, u64 modifier,
|
||||
unsigned int rotation);
|
||||
const struct drm_format_info *info,
|
||||
u64 modifier, unsigned int rotation);
|
||||
unsigned int vlv_plane_min_alignment(struct intel_plane *plane,
|
||||
const struct drm_framebuffer *fb,
|
||||
int colot_plane);
|
||||
|
||||
@@ -148,9 +148,9 @@ static void wait_for_cmds_dispatched_to_panel(struct intel_encoder *encoder)
|
||||
for_each_dsi_port(port, intel_dsi->ports) {
|
||||
dsi_trans = dsi_port_to_transcoder(port);
|
||||
|
||||
ret = intel_de_wait_custom(display, DSI_LP_MSG(dsi_trans),
|
||||
LPTX_IN_PROGRESS, 0,
|
||||
20, 0, NULL);
|
||||
ret = intel_de_wait_for_clear_us(display,
|
||||
DSI_LP_MSG(dsi_trans),
|
||||
LPTX_IN_PROGRESS, 20);
|
||||
if (ret)
|
||||
drm_err(display->drm, "LPTX bit not cleared\n");
|
||||
}
|
||||
@@ -534,9 +534,8 @@ static void gen11_dsi_enable_ddi_buffer(struct intel_encoder *encoder)
|
||||
for_each_dsi_port(port, intel_dsi->ports) {
|
||||
intel_de_rmw(display, DDI_BUF_CTL(port), 0, DDI_BUF_CTL_ENABLE);
|
||||
|
||||
ret = intel_de_wait_custom(display, DDI_BUF_CTL(port),
|
||||
DDI_BUF_IS_IDLE, 0,
|
||||
500, 0, NULL);
|
||||
ret = intel_de_wait_for_clear_us(display, DDI_BUF_CTL(port),
|
||||
DDI_BUF_IS_IDLE, 500);
|
||||
if (ret)
|
||||
drm_err(display->drm, "DDI port:%c buffer idle\n",
|
||||
port_name(port));
|
||||
@@ -857,9 +856,9 @@ gen11_dsi_configure_transcoder(struct intel_encoder *encoder,
|
||||
|
||||
dsi_trans = dsi_port_to_transcoder(port);
|
||||
|
||||
ret = intel_de_wait_custom(display, DSI_TRANS_FUNC_CONF(dsi_trans),
|
||||
LINK_READY, LINK_READY,
|
||||
2500, 0, NULL);
|
||||
ret = intel_de_wait_for_set_us(display,
|
||||
DSI_TRANS_FUNC_CONF(dsi_trans),
|
||||
LINK_READY, 2500);
|
||||
if (ret)
|
||||
drm_err(display->drm, "DSI link not ready\n");
|
||||
}
|
||||
@@ -1048,8 +1047,8 @@ static void gen11_dsi_enable_transcoder(struct intel_encoder *encoder)
|
||||
TRANSCONF_ENABLE);
|
||||
|
||||
/* wait for transcoder to be enabled */
|
||||
if (intel_de_wait_for_set(display, TRANSCONF(display, dsi_trans),
|
||||
TRANSCONF_STATE_ENABLE, 10))
|
||||
if (intel_de_wait_for_set_ms(display, TRANSCONF(display, dsi_trans),
|
||||
TRANSCONF_STATE_ENABLE, 10))
|
||||
drm_err(display->drm,
|
||||
"DSI transcoder not enabled\n");
|
||||
}
|
||||
@@ -1317,8 +1316,8 @@ static void gen11_dsi_disable_transcoder(struct intel_encoder *encoder)
|
||||
TRANSCONF_ENABLE, 0);
|
||||
|
||||
/* wait for transcoder to be disabled */
|
||||
if (intel_de_wait_for_clear(display, TRANSCONF(display, dsi_trans),
|
||||
TRANSCONF_STATE_ENABLE, 50))
|
||||
if (intel_de_wait_for_clear_ms(display, TRANSCONF(display, dsi_trans),
|
||||
TRANSCONF_STATE_ENABLE, 50))
|
||||
drm_err(display->drm,
|
||||
"DSI trancoder not disabled\n");
|
||||
}
|
||||
@@ -1358,9 +1357,8 @@ static void gen11_dsi_deconfigure_trancoder(struct intel_encoder *encoder)
|
||||
tmp &= ~LINK_ULPS_TYPE_LP11;
|
||||
intel_de_write(display, DSI_LP_MSG(dsi_trans), tmp);
|
||||
|
||||
ret = intel_de_wait_custom(display, DSI_LP_MSG(dsi_trans),
|
||||
LINK_IN_ULPS, LINK_IN_ULPS,
|
||||
10, 0, NULL);
|
||||
ret = intel_de_wait_for_set_us(display, DSI_LP_MSG(dsi_trans),
|
||||
LINK_IN_ULPS, 10);
|
||||
if (ret)
|
||||
drm_err(display->drm, "DSI link not in ULPS\n");
|
||||
}
|
||||
@@ -1395,9 +1393,8 @@ static void gen11_dsi_disable_port(struct intel_encoder *encoder)
|
||||
for_each_dsi_port(port, intel_dsi->ports) {
|
||||
intel_de_rmw(display, DDI_BUF_CTL(port), DDI_BUF_CTL_ENABLE, 0);
|
||||
|
||||
ret = intel_de_wait_custom(display, DDI_BUF_CTL(port),
|
||||
DDI_BUF_IS_IDLE, DDI_BUF_IS_IDLE,
|
||||
8, 0, NULL);
|
||||
ret = intel_de_wait_for_set_us(display, DDI_BUF_CTL(port),
|
||||
DDI_BUF_IS_IDLE, 8);
|
||||
|
||||
if (ret)
|
||||
drm_err(display->drm,
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
|
||||
#include "soc/intel_rom.h"
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "intel_display.h"
|
||||
#include "intel_display_core.h"
|
||||
#include "intel_display_rpm.h"
|
||||
@@ -3145,7 +3144,6 @@ err_free_rom:
|
||||
static const struct vbt_header *intel_bios_get_vbt(struct intel_display *display,
|
||||
size_t *sizep)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
const struct vbt_header *vbt = NULL;
|
||||
|
||||
vbt = firmware_get_vbt(display, sizep);
|
||||
@@ -3159,11 +3157,11 @@ static const struct vbt_header *intel_bios_get_vbt(struct intel_display *display
|
||||
*/
|
||||
if (!vbt && display->platform.dgfx)
|
||||
with_intel_display_rpm(display)
|
||||
vbt = oprom_get_vbt(display, intel_rom_spi(i915), sizep, "SPI flash");
|
||||
vbt = oprom_get_vbt(display, intel_rom_spi(display->drm), sizep, "SPI flash");
|
||||
|
||||
if (!vbt)
|
||||
with_intel_display_rpm(display)
|
||||
vbt = oprom_get_vbt(display, intel_rom_pci(i915), sizep, "PCI ROM");
|
||||
vbt = oprom_get_vbt(display, intel_rom_pci(display->drm), sizep, "PCI ROM");
|
||||
|
||||
return vbt;
|
||||
}
|
||||
|
||||
@@ -29,11 +29,6 @@ bool intel_bo_is_protected(struct drm_gem_object *obj)
|
||||
return i915_gem_object_is_protected(to_intel_bo(obj));
|
||||
}
|
||||
|
||||
void intel_bo_flush_if_display(struct drm_gem_object *obj)
|
||||
{
|
||||
i915_gem_object_flush_if_display(to_intel_bo(obj));
|
||||
}
|
||||
|
||||
int intel_bo_fb_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
|
||||
{
|
||||
return i915_gem_fb_mmap(to_intel_bo(obj), vma);
|
||||
@@ -44,15 +39,40 @@ int intel_bo_read_from_page(struct drm_gem_object *obj, u64 offset, void *dst, i
|
||||
return i915_gem_object_read_from_page(to_intel_bo(obj), offset, dst, size);
|
||||
}
|
||||
|
||||
struct intel_frontbuffer *intel_bo_get_frontbuffer(struct drm_gem_object *obj)
|
||||
struct intel_frontbuffer *intel_bo_frontbuffer_get(struct drm_gem_object *_obj)
|
||||
{
|
||||
return i915_gem_object_get_frontbuffer(to_intel_bo(obj));
|
||||
struct drm_i915_gem_object *obj = to_intel_bo(_obj);
|
||||
struct i915_frontbuffer *front;
|
||||
|
||||
front = i915_gem_object_frontbuffer_get(obj);
|
||||
if (!front)
|
||||
return NULL;
|
||||
|
||||
return &front->base;
|
||||
}
|
||||
|
||||
struct intel_frontbuffer *intel_bo_set_frontbuffer(struct drm_gem_object *obj,
|
||||
struct intel_frontbuffer *front)
|
||||
void intel_bo_frontbuffer_ref(struct intel_frontbuffer *_front)
|
||||
{
|
||||
return i915_gem_object_set_frontbuffer(to_intel_bo(obj), front);
|
||||
struct i915_frontbuffer *front =
|
||||
container_of(_front, typeof(*front), base);
|
||||
|
||||
i915_gem_object_frontbuffer_ref(front);
|
||||
}
|
||||
|
||||
void intel_bo_frontbuffer_put(struct intel_frontbuffer *_front)
|
||||
{
|
||||
struct i915_frontbuffer *front =
|
||||
container_of(_front, typeof(*front), base);
|
||||
|
||||
return i915_gem_object_frontbuffer_put(front);
|
||||
}
|
||||
|
||||
void intel_bo_frontbuffer_flush_for_display(struct intel_frontbuffer *_front)
|
||||
{
|
||||
struct i915_frontbuffer *front =
|
||||
container_of(_front, typeof(*front), base);
|
||||
|
||||
i915_gem_object_flush_if_display(front->obj);
|
||||
}
|
||||
|
||||
void intel_bo_describe(struct seq_file *m, struct drm_gem_object *obj)
|
||||
|
||||
@@ -16,13 +16,13 @@ bool intel_bo_is_tiled(struct drm_gem_object *obj);
|
||||
bool intel_bo_is_userptr(struct drm_gem_object *obj);
|
||||
bool intel_bo_is_shmem(struct drm_gem_object *obj);
|
||||
bool intel_bo_is_protected(struct drm_gem_object *obj);
|
||||
void intel_bo_flush_if_display(struct drm_gem_object *obj);
|
||||
int intel_bo_fb_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma);
|
||||
int intel_bo_read_from_page(struct drm_gem_object *obj, u64 offset, void *dst, int size);
|
||||
|
||||
struct intel_frontbuffer *intel_bo_get_frontbuffer(struct drm_gem_object *obj);
|
||||
struct intel_frontbuffer *intel_bo_set_frontbuffer(struct drm_gem_object *obj,
|
||||
struct intel_frontbuffer *front);
|
||||
struct intel_frontbuffer *intel_bo_frontbuffer_get(struct drm_gem_object *obj);
|
||||
void intel_bo_frontbuffer_ref(struct intel_frontbuffer *front);
|
||||
void intel_bo_frontbuffer_put(struct intel_frontbuffer *front);
|
||||
void intel_bo_frontbuffer_flush_for_display(struct intel_frontbuffer *front);
|
||||
|
||||
void intel_bo_describe(struct seq_file *m, struct drm_gem_object *obj);
|
||||
|
||||
|
||||
@@ -805,29 +805,40 @@ void intel_bw_init_hw(struct intel_display *display)
|
||||
if (!HAS_DISPLAY(display))
|
||||
return;
|
||||
|
||||
if (DISPLAY_VERx100(display) >= 3002)
|
||||
tgl_get_bw_info(display, dram_info, &xe3lpd_3002_sa_info);
|
||||
else if (DISPLAY_VER(display) >= 30)
|
||||
tgl_get_bw_info(display, dram_info, &xe3lpd_sa_info);
|
||||
else if (DISPLAY_VERx100(display) >= 1401 && display->platform.dgfx &&
|
||||
dram_info->type == INTEL_DRAM_GDDR_ECC)
|
||||
xe2_hpd_get_bw_info(display, dram_info, &xe2_hpd_ecc_sa_info);
|
||||
else if (DISPLAY_VERx100(display) >= 1401 && display->platform.dgfx)
|
||||
xe2_hpd_get_bw_info(display, dram_info, &xe2_hpd_sa_info);
|
||||
else if (DISPLAY_VER(display) >= 14)
|
||||
/*
|
||||
* Starting with Xe3p_LPD, the hardware tells us whether memory has ECC
|
||||
* enabled that would impact display bandwidth. However, so far there
|
||||
* are no instructions in Bspec on how to handle that case. Let's
|
||||
* complain if we ever find such a scenario.
|
||||
*/
|
||||
if (DISPLAY_VER(display) >= 35)
|
||||
drm_WARN_ON(display->drm, dram_info->ecc_impacting_de_bw);
|
||||
|
||||
if (DISPLAY_VER(display) >= 30) {
|
||||
if (DISPLAY_VERx100(display) == 3002)
|
||||
tgl_get_bw_info(display, dram_info, &xe3lpd_3002_sa_info);
|
||||
else
|
||||
tgl_get_bw_info(display, dram_info, &xe3lpd_sa_info);
|
||||
} else if (DISPLAY_VERx100(display) >= 1401 && display->platform.dgfx) {
|
||||
if (dram_info->type == INTEL_DRAM_GDDR_ECC)
|
||||
xe2_hpd_get_bw_info(display, dram_info, &xe2_hpd_ecc_sa_info);
|
||||
else
|
||||
xe2_hpd_get_bw_info(display, dram_info, &xe2_hpd_sa_info);
|
||||
} else if (DISPLAY_VER(display) >= 14) {
|
||||
tgl_get_bw_info(display, dram_info, &mtl_sa_info);
|
||||
else if (display->platform.dg2)
|
||||
} else if (display->platform.dg2) {
|
||||
dg2_get_bw_info(display);
|
||||
else if (display->platform.alderlake_p)
|
||||
} else if (display->platform.alderlake_p) {
|
||||
tgl_get_bw_info(display, dram_info, &adlp_sa_info);
|
||||
else if (display->platform.alderlake_s)
|
||||
} else if (display->platform.alderlake_s) {
|
||||
tgl_get_bw_info(display, dram_info, &adls_sa_info);
|
||||
else if (display->platform.rocketlake)
|
||||
} else if (display->platform.rocketlake) {
|
||||
tgl_get_bw_info(display, dram_info, &rkl_sa_info);
|
||||
else if (DISPLAY_VER(display) == 12)
|
||||
} else if (DISPLAY_VER(display) == 12) {
|
||||
tgl_get_bw_info(display, dram_info, &tgl_sa_info);
|
||||
else if (DISPLAY_VER(display) == 11)
|
||||
} else if (DISPLAY_VER(display) == 11) {
|
||||
icl_get_bw_info(display, dram_info, &icl_sa_info);
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int intel_bw_num_active_planes(struct intel_display *display,
|
||||
|
||||
@@ -902,9 +902,8 @@ static void bdw_set_cdclk(struct intel_display *display,
|
||||
* According to the spec, it should be enough to poll for this 1 us.
|
||||
* However, extensive testing shows that this can take longer.
|
||||
*/
|
||||
ret = intel_de_wait_custom(display, LCPLL_CTL,
|
||||
LCPLL_CD_SOURCE_FCLK_DONE, LCPLL_CD_SOURCE_FCLK_DONE,
|
||||
100, 0, NULL);
|
||||
ret = intel_de_wait_for_set_us(display, LCPLL_CTL,
|
||||
LCPLL_CD_SOURCE_FCLK_DONE, 100);
|
||||
if (ret)
|
||||
drm_err(display->drm, "Switching to FCLK failed\n");
|
||||
|
||||
@@ -914,9 +913,8 @@ static void bdw_set_cdclk(struct intel_display *display,
|
||||
intel_de_rmw(display, LCPLL_CTL,
|
||||
LCPLL_CD_SOURCE_FCLK, 0);
|
||||
|
||||
ret = intel_de_wait_custom(display, LCPLL_CTL,
|
||||
LCPLL_CD_SOURCE_FCLK_DONE, 0,
|
||||
1, 0, NULL);
|
||||
ret = intel_de_wait_for_clear_us(display, LCPLL_CTL,
|
||||
LCPLL_CD_SOURCE_FCLK_DONE, 1);
|
||||
if (ret)
|
||||
drm_err(display->drm, "Switching back to LCPLL failed\n");
|
||||
|
||||
@@ -1114,7 +1112,7 @@ static void skl_dpll0_enable(struct intel_display *display, int vco)
|
||||
intel_de_rmw(display, LCPLL1_CTL,
|
||||
0, LCPLL_PLL_ENABLE);
|
||||
|
||||
if (intel_de_wait_for_set(display, LCPLL1_CTL, LCPLL_PLL_LOCK, 5))
|
||||
if (intel_de_wait_for_set_ms(display, LCPLL1_CTL, LCPLL_PLL_LOCK, 5))
|
||||
drm_err(display->drm, "DPLL0 not locked\n");
|
||||
|
||||
display->cdclk.hw.vco = vco;
|
||||
@@ -1128,7 +1126,7 @@ static void skl_dpll0_disable(struct intel_display *display)
|
||||
intel_de_rmw(display, LCPLL1_CTL,
|
||||
LCPLL_PLL_ENABLE, 0);
|
||||
|
||||
if (intel_de_wait_for_clear(display, LCPLL1_CTL, LCPLL_PLL_LOCK, 1))
|
||||
if (intel_de_wait_for_clear_ms(display, LCPLL1_CTL, LCPLL_PLL_LOCK, 1))
|
||||
drm_err(display->drm, "Couldn't disable DPLL0\n");
|
||||
|
||||
display->cdclk.hw.vco = 0;
|
||||
@@ -1535,6 +1533,41 @@ static const struct intel_cdclk_vals xe3lpd_cdclk_table[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct intel_cdclk_vals xe3p_lpd_cdclk_table[] = {
|
||||
{ .refclk = 38400, .cdclk = 151200, .ratio = 21, .waveform = 0xa4a4 },
|
||||
{ .refclk = 38400, .cdclk = 176400, .ratio = 21, .waveform = 0xaa54 },
|
||||
{ .refclk = 38400, .cdclk = 201600, .ratio = 21, .waveform = 0xaaaa },
|
||||
{ .refclk = 38400, .cdclk = 226800, .ratio = 21, .waveform = 0xad5a },
|
||||
{ .refclk = 38400, .cdclk = 252000, .ratio = 21, .waveform = 0xb6b6 },
|
||||
{ .refclk = 38400, .cdclk = 277200, .ratio = 21, .waveform = 0xdbb6 },
|
||||
{ .refclk = 38400, .cdclk = 302400, .ratio = 21, .waveform = 0xeeee },
|
||||
{ .refclk = 38400, .cdclk = 327600, .ratio = 21, .waveform = 0xf7de },
|
||||
{ .refclk = 38400, .cdclk = 352800, .ratio = 21, .waveform = 0xfefe },
|
||||
{ .refclk = 38400, .cdclk = 378000, .ratio = 21, .waveform = 0xfffe },
|
||||
{ .refclk = 38400, .cdclk = 403200, .ratio = 21, .waveform = 0xffff },
|
||||
{ .refclk = 38400, .cdclk = 422400, .ratio = 22, .waveform = 0xffff },
|
||||
{ .refclk = 38400, .cdclk = 441600, .ratio = 23, .waveform = 0xffff },
|
||||
{ .refclk = 38400, .cdclk = 460800, .ratio = 24, .waveform = 0xffff },
|
||||
{ .refclk = 38400, .cdclk = 480000, .ratio = 25, .waveform = 0xffff },
|
||||
{ .refclk = 38400, .cdclk = 499200, .ratio = 26, .waveform = 0xffff },
|
||||
{ .refclk = 38400, .cdclk = 518400, .ratio = 27, .waveform = 0xffff },
|
||||
{ .refclk = 38400, .cdclk = 537600, .ratio = 28, .waveform = 0xffff },
|
||||
{ .refclk = 38400, .cdclk = 556800, .ratio = 29, .waveform = 0xffff },
|
||||
{ .refclk = 38400, .cdclk = 576000, .ratio = 30, .waveform = 0xffff },
|
||||
{ .refclk = 38400, .cdclk = 595200, .ratio = 31, .waveform = 0xffff },
|
||||
{ .refclk = 38400, .cdclk = 614400, .ratio = 32, .waveform = 0xffff },
|
||||
{ .refclk = 38400, .cdclk = 633600, .ratio = 33, .waveform = 0xffff },
|
||||
{ .refclk = 38400, .cdclk = 652800, .ratio = 34, .waveform = 0xffff },
|
||||
{ .refclk = 38400, .cdclk = 672000, .ratio = 35, .waveform = 0xffff },
|
||||
{ .refclk = 38400, .cdclk = 691200, .ratio = 36, .waveform = 0xffff },
|
||||
{ .refclk = 38400, .cdclk = 710400, .ratio = 37, .waveform = 0xffff },
|
||||
{ .refclk = 38400, .cdclk = 729600, .ratio = 38, .waveform = 0xffff },
|
||||
{ .refclk = 38400, .cdclk = 748800, .ratio = 39, .waveform = 0xffff },
|
||||
{ .refclk = 38400, .cdclk = 768000, .ratio = 40, .waveform = 0xffff },
|
||||
{ .refclk = 38400, .cdclk = 787200, .ratio = 41, .waveform = 0xffff },
|
||||
{}
|
||||
};
|
||||
|
||||
static const int cdclk_squash_len = 16;
|
||||
|
||||
static int cdclk_squash_divider(u16 waveform)
|
||||
@@ -1800,8 +1833,8 @@ static void bxt_de_pll_disable(struct intel_display *display)
|
||||
intel_de_write(display, BXT_DE_PLL_ENABLE, 0);
|
||||
|
||||
/* Timeout 200us */
|
||||
if (intel_de_wait_for_clear(display,
|
||||
BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK, 1))
|
||||
if (intel_de_wait_for_clear_ms(display,
|
||||
BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK, 1))
|
||||
drm_err(display->drm, "timeout waiting for DE PLL unlock\n");
|
||||
|
||||
display->cdclk.hw.vco = 0;
|
||||
@@ -1817,8 +1850,8 @@ static void bxt_de_pll_enable(struct intel_display *display, int vco)
|
||||
intel_de_write(display, BXT_DE_PLL_ENABLE, BXT_DE_PLL_PLL_ENABLE);
|
||||
|
||||
/* Timeout 200us */
|
||||
if (intel_de_wait_for_set(display,
|
||||
BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK, 1))
|
||||
if (intel_de_wait_for_set_ms(display,
|
||||
BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK, 1))
|
||||
drm_err(display->drm, "timeout waiting for DE PLL lock\n");
|
||||
|
||||
display->cdclk.hw.vco = vco;
|
||||
@@ -1830,7 +1863,7 @@ static void icl_cdclk_pll_disable(struct intel_display *display)
|
||||
BXT_DE_PLL_PLL_ENABLE, 0);
|
||||
|
||||
/* Timeout 200us */
|
||||
if (intel_de_wait_for_clear(display, BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK, 1))
|
||||
if (intel_de_wait_for_clear_ms(display, BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK, 1))
|
||||
drm_err(display->drm, "timeout waiting for CDCLK PLL unlock\n");
|
||||
|
||||
display->cdclk.hw.vco = 0;
|
||||
@@ -1848,7 +1881,7 @@ static void icl_cdclk_pll_enable(struct intel_display *display, int vco)
|
||||
intel_de_write(display, BXT_DE_PLL_ENABLE, val);
|
||||
|
||||
/* Timeout 200us */
|
||||
if (intel_de_wait_for_set(display, BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK, 1))
|
||||
if (intel_de_wait_for_set_ms(display, BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK, 1))
|
||||
drm_err(display->drm, "timeout waiting for CDCLK PLL lock\n");
|
||||
|
||||
display->cdclk.hw.vco = vco;
|
||||
@@ -1868,8 +1901,8 @@ static void adlp_cdclk_pll_crawl(struct intel_display *display, int vco)
|
||||
intel_de_write(display, BXT_DE_PLL_ENABLE, val);
|
||||
|
||||
/* Timeout 200us */
|
||||
if (intel_de_wait_for_set(display, BXT_DE_PLL_ENABLE,
|
||||
BXT_DE_PLL_LOCK | BXT_DE_PLL_FREQ_REQ_ACK, 1))
|
||||
if (intel_de_wait_for_set_ms(display, BXT_DE_PLL_ENABLE,
|
||||
BXT_DE_PLL_LOCK | BXT_DE_PLL_FREQ_REQ_ACK, 1))
|
||||
drm_err(display->drm, "timeout waiting for FREQ change request ack\n");
|
||||
|
||||
val &= ~BXT_DE_PLL_FREQ_REQ;
|
||||
@@ -3561,7 +3594,9 @@ static int intel_compute_max_dotclk(struct intel_display *display)
|
||||
*/
|
||||
void intel_update_max_cdclk(struct intel_display *display)
|
||||
{
|
||||
if (DISPLAY_VERx100(display) >= 3002) {
|
||||
if (DISPLAY_VER(display) >= 35) {
|
||||
display->cdclk.max_cdclk_freq = 787200;
|
||||
} else if (DISPLAY_VERx100(display) >= 3002) {
|
||||
display->cdclk.max_cdclk_freq = 480000;
|
||||
} else if (DISPLAY_VER(display) >= 30) {
|
||||
display->cdclk.max_cdclk_freq = 691200;
|
||||
@@ -3912,7 +3947,10 @@ static const struct intel_cdclk_funcs i830_cdclk_funcs = {
|
||||
*/
|
||||
void intel_init_cdclk_hooks(struct intel_display *display)
|
||||
{
|
||||
if (DISPLAY_VER(display) >= 30) {
|
||||
if (DISPLAY_VER(display) >= 35) {
|
||||
display->funcs.cdclk = &xe3lpd_cdclk_funcs;
|
||||
display->cdclk.table = xe3p_lpd_cdclk_table;
|
||||
} else if (DISPLAY_VER(display) >= 30) {
|
||||
display->funcs.cdclk = &xe3lpd_cdclk_funcs;
|
||||
display->cdclk.table = xe3lpd_cdclk_table;
|
||||
} else if (DISPLAY_VER(display) >= 20) {
|
||||
|
||||
@@ -1090,18 +1090,19 @@ static void skl_get_config(struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
u32 tmp;
|
||||
|
||||
crtc_state->gamma_mode = hsw_read_gamma_mode(crtc);
|
||||
crtc_state->csc_mode = ilk_read_csc_mode(crtc);
|
||||
|
||||
tmp = intel_de_read(display, SKL_BOTTOM_COLOR(crtc->pipe));
|
||||
if (DISPLAY_VER(display) < 35) {
|
||||
u32 tmp = intel_de_read(display, SKL_BOTTOM_COLOR(crtc->pipe));
|
||||
|
||||
if (tmp & SKL_BOTTOM_COLOR_GAMMA_ENABLE)
|
||||
crtc_state->gamma_enable = true;
|
||||
if (tmp & SKL_BOTTOM_COLOR_GAMMA_ENABLE)
|
||||
crtc_state->gamma_enable = true;
|
||||
|
||||
if (tmp & SKL_BOTTOM_COLOR_CSC_ENABLE)
|
||||
crtc_state->csc_enable = true;
|
||||
if (tmp & SKL_BOTTOM_COLOR_CSC_ENABLE)
|
||||
crtc_state->csc_enable = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void skl_color_commit_arm(struct intel_dsb *dsb,
|
||||
|
||||
@@ -498,10 +498,10 @@ static bool ilk_crt_detect_hotplug(struct drm_connector *connector)
|
||||
|
||||
intel_de_write(display, crt->adpa_reg, adpa);
|
||||
|
||||
if (intel_de_wait_for_clear(display,
|
||||
crt->adpa_reg,
|
||||
ADPA_CRT_HOTPLUG_FORCE_TRIGGER,
|
||||
1000))
|
||||
if (intel_de_wait_for_clear_ms(display,
|
||||
crt->adpa_reg,
|
||||
ADPA_CRT_HOTPLUG_FORCE_TRIGGER,
|
||||
1000))
|
||||
drm_dbg_kms(display->drm,
|
||||
"timed out waiting for FORCE_TRIGGER");
|
||||
|
||||
@@ -553,8 +553,8 @@ static bool valleyview_crt_detect_hotplug(struct drm_connector *connector)
|
||||
|
||||
intel_de_write(display, crt->adpa_reg, adpa);
|
||||
|
||||
if (intel_de_wait_for_clear(display, crt->adpa_reg,
|
||||
ADPA_CRT_HOTPLUG_FORCE_TRIGGER, 1000)) {
|
||||
if (intel_de_wait_for_clear_ms(display, crt->adpa_reg,
|
||||
ADPA_CRT_HOTPLUG_FORCE_TRIGGER, 1000)) {
|
||||
drm_dbg_kms(display->drm,
|
||||
"timed out waiting for FORCE_TRIGGER");
|
||||
intel_de_write(display, crt->adpa_reg, save_adpa);
|
||||
@@ -604,8 +604,8 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
|
||||
CRT_HOTPLUG_FORCE_DETECT,
|
||||
CRT_HOTPLUG_FORCE_DETECT);
|
||||
/* wait for FORCE_DETECT to go off */
|
||||
if (intel_de_wait_for_clear(display, PORT_HOTPLUG_EN(display),
|
||||
CRT_HOTPLUG_FORCE_DETECT, 1000))
|
||||
if (intel_de_wait_for_clear_ms(display, PORT_HOTPLUG_EN(display),
|
||||
CRT_HOTPLUG_FORCE_DETECT, 1000))
|
||||
drm_dbg_kms(display->drm,
|
||||
"timed out waiting for FORCE_DETECT to go off");
|
||||
}
|
||||
|
||||
@@ -182,8 +182,8 @@ static int intel_check_cursor(struct intel_crtc_state *crtc_state,
|
||||
|
||||
static unsigned int
|
||||
i845_cursor_max_stride(struct intel_plane *plane,
|
||||
u32 pixel_format, u64 modifier,
|
||||
unsigned int rotation)
|
||||
const struct drm_format_info *info,
|
||||
u64 modifier, unsigned int rotation)
|
||||
{
|
||||
return 2048;
|
||||
}
|
||||
@@ -343,8 +343,8 @@ static bool i845_cursor_get_hw_state(struct intel_plane *plane,
|
||||
|
||||
static unsigned int
|
||||
i9xx_cursor_max_stride(struct intel_plane *plane,
|
||||
u32 pixel_format, u64 modifier,
|
||||
unsigned int rotation)
|
||||
const struct drm_format_info *info,
|
||||
u64 modifier, unsigned int rotation)
|
||||
{
|
||||
return plane->base.dev->mode_config.cursor_width * 4;
|
||||
}
|
||||
@@ -1092,3 +1092,23 @@ fail:
|
||||
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
void intel_cursor_mode_config_init(struct intel_display *display)
|
||||
{
|
||||
struct drm_mode_config *mode_config = &display->drm->mode_config;
|
||||
|
||||
if (display->platform.i845g) {
|
||||
mode_config->cursor_width = 64;
|
||||
mode_config->cursor_height = 1023;
|
||||
} else if (display->platform.i865g) {
|
||||
mode_config->cursor_width = 512;
|
||||
mode_config->cursor_height = 1023;
|
||||
} else if (display->platform.i830 || display->platform.i85x ||
|
||||
display->platform.i915g || display->platform.i915gm) {
|
||||
mode_config->cursor_width = 64;
|
||||
mode_config->cursor_height = 64;
|
||||
} else {
|
||||
mode_config->cursor_width = 256;
|
||||
mode_config->cursor_height = 256;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,4 +17,6 @@ intel_cursor_plane_create(struct intel_display *display,
|
||||
|
||||
void intel_cursor_unpin_work(struct kthread_work *base);
|
||||
|
||||
void intel_cursor_mode_config_init(struct intel_display *display);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -145,9 +145,9 @@ void intel_cx0_bus_reset(struct intel_encoder *encoder, int lane)
|
||||
intel_de_write(display, XELPDP_PORT_M2P_MSGBUS_CTL(display, port, lane),
|
||||
XELPDP_PORT_M2P_TRANSACTION_RESET);
|
||||
|
||||
if (intel_de_wait_for_clear(display, XELPDP_PORT_M2P_MSGBUS_CTL(display, port, lane),
|
||||
XELPDP_PORT_M2P_TRANSACTION_RESET,
|
||||
XELPDP_MSGBUS_TIMEOUT_SLOW)) {
|
||||
if (intel_de_wait_for_clear_ms(display, XELPDP_PORT_M2P_MSGBUS_CTL(display, port, lane),
|
||||
XELPDP_PORT_M2P_TRANSACTION_RESET,
|
||||
XELPDP_MSGBUS_TIMEOUT_MS)) {
|
||||
drm_err_once(display->drm,
|
||||
"Failed to bring PHY %c to idle.\n",
|
||||
phy_name(phy));
|
||||
@@ -164,12 +164,10 @@ int intel_cx0_wait_for_ack(struct intel_encoder *encoder,
|
||||
enum port port = encoder->port;
|
||||
enum phy phy = intel_encoder_to_phy(encoder);
|
||||
|
||||
if (intel_de_wait_custom(display,
|
||||
XELPDP_PORT_P2M_MSGBUS_STATUS(display, port, lane),
|
||||
XELPDP_PORT_P2M_RESPONSE_READY,
|
||||
XELPDP_PORT_P2M_RESPONSE_READY,
|
||||
XELPDP_MSGBUS_TIMEOUT_FAST_US,
|
||||
XELPDP_MSGBUS_TIMEOUT_SLOW, val)) {
|
||||
if (intel_de_wait_ms(display, XELPDP_PORT_P2M_MSGBUS_STATUS(display, port, lane),
|
||||
XELPDP_PORT_P2M_RESPONSE_READY,
|
||||
XELPDP_PORT_P2M_RESPONSE_READY,
|
||||
XELPDP_MSGBUS_TIMEOUT_MS, val)) {
|
||||
drm_dbg_kms(display->drm,
|
||||
"PHY %c Timeout waiting for message ACK. Status: 0x%x\n",
|
||||
phy_name(phy), *val);
|
||||
@@ -214,9 +212,9 @@ static int __intel_cx0_read_once(struct intel_encoder *encoder,
|
||||
int ack;
|
||||
u32 val;
|
||||
|
||||
if (intel_de_wait_for_clear(display, XELPDP_PORT_M2P_MSGBUS_CTL(display, port, lane),
|
||||
XELPDP_PORT_M2P_TRANSACTION_PENDING,
|
||||
XELPDP_MSGBUS_TIMEOUT_SLOW)) {
|
||||
if (intel_de_wait_for_clear_ms(display, XELPDP_PORT_M2P_MSGBUS_CTL(display, port, lane),
|
||||
XELPDP_PORT_M2P_TRANSACTION_PENDING,
|
||||
XELPDP_MSGBUS_TIMEOUT_MS)) {
|
||||
drm_dbg_kms(display->drm,
|
||||
"PHY %c Timeout waiting for previous transaction to complete. Reset the bus and retry.\n", phy_name(phy));
|
||||
intel_cx0_bus_reset(encoder, lane);
|
||||
@@ -285,9 +283,9 @@ static int __intel_cx0_write_once(struct intel_encoder *encoder,
|
||||
int ack;
|
||||
u32 val;
|
||||
|
||||
if (intel_de_wait_for_clear(display, XELPDP_PORT_M2P_MSGBUS_CTL(display, port, lane),
|
||||
XELPDP_PORT_M2P_TRANSACTION_PENDING,
|
||||
XELPDP_MSGBUS_TIMEOUT_SLOW)) {
|
||||
if (intel_de_wait_for_clear_ms(display, XELPDP_PORT_M2P_MSGBUS_CTL(display, port, lane),
|
||||
XELPDP_PORT_M2P_TRANSACTION_PENDING,
|
||||
XELPDP_MSGBUS_TIMEOUT_MS)) {
|
||||
drm_dbg_kms(display->drm,
|
||||
"PHY %c Timeout waiting for previous transaction to complete. Resetting the bus.\n", phy_name(phy));
|
||||
intel_cx0_bus_reset(encoder, lane);
|
||||
@@ -301,9 +299,9 @@ static int __intel_cx0_write_once(struct intel_encoder *encoder,
|
||||
XELPDP_PORT_M2P_DATA(data) |
|
||||
XELPDP_PORT_M2P_ADDRESS(addr));
|
||||
|
||||
if (intel_de_wait_for_clear(display, XELPDP_PORT_M2P_MSGBUS_CTL(display, port, lane),
|
||||
XELPDP_PORT_M2P_TRANSACTION_PENDING,
|
||||
XELPDP_MSGBUS_TIMEOUT_SLOW)) {
|
||||
if (intel_de_wait_for_clear_ms(display, XELPDP_PORT_M2P_MSGBUS_CTL(display, port, lane),
|
||||
XELPDP_PORT_M2P_TRANSACTION_PENDING,
|
||||
XELPDP_MSGBUS_TIMEOUT_MS)) {
|
||||
drm_dbg_kms(display->drm,
|
||||
"PHY %c Timeout waiting for write to complete. Resetting the bus.\n", phy_name(phy));
|
||||
intel_cx0_bus_reset(encoder, lane);
|
||||
@@ -2814,9 +2812,9 @@ void intel_cx0_powerdown_change_sequence(struct intel_encoder *encoder,
|
||||
|
||||
/* Wait for pending transactions.*/
|
||||
for_each_cx0_lane_in_mask(lane_mask, lane)
|
||||
if (intel_de_wait_for_clear(display, XELPDP_PORT_M2P_MSGBUS_CTL(display, port, lane),
|
||||
XELPDP_PORT_M2P_TRANSACTION_PENDING,
|
||||
XELPDP_MSGBUS_TIMEOUT_SLOW)) {
|
||||
if (intel_de_wait_for_clear_ms(display, XELPDP_PORT_M2P_MSGBUS_CTL(display, port, lane),
|
||||
XELPDP_PORT_M2P_TRANSACTION_PENDING,
|
||||
XELPDP_MSGBUS_TIMEOUT_MS)) {
|
||||
drm_dbg_kms(display->drm,
|
||||
"PHY %c Timeout waiting for previous transaction to complete. Reset the bus.\n",
|
||||
phy_name(phy));
|
||||
@@ -2828,12 +2826,12 @@ void intel_cx0_powerdown_change_sequence(struct intel_encoder *encoder,
|
||||
intel_cx0_get_powerdown_update(lane_mask));
|
||||
|
||||
/* Update Timeout Value */
|
||||
if (intel_de_wait_custom(display, buf_ctl2_reg,
|
||||
intel_cx0_get_powerdown_update(lane_mask), 0,
|
||||
XELPDP_PORT_POWERDOWN_UPDATE_TIMEOUT_US, 2, NULL))
|
||||
if (intel_de_wait_for_clear_ms(display, buf_ctl2_reg,
|
||||
intel_cx0_get_powerdown_update(lane_mask),
|
||||
XELPDP_PORT_POWERDOWN_UPDATE_TIMEOUT_MS))
|
||||
drm_warn(display->drm,
|
||||
"PHY %c failed to bring out of Lane reset after %dus.\n",
|
||||
phy_name(phy), XELPDP_PORT_RESET_START_TIMEOUT_US);
|
||||
"PHY %c failed to bring out of lane reset\n",
|
||||
phy_name(phy));
|
||||
}
|
||||
|
||||
void intel_cx0_setup_powerdown(struct intel_encoder *encoder)
|
||||
@@ -2889,35 +2887,34 @@ static void intel_cx0_phy_lane_reset(struct intel_encoder *encoder,
|
||||
XELPDP_LANE_PHY_CURRENT_STATUS(1))
|
||||
: XELPDP_LANE_PHY_CURRENT_STATUS(0);
|
||||
|
||||
if (intel_de_wait_custom(display, XELPDP_PORT_BUF_CTL1(display, port),
|
||||
XELPDP_PORT_BUF_SOC_PHY_READY,
|
||||
XELPDP_PORT_BUF_SOC_PHY_READY,
|
||||
XELPDP_PORT_BUF_SOC_READY_TIMEOUT_US, 0, NULL))
|
||||
if (intel_de_wait_for_set_us(display, XELPDP_PORT_BUF_CTL1(display, port),
|
||||
XELPDP_PORT_BUF_SOC_PHY_READY,
|
||||
XELPDP_PORT_BUF_SOC_READY_TIMEOUT_US))
|
||||
drm_warn(display->drm,
|
||||
"PHY %c failed to bring out of SOC reset after %dus.\n",
|
||||
phy_name(phy), XELPDP_PORT_BUF_SOC_READY_TIMEOUT_US);
|
||||
"PHY %c failed to bring out of SOC reset\n",
|
||||
phy_name(phy));
|
||||
|
||||
intel_de_rmw(display, XELPDP_PORT_BUF_CTL2(display, port), lane_pipe_reset,
|
||||
lane_pipe_reset);
|
||||
|
||||
if (intel_de_wait_custom(display, XELPDP_PORT_BUF_CTL2(display, port),
|
||||
lane_phy_current_status, lane_phy_current_status,
|
||||
XELPDP_PORT_RESET_START_TIMEOUT_US, 0, NULL))
|
||||
if (intel_de_wait_for_set_us(display, XELPDP_PORT_BUF_CTL2(display, port),
|
||||
lane_phy_current_status,
|
||||
XELPDP_PORT_RESET_START_TIMEOUT_US))
|
||||
drm_warn(display->drm,
|
||||
"PHY %c failed to bring out of Lane reset after %dus.\n",
|
||||
phy_name(phy), XELPDP_PORT_RESET_START_TIMEOUT_US);
|
||||
"PHY %c failed to bring out of lane reset\n",
|
||||
phy_name(phy));
|
||||
|
||||
intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, port),
|
||||
intel_cx0_get_pclk_refclk_request(owned_lane_mask),
|
||||
intel_cx0_get_pclk_refclk_request(lane_mask));
|
||||
|
||||
if (intel_de_wait_custom(display, XELPDP_PORT_CLOCK_CTL(display, port),
|
||||
intel_cx0_get_pclk_refclk_ack(owned_lane_mask),
|
||||
intel_cx0_get_pclk_refclk_ack(lane_mask),
|
||||
XELPDP_REFCLK_ENABLE_TIMEOUT_US, 0, NULL))
|
||||
if (intel_de_wait_us(display, XELPDP_PORT_CLOCK_CTL(display, port),
|
||||
intel_cx0_get_pclk_refclk_ack(owned_lane_mask),
|
||||
intel_cx0_get_pclk_refclk_ack(lane_mask),
|
||||
XELPDP_REFCLK_ENABLE_TIMEOUT_US, NULL))
|
||||
drm_warn(display->drm,
|
||||
"PHY %c failed to request refclk after %dus.\n",
|
||||
phy_name(phy), XELPDP_REFCLK_ENABLE_TIMEOUT_US);
|
||||
"PHY %c failed to request refclk\n",
|
||||
phy_name(phy));
|
||||
|
||||
intel_cx0_powerdown_change_sequence(encoder, INTEL_CX0_BOTH_LANES,
|
||||
XELPDP_P2_STATE_RESET);
|
||||
@@ -2925,12 +2922,12 @@ static void intel_cx0_phy_lane_reset(struct intel_encoder *encoder,
|
||||
|
||||
intel_de_rmw(display, XELPDP_PORT_BUF_CTL2(display, port), lane_pipe_reset, 0);
|
||||
|
||||
if (intel_de_wait_for_clear(display, XELPDP_PORT_BUF_CTL2(display, port),
|
||||
lane_phy_current_status,
|
||||
XELPDP_PORT_RESET_END_TIMEOUT))
|
||||
if (intel_de_wait_for_clear_ms(display, XELPDP_PORT_BUF_CTL2(display, port),
|
||||
lane_phy_current_status,
|
||||
XELPDP_PORT_RESET_END_TIMEOUT_MS))
|
||||
drm_warn(display->drm,
|
||||
"PHY %c failed to bring out of Lane reset after %dms.\n",
|
||||
phy_name(phy), XELPDP_PORT_RESET_END_TIMEOUT);
|
||||
"PHY %c failed to bring out of lane reset\n",
|
||||
phy_name(phy));
|
||||
}
|
||||
|
||||
static void intel_cx0_program_phy_lane(struct intel_encoder *encoder, int lane_count,
|
||||
@@ -3065,12 +3062,12 @@ static void __intel_cx0pll_enable(struct intel_encoder *encoder,
|
||||
intel_cx0_get_pclk_pll_request(maxpclk_lane));
|
||||
|
||||
/* 10. Poll on PORT_CLOCK_CTL PCLK PLL Ack LN<Lane for maxPCLK> == "1". */
|
||||
if (intel_de_wait_custom(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port),
|
||||
intel_cx0_get_pclk_pll_ack(INTEL_CX0_BOTH_LANES),
|
||||
intel_cx0_get_pclk_pll_ack(maxpclk_lane),
|
||||
XELPDP_PCLK_PLL_ENABLE_TIMEOUT_US, 0, NULL))
|
||||
drm_warn(display->drm, "Port %c PLL not locked after %dus.\n",
|
||||
phy_name(phy), XELPDP_PCLK_PLL_ENABLE_TIMEOUT_US);
|
||||
if (intel_de_wait_us(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port),
|
||||
intel_cx0_get_pclk_pll_ack(INTEL_CX0_BOTH_LANES),
|
||||
intel_cx0_get_pclk_pll_ack(maxpclk_lane),
|
||||
XELPDP_PCLK_PLL_ENABLE_TIMEOUT_US, NULL))
|
||||
drm_warn(display->drm, "Port %c PLL not locked\n",
|
||||
phy_name(phy));
|
||||
|
||||
/*
|
||||
* 11. Follow the Display Voltage Frequency Switching Sequence After
|
||||
@@ -3189,12 +3186,9 @@ void intel_mtl_tbt_pll_enable(struct intel_encoder *encoder,
|
||||
intel_de_write(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port), val);
|
||||
|
||||
/* 5. Poll on PORT_CLOCK_CTL TBT CLOCK Ack == "1". */
|
||||
if (intel_de_wait_custom(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port),
|
||||
XELPDP_TBT_CLOCK_ACK,
|
||||
XELPDP_TBT_CLOCK_ACK,
|
||||
100, 0, NULL))
|
||||
drm_warn(display->drm,
|
||||
"[ENCODER:%d:%s][%c] PHY PLL not locked after 100us.\n",
|
||||
if (intel_de_wait_for_set_us(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port),
|
||||
XELPDP_TBT_CLOCK_ACK, 100))
|
||||
drm_warn(display->drm, "[ENCODER:%d:%s][%c] PHY PLL not locked\n",
|
||||
encoder->base.base.id, encoder->base.name, phy_name(phy));
|
||||
|
||||
/*
|
||||
@@ -3304,13 +3298,12 @@ static void intel_cx0pll_disable(struct intel_encoder *encoder)
|
||||
/*
|
||||
* 5. Poll on PORT_CLOCK_CTL PCLK PLL Ack LN<Lane for maxPCLK**> == "0".
|
||||
*/
|
||||
if (intel_de_wait_custom(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port),
|
||||
intel_cx0_get_pclk_pll_ack(INTEL_CX0_BOTH_LANES) |
|
||||
intel_cx0_get_pclk_refclk_ack(INTEL_CX0_BOTH_LANES), 0,
|
||||
XELPDP_PCLK_PLL_DISABLE_TIMEOUT_US, 0, NULL))
|
||||
drm_warn(display->drm,
|
||||
"Port %c PLL not unlocked after %dus.\n",
|
||||
phy_name(phy), XELPDP_PCLK_PLL_DISABLE_TIMEOUT_US);
|
||||
if (intel_de_wait_for_clear_us(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port),
|
||||
intel_cx0_get_pclk_pll_ack(INTEL_CX0_BOTH_LANES) |
|
||||
intel_cx0_get_pclk_refclk_ack(INTEL_CX0_BOTH_LANES),
|
||||
XELPDP_PCLK_PLL_DISABLE_TIMEOUT_US))
|
||||
drm_warn(display->drm, "Port %c PLL not unlocked\n",
|
||||
phy_name(phy));
|
||||
|
||||
/*
|
||||
* 6. Follow the Display Voltage Frequency Switching Sequence After
|
||||
@@ -3353,10 +3346,9 @@ void intel_mtl_tbt_pll_disable(struct intel_encoder *encoder)
|
||||
XELPDP_TBT_CLOCK_REQUEST, 0);
|
||||
|
||||
/* 3. Poll on PORT_CLOCK_CTL TBT CLOCK Ack == "0". */
|
||||
if (intel_de_wait_custom(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port),
|
||||
XELPDP_TBT_CLOCK_ACK, 0, 10, 0, NULL))
|
||||
drm_warn(display->drm,
|
||||
"[ENCODER:%d:%s][%c] PHY PLL not unlocked after 10us.\n",
|
||||
if (intel_de_wait_for_clear_us(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port),
|
||||
XELPDP_TBT_CLOCK_ACK, 10))
|
||||
drm_warn(display->drm, "[ENCODER:%d:%s][%c] PHY PLL not unlocked\n",
|
||||
encoder->base.base.id, encoder->base.name, phy_name(phy));
|
||||
|
||||
/*
|
||||
|
||||
@@ -74,14 +74,13 @@
|
||||
#define XELPDP_PORT_P2M_DATA(val) REG_FIELD_PREP(XELPDP_PORT_P2M_DATA_MASK, val)
|
||||
#define XELPDP_PORT_P2M_ERROR_SET REG_BIT(15)
|
||||
|
||||
#define XELPDP_MSGBUS_TIMEOUT_SLOW 1
|
||||
#define XELPDP_MSGBUS_TIMEOUT_FAST_US 2
|
||||
#define XELPDP_MSGBUS_TIMEOUT_MS 1
|
||||
#define XELPDP_PCLK_PLL_ENABLE_TIMEOUT_US 3200
|
||||
#define XELPDP_PCLK_PLL_DISABLE_TIMEOUT_US 20
|
||||
#define XELPDP_PORT_BUF_SOC_READY_TIMEOUT_US 100
|
||||
#define XELPDP_PORT_RESET_START_TIMEOUT_US 5
|
||||
#define XELPDP_PORT_POWERDOWN_UPDATE_TIMEOUT_US 100
|
||||
#define XELPDP_PORT_RESET_END_TIMEOUT 15
|
||||
#define XELPDP_PORT_POWERDOWN_UPDATE_TIMEOUT_MS 2
|
||||
#define XELPDP_PORT_RESET_END_TIMEOUT_MS 15
|
||||
#define XELPDP_REFCLK_ENABLE_TIMEOUT_US 1
|
||||
|
||||
#define _XELPDP_PORT_BUF_CTL1_LN0_A 0x64004
|
||||
|
||||
@@ -210,8 +210,8 @@ void intel_wait_ddi_buf_idle(struct intel_display *display, enum port port)
|
||||
}
|
||||
|
||||
static_assert(DDI_BUF_IS_IDLE == XELPDP_PORT_BUF_PHY_IDLE);
|
||||
if (intel_de_wait_for_set(display, intel_ddi_buf_status_reg(display, port),
|
||||
DDI_BUF_IS_IDLE, 10))
|
||||
if (intel_de_wait_for_set_ms(display, intel_ddi_buf_status_reg(display, port),
|
||||
DDI_BUF_IS_IDLE, 10))
|
||||
drm_err(display->drm, "Timeout waiting for DDI BUF %c to get idle\n",
|
||||
port_name(port));
|
||||
}
|
||||
@@ -235,8 +235,8 @@ static void intel_wait_ddi_buf_active(struct intel_encoder *encoder)
|
||||
}
|
||||
|
||||
static_assert(DDI_BUF_IS_IDLE == XELPDP_PORT_BUF_PHY_IDLE);
|
||||
if (intel_de_wait_for_clear(display, intel_ddi_buf_status_reg(display, port),
|
||||
DDI_BUF_IS_IDLE, 10))
|
||||
if (intel_de_wait_for_clear_ms(display, intel_ddi_buf_status_reg(display, port),
|
||||
DDI_BUF_IS_IDLE, 10))
|
||||
drm_err(display->drm, "Timeout waiting for DDI BUF %c to get active\n",
|
||||
port_name(port));
|
||||
}
|
||||
@@ -2307,8 +2307,8 @@ void intel_ddi_wait_for_act_sent(struct intel_encoder *encoder,
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
|
||||
if (intel_de_wait_for_set(display, dp_tp_status_reg(encoder, crtc_state),
|
||||
DP_TP_STATUS_ACT_SENT, 1))
|
||||
if (intel_de_wait_for_set_ms(display, dp_tp_status_reg(encoder, crtc_state),
|
||||
DP_TP_STATUS_ACT_SENT, 1))
|
||||
drm_err(display->drm, "Timed out waiting for ACT sent\n");
|
||||
}
|
||||
|
||||
@@ -2383,11 +2383,11 @@ int intel_ddi_wait_for_fec_status(struct intel_encoder *encoder,
|
||||
return 0;
|
||||
|
||||
if (enabled)
|
||||
ret = intel_de_wait_for_set(display, dp_tp_status_reg(encoder, crtc_state),
|
||||
DP_TP_STATUS_FEC_ENABLE_LIVE, 1);
|
||||
ret = intel_de_wait_for_set_ms(display, dp_tp_status_reg(encoder, crtc_state),
|
||||
DP_TP_STATUS_FEC_ENABLE_LIVE, 1);
|
||||
else
|
||||
ret = intel_de_wait_for_clear(display, dp_tp_status_reg(encoder, crtc_state),
|
||||
DP_TP_STATUS_FEC_ENABLE_LIVE, 1);
|
||||
ret = intel_de_wait_for_clear_ms(display, dp_tp_status_reg(encoder, crtc_state),
|
||||
DP_TP_STATUS_FEC_ENABLE_LIVE, 1);
|
||||
|
||||
if (ret) {
|
||||
drm_err(display->drm,
|
||||
@@ -2577,9 +2577,7 @@ mtl_ddi_enable_d2d(struct intel_encoder *encoder)
|
||||
|
||||
intel_de_rmw(display, reg, 0, set_bits);
|
||||
|
||||
ret = intel_de_wait_custom(display, reg,
|
||||
wait_bits, wait_bits,
|
||||
100, 0, NULL);
|
||||
ret = intel_de_wait_for_set_us(display, reg, wait_bits, 100);
|
||||
if (ret) {
|
||||
drm_err(display->drm, "Timeout waiting for D2D Link enable for DDI/PORT_BUF_CTL %c\n",
|
||||
port_name(port));
|
||||
@@ -3079,9 +3077,7 @@ mtl_ddi_disable_d2d(struct intel_encoder *encoder)
|
||||
|
||||
intel_de_rmw(display, reg, clr_bits, 0);
|
||||
|
||||
ret = intel_de_wait_custom(display, reg,
|
||||
wait_bits, 0,
|
||||
100, 0, NULL);
|
||||
ret = intel_de_wait_for_clear_us(display, reg, wait_bits, 100);
|
||||
if (ret)
|
||||
drm_err(display->drm, "Timeout waiting for D2D Link disable for DDI/PORT_BUF_CTL %c\n",
|
||||
port_name(port));
|
||||
@@ -3868,9 +3864,9 @@ static void intel_ddi_set_idle_link_train(struct intel_dp *intel_dp,
|
||||
if (port == PORT_A && DISPLAY_VER(display) < 12)
|
||||
return;
|
||||
|
||||
if (intel_de_wait_for_set(display,
|
||||
dp_tp_status_reg(encoder, crtc_state),
|
||||
DP_TP_STATUS_IDLE_DONE, 2))
|
||||
if (intel_de_wait_for_set_ms(display,
|
||||
dp_tp_status_reg(encoder, crtc_state),
|
||||
DP_TP_STATUS_IDLE_DONE, 2))
|
||||
drm_err(display->drm,
|
||||
"Timed out waiting for DP idle patterns\n");
|
||||
}
|
||||
|
||||
@@ -83,13 +83,6 @@ intel_de_write(struct intel_display *display, i915_reg_t reg, u32 val)
|
||||
intel_dmc_wl_put(display, reg);
|
||||
}
|
||||
|
||||
static inline u32
|
||||
__intel_de_rmw_nowl(struct intel_display *display, i915_reg_t reg,
|
||||
u32 clear, u32 set)
|
||||
{
|
||||
return intel_uncore_rmw(__to_uncore(display), reg, clear, set);
|
||||
}
|
||||
|
||||
static inline u32
|
||||
intel_de_rmw(struct intel_display *display, i915_reg_t reg, u32 clear, u32 set)
|
||||
{
|
||||
@@ -97,7 +90,7 @@ intel_de_rmw(struct intel_display *display, i915_reg_t reg, u32 clear, u32 set)
|
||||
|
||||
intel_dmc_wl_get(display, reg);
|
||||
|
||||
val = __intel_de_rmw_nowl(display, reg, clear, set);
|
||||
val = intel_uncore_rmw(__to_uncore(display), reg, clear, set);
|
||||
|
||||
intel_dmc_wl_put(display, reg);
|
||||
|
||||
@@ -105,69 +98,16 @@ intel_de_rmw(struct intel_display *display, i915_reg_t reg, u32 clear, u32 set)
|
||||
}
|
||||
|
||||
static inline int
|
||||
__intel_de_wait_for_register_nowl(struct intel_display *display,
|
||||
i915_reg_t reg,
|
||||
u32 mask, u32 value, unsigned int timeout_ms)
|
||||
{
|
||||
return intel_wait_for_register(__to_uncore(display), reg, mask,
|
||||
value, timeout_ms);
|
||||
}
|
||||
|
||||
static inline int
|
||||
__intel_de_wait_for_register_atomic_nowl(struct intel_display *display,
|
||||
i915_reg_t reg,
|
||||
u32 mask, u32 value,
|
||||
unsigned int fast_timeout_us)
|
||||
{
|
||||
return __intel_wait_for_register(__to_uncore(display), reg, mask,
|
||||
value, fast_timeout_us, 0, NULL);
|
||||
}
|
||||
|
||||
static inline int
|
||||
intel_de_wait(struct intel_display *display, i915_reg_t reg,
|
||||
u32 mask, u32 value, unsigned int timeout_ms)
|
||||
{
|
||||
int ret;
|
||||
|
||||
intel_dmc_wl_get(display, reg);
|
||||
|
||||
ret = __intel_de_wait_for_register_nowl(display, reg, mask, value,
|
||||
timeout_ms);
|
||||
|
||||
intel_dmc_wl_put(display, reg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int
|
||||
intel_de_wait_fw(struct intel_display *display, i915_reg_t reg,
|
||||
u32 mask, u32 value, unsigned int timeout_ms, u32 *out_value)
|
||||
{
|
||||
int ret;
|
||||
|
||||
intel_dmc_wl_get(display, reg);
|
||||
|
||||
ret = intel_wait_for_register_fw(__to_uncore(display), reg, mask,
|
||||
value, timeout_ms, out_value);
|
||||
|
||||
intel_dmc_wl_put(display, reg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int
|
||||
intel_de_wait_custom(struct intel_display *display, i915_reg_t reg,
|
||||
u32 mask, u32 value,
|
||||
unsigned int fast_timeout_us,
|
||||
unsigned int slow_timeout_ms, u32 *out_value)
|
||||
intel_de_wait_us(struct intel_display *display, i915_reg_t reg,
|
||||
u32 mask, u32 value, unsigned int timeout_us,
|
||||
u32 *out_value)
|
||||
{
|
||||
int ret;
|
||||
|
||||
intel_dmc_wl_get(display, reg);
|
||||
|
||||
ret = __intel_wait_for_register(__to_uncore(display), reg, mask,
|
||||
value,
|
||||
fast_timeout_us, slow_timeout_ms, out_value);
|
||||
value, timeout_us, 0, out_value);
|
||||
|
||||
intel_dmc_wl_put(display, reg);
|
||||
|
||||
@@ -175,17 +115,66 @@ intel_de_wait_custom(struct intel_display *display, i915_reg_t reg,
|
||||
}
|
||||
|
||||
static inline int
|
||||
intel_de_wait_for_set(struct intel_display *display, i915_reg_t reg,
|
||||
u32 mask, unsigned int timeout_ms)
|
||||
intel_de_wait_ms(struct intel_display *display, i915_reg_t reg,
|
||||
u32 mask, u32 value, unsigned int timeout_ms,
|
||||
u32 *out_value)
|
||||
{
|
||||
return intel_de_wait(display, reg, mask, mask, timeout_ms);
|
||||
int ret;
|
||||
|
||||
intel_dmc_wl_get(display, reg);
|
||||
|
||||
ret = __intel_wait_for_register(__to_uncore(display), reg, mask,
|
||||
value, 2, timeout_ms, out_value);
|
||||
|
||||
intel_dmc_wl_put(display, reg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int
|
||||
intel_de_wait_for_clear(struct intel_display *display, i915_reg_t reg,
|
||||
u32 mask, unsigned int timeout_ms)
|
||||
intel_de_wait_fw_ms(struct intel_display *display, i915_reg_t reg,
|
||||
u32 mask, u32 value, unsigned int timeout_ms,
|
||||
u32 *out_value)
|
||||
{
|
||||
return intel_de_wait(display, reg, mask, 0, timeout_ms);
|
||||
return __intel_wait_for_register_fw(__to_uncore(display), reg, mask,
|
||||
value, 2, timeout_ms, out_value);
|
||||
}
|
||||
|
||||
static inline int
|
||||
intel_de_wait_fw_us_atomic(struct intel_display *display, i915_reg_t reg,
|
||||
u32 mask, u32 value, unsigned int timeout_us,
|
||||
u32 *out_value)
|
||||
{
|
||||
return __intel_wait_for_register_fw(__to_uncore(display), reg, mask,
|
||||
value, timeout_us, 0, out_value);
|
||||
}
|
||||
|
||||
static inline int
|
||||
intel_de_wait_for_set_us(struct intel_display *display, i915_reg_t reg,
|
||||
u32 mask, unsigned int timeout_us)
|
||||
{
|
||||
return intel_de_wait_us(display, reg, mask, mask, timeout_us, NULL);
|
||||
}
|
||||
|
||||
static inline int
|
||||
intel_de_wait_for_clear_us(struct intel_display *display, i915_reg_t reg,
|
||||
u32 mask, unsigned int timeout_us)
|
||||
{
|
||||
return intel_de_wait_us(display, reg, mask, 0, timeout_us, NULL);
|
||||
}
|
||||
|
||||
static inline int
|
||||
intel_de_wait_for_set_ms(struct intel_display *display, i915_reg_t reg,
|
||||
u32 mask, unsigned int timeout_ms)
|
||||
{
|
||||
return intel_de_wait_ms(display, reg, mask, mask, timeout_ms, NULL);
|
||||
}
|
||||
|
||||
static inline int
|
||||
intel_de_wait_for_clear_ms(struct intel_display *display, i915_reg_t reg,
|
||||
u32 mask, unsigned int timeout_ms)
|
||||
{
|
||||
return intel_de_wait_ms(display, reg, mask, 0, timeout_ms, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -214,6 +203,18 @@ intel_de_write_fw(struct intel_display *display, i915_reg_t reg, u32 val)
|
||||
intel_uncore_write_fw(__to_uncore(display), reg, val);
|
||||
}
|
||||
|
||||
static inline u32
|
||||
intel_de_rmw_fw(struct intel_display *display, i915_reg_t reg, u32 clear, u32 set)
|
||||
{
|
||||
u32 old, val;
|
||||
|
||||
old = intel_de_read_fw(display, reg);
|
||||
val = (old & ~clear) | set;
|
||||
intel_de_write_fw(display, reg, val);
|
||||
|
||||
return old;
|
||||
}
|
||||
|
||||
static inline u32
|
||||
intel_de_read_notrace(struct intel_display *display, i915_reg_t reg)
|
||||
{
|
||||
|
||||
@@ -359,8 +359,8 @@ intel_wait_for_pipe_off(const struct intel_crtc_state *old_crtc_state)
|
||||
enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder;
|
||||
|
||||
/* Wait for the Pipe State to go off */
|
||||
if (intel_de_wait_for_clear(display, TRANSCONF(display, cpu_transcoder),
|
||||
TRANSCONF_STATE_ENABLE, 100))
|
||||
if (intel_de_wait_for_clear_ms(display, TRANSCONF(display, cpu_transcoder),
|
||||
TRANSCONF_STATE_ENABLE, 100))
|
||||
drm_WARN(display->drm, 1, "pipe_off wait timed out\n");
|
||||
} else {
|
||||
intel_wait_for_pipe_scanline_stopped(crtc);
|
||||
@@ -547,16 +547,13 @@ void intel_disable_transcoder(const struct intel_crtc_state *old_crtc_state)
|
||||
intel_wait_for_pipe_off(old_crtc_state);
|
||||
}
|
||||
|
||||
u32 intel_plane_fb_max_stride(struct drm_device *drm,
|
||||
u32 pixel_format, u64 modifier)
|
||||
u32 intel_plane_fb_max_stride(struct intel_display *display,
|
||||
const struct drm_format_info *info,
|
||||
u64 modifier)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(drm);
|
||||
struct intel_crtc *crtc;
|
||||
struct intel_plane *plane;
|
||||
|
||||
if (!HAS_DISPLAY(display))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* We assume the primary plane for pipe A has
|
||||
* the highest stride limits of them all,
|
||||
@@ -568,10 +565,23 @@ u32 intel_plane_fb_max_stride(struct drm_device *drm,
|
||||
|
||||
plane = to_intel_plane(crtc->base.primary);
|
||||
|
||||
return plane->max_stride(plane, pixel_format, modifier,
|
||||
return plane->max_stride(plane, info, modifier,
|
||||
DRM_MODE_ROTATE_0);
|
||||
}
|
||||
|
||||
u32 intel_dumb_fb_max_stride(struct drm_device *drm,
|
||||
u32 pixel_format, u64 modifier)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(drm);
|
||||
|
||||
if (!HAS_DISPLAY(display))
|
||||
return 0;
|
||||
|
||||
return intel_plane_fb_max_stride(display,
|
||||
drm_get_format_info(drm, pixel_format, modifier),
|
||||
modifier);
|
||||
}
|
||||
|
||||
void intel_set_plane_visible(struct intel_crtc_state *crtc_state,
|
||||
struct intel_plane_state *plane_state,
|
||||
bool visible)
|
||||
@@ -2658,7 +2668,7 @@ static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_sta
|
||||
crtc_vblank_start = crtc_vdisplay + crtc_state->set_context_latency;
|
||||
}
|
||||
|
||||
if (DISPLAY_VER(display) >= 4)
|
||||
if (DISPLAY_VER(display) >= 4 && DISPLAY_VER(display) < 35)
|
||||
intel_de_write(display,
|
||||
TRANS_VSYNCSHIFT(display, cpu_transcoder),
|
||||
vsyncshift);
|
||||
@@ -2799,7 +2809,7 @@ static bool intel_pipe_is_interlaced(const struct intel_crtc_state *crtc_state)
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
|
||||
|
||||
if (DISPLAY_VER(display) == 2)
|
||||
if (DISPLAY_VER(display) == 2 || DISPLAY_VER(display) >= 35)
|
||||
return false;
|
||||
|
||||
if (DISPLAY_VER(display) >= 9 ||
|
||||
@@ -3190,10 +3200,12 @@ static void hsw_set_transconf(const struct intel_crtc_state *crtc_state)
|
||||
if (display->platform.haswell && crtc_state->dither)
|
||||
val |= TRANSCONF_DITHER_EN | TRANSCONF_DITHER_TYPE_SP;
|
||||
|
||||
if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
|
||||
val |= TRANSCONF_INTERLACE_IF_ID_ILK;
|
||||
else
|
||||
val |= TRANSCONF_INTERLACE_PF_PD_ILK;
|
||||
if (DISPLAY_VER(display) < 35) {
|
||||
if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
|
||||
val |= TRANSCONF_INTERLACE_IF_ID_ILK;
|
||||
else
|
||||
val |= TRANSCONF_INTERLACE_PF_PD_ILK;
|
||||
}
|
||||
|
||||
if (display->platform.haswell &&
|
||||
crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB)
|
||||
|
||||
@@ -34,6 +34,7 @@ struct drm_atomic_state;
|
||||
struct drm_device;
|
||||
struct drm_display_mode;
|
||||
struct drm_encoder;
|
||||
struct drm_format_info;
|
||||
struct drm_modeset_acquire_ctx;
|
||||
struct intel_atomic_state;
|
||||
struct intel_crtc;
|
||||
@@ -402,8 +403,11 @@ void intel_link_compute_m_n(u16 bpp, int nlanes,
|
||||
int pixel_clock, int link_clock,
|
||||
int bw_overhead,
|
||||
struct intel_link_m_n *m_n);
|
||||
u32 intel_plane_fb_max_stride(struct drm_device *drm,
|
||||
u32 pixel_format, u64 modifier);
|
||||
u32 intel_plane_fb_max_stride(struct intel_display *display,
|
||||
const struct drm_format_info *info,
|
||||
u64 modifier);
|
||||
u32 intel_dumb_fb_max_stride(struct drm_device *drm,
|
||||
u32 pixel_format, u64 modifier);
|
||||
enum drm_mode_status
|
||||
intel_mode_valid_max_plane_size(struct intel_display *display,
|
||||
const struct drm_display_mode *mode,
|
||||
|
||||
@@ -142,14 +142,13 @@ struct intel_dpll_global {
|
||||
};
|
||||
|
||||
struct intel_frontbuffer_tracking {
|
||||
/* protects busy_bits */
|
||||
spinlock_t lock;
|
||||
|
||||
/*
|
||||
* Tracking bits for delayed frontbuffer flushing du to gpu activity or
|
||||
* scheduled flips.
|
||||
* Tracking bits for delayed frontbuffer flushing due to gpu activity.
|
||||
*/
|
||||
unsigned busy_bits;
|
||||
unsigned flip_bits;
|
||||
};
|
||||
|
||||
struct intel_hotplug {
|
||||
|
||||
@@ -78,9 +78,6 @@ static int i915_frontbuffer_tracking(struct seq_file *m, void *unused)
|
||||
seq_printf(m, "FB tracking busy bits: 0x%08x\n",
|
||||
display->fb_tracking.busy_bits);
|
||||
|
||||
seq_printf(m, "FB tracking flip bits: 0x%08x\n",
|
||||
display->fb_tracking.flip_bits);
|
||||
|
||||
spin_unlock(&display->fb_tracking.lock);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1507,6 +1507,7 @@ static const struct {
|
||||
{ 20, 0, &xe2_lpd_display },
|
||||
{ 30, 0, &xe2_lpd_display },
|
||||
{ 30, 2, &wcl_display },
|
||||
{ 35, 0, &xe2_lpd_display },
|
||||
};
|
||||
|
||||
static const struct intel_display_device_info *
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "intel_cdclk.h"
|
||||
#include "intel_color.h"
|
||||
#include "intel_crtc.h"
|
||||
#include "intel_cursor.h"
|
||||
#include "intel_dbuf_bw.h"
|
||||
#include "intel_display_core.h"
|
||||
#include "intel_display_debugfs.h"
|
||||
@@ -148,17 +149,7 @@ static void intel_mode_config_init(struct intel_display *display)
|
||||
mode_config->max_height = 2048;
|
||||
}
|
||||
|
||||
if (display->platform.i845g || display->platform.i865g) {
|
||||
mode_config->cursor_width = display->platform.i845g ? 64 : 512;
|
||||
mode_config->cursor_height = 1023;
|
||||
} else if (display->platform.i830 || display->platform.i85x ||
|
||||
display->platform.i915g || display->platform.i915gm) {
|
||||
mode_config->cursor_width = 64;
|
||||
mode_config->cursor_height = 64;
|
||||
} else {
|
||||
mode_config->cursor_width = 256;
|
||||
mode_config->cursor_height = 256;
|
||||
}
|
||||
intel_cursor_mode_config_init(display);
|
||||
}
|
||||
|
||||
static void intel_mode_config_cleanup(struct intel_display *display)
|
||||
|
||||
@@ -1292,9 +1292,8 @@ static void hsw_disable_lcpll(struct intel_display *display,
|
||||
val |= LCPLL_CD_SOURCE_FCLK;
|
||||
intel_de_write(display, LCPLL_CTL, val);
|
||||
|
||||
ret = intel_de_wait_custom(display, LCPLL_CTL,
|
||||
LCPLL_CD_SOURCE_FCLK_DONE, LCPLL_CD_SOURCE_FCLK_DONE,
|
||||
1, 0, NULL);
|
||||
ret = intel_de_wait_for_set_us(display, LCPLL_CTL,
|
||||
LCPLL_CD_SOURCE_FCLK_DONE, 1);
|
||||
if (ret)
|
||||
drm_err(display->drm, "Switching to FCLK failed\n");
|
||||
|
||||
@@ -1305,7 +1304,7 @@ static void hsw_disable_lcpll(struct intel_display *display,
|
||||
intel_de_write(display, LCPLL_CTL, val);
|
||||
intel_de_posting_read(display, LCPLL_CTL);
|
||||
|
||||
if (intel_de_wait_for_clear(display, LCPLL_CTL, LCPLL_PLL_LOCK, 1))
|
||||
if (intel_de_wait_for_clear_ms(display, LCPLL_CTL, LCPLL_PLL_LOCK, 1))
|
||||
drm_err(display->drm, "LCPLL still locked\n");
|
||||
|
||||
val = hsw_read_dcomp(display);
|
||||
@@ -1362,15 +1361,14 @@ static void hsw_restore_lcpll(struct intel_display *display)
|
||||
val &= ~LCPLL_PLL_DISABLE;
|
||||
intel_de_write(display, LCPLL_CTL, val);
|
||||
|
||||
if (intel_de_wait_for_set(display, LCPLL_CTL, LCPLL_PLL_LOCK, 5))
|
||||
if (intel_de_wait_for_set_ms(display, LCPLL_CTL, LCPLL_PLL_LOCK, 5))
|
||||
drm_err(display->drm, "LCPLL not locked yet\n");
|
||||
|
||||
if (val & LCPLL_CD_SOURCE_FCLK) {
|
||||
intel_de_rmw(display, LCPLL_CTL, LCPLL_CD_SOURCE_FCLK, 0);
|
||||
|
||||
ret = intel_de_wait_custom(display, LCPLL_CTL,
|
||||
LCPLL_CD_SOURCE_FCLK_DONE, 0,
|
||||
1, 0, NULL);
|
||||
ret = intel_de_wait_for_clear_us(display, LCPLL_CTL,
|
||||
LCPLL_CD_SOURCE_FCLK_DONE, 1);
|
||||
if (ret)
|
||||
drm_err(display->drm,
|
||||
"Switching back to LCPLL failed\n");
|
||||
@@ -1438,6 +1436,9 @@ static void intel_pch_reset_handshake(struct intel_display *display,
|
||||
i915_reg_t reg;
|
||||
u32 reset_bits;
|
||||
|
||||
if (DISPLAY_VER(display) >= 35)
|
||||
return;
|
||||
|
||||
if (display->platform.ivybridge) {
|
||||
reg = GEN7_MSG_CTL;
|
||||
reset_bits = WAIT_FOR_PCH_FLR_ACK | WAIT_FOR_PCH_RESET_ACK;
|
||||
|
||||
@@ -293,8 +293,8 @@ static void hsw_wait_for_power_well_enable(struct intel_display *display,
|
||||
}
|
||||
|
||||
/* Timeout for PW1:10 us, AUX:not specified, other PWs:20 us. */
|
||||
if (intel_de_wait_for_set(display, regs->driver,
|
||||
HSW_PWR_WELL_CTL_STATE(pw_idx), timeout)) {
|
||||
if (intel_de_wait_for_set_ms(display, regs->driver,
|
||||
HSW_PWR_WELL_CTL_STATE(pw_idx), timeout)) {
|
||||
drm_dbg_kms(display->drm, "%s power well enable timeout\n",
|
||||
intel_power_well_name(power_well));
|
||||
|
||||
@@ -338,9 +338,9 @@ static void hsw_wait_for_power_well_disable(struct intel_display *display,
|
||||
*/
|
||||
reqs = hsw_power_well_requesters(display, regs, pw_idx);
|
||||
|
||||
ret = intel_de_wait_for_clear(display, regs->driver,
|
||||
HSW_PWR_WELL_CTL_STATE(pw_idx),
|
||||
reqs ? 0 : 1);
|
||||
ret = intel_de_wait_for_clear_ms(display, regs->driver,
|
||||
HSW_PWR_WELL_CTL_STATE(pw_idx),
|
||||
reqs ? 0 : 1);
|
||||
if (!ret)
|
||||
return;
|
||||
|
||||
@@ -359,8 +359,8 @@ static void gen9_wait_for_power_well_fuses(struct intel_display *display,
|
||||
{
|
||||
/* Timeout 5us for PG#0, for other PGs 1us */
|
||||
drm_WARN_ON(display->drm,
|
||||
intel_de_wait_for_set(display, SKL_FUSE_STATUS,
|
||||
SKL_FUSE_PG_DIST_STATUS(pg), 1));
|
||||
intel_de_wait_for_set_ms(display, SKL_FUSE_STATUS,
|
||||
SKL_FUSE_PG_DIST_STATUS(pg), 1));
|
||||
}
|
||||
|
||||
static void hsw_power_well_enable(struct intel_display *display,
|
||||
@@ -1358,6 +1358,7 @@ static void assert_chv_phy_status(struct intel_display *display)
|
||||
u32 phy_control = display->power.chv_phy_control;
|
||||
u32 phy_status = 0;
|
||||
u32 phy_status_mask = 0xffffffff;
|
||||
u32 val;
|
||||
|
||||
/*
|
||||
* The BIOS can leave the PHY is some weird state
|
||||
@@ -1445,12 +1446,11 @@ static void assert_chv_phy_status(struct intel_display *display)
|
||||
* The PHY may be busy with some initial calibration and whatnot,
|
||||
* so the power state can take a while to actually change.
|
||||
*/
|
||||
if (intel_de_wait(display, DISPLAY_PHY_STATUS,
|
||||
phy_status_mask, phy_status, 10))
|
||||
if (intel_de_wait_ms(display, DISPLAY_PHY_STATUS,
|
||||
phy_status_mask, phy_status, 10, &val))
|
||||
drm_err(display->drm,
|
||||
"Unexpected PHY_STATUS 0x%08x, expected 0x%08x (PHY_CONTROL=0x%08x)\n",
|
||||
intel_de_read(display, DISPLAY_PHY_STATUS) & phy_status_mask,
|
||||
phy_status, display->power.chv_phy_control);
|
||||
val & phy_status_mask, phy_status, display->power.chv_phy_control);
|
||||
}
|
||||
|
||||
#undef BITS_SET
|
||||
@@ -1476,8 +1476,8 @@ static void chv_dpio_cmn_power_well_enable(struct intel_display *display,
|
||||
vlv_set_power_well(display, power_well, true);
|
||||
|
||||
/* Poll for phypwrgood signal */
|
||||
if (intel_de_wait_for_set(display, DISPLAY_PHY_STATUS,
|
||||
PHY_POWERGOOD(phy), 1))
|
||||
if (intel_de_wait_for_set_ms(display, DISPLAY_PHY_STATUS,
|
||||
PHY_POWERGOOD(phy), 1))
|
||||
drm_err(display->drm, "Display PHY %d is not power up\n",
|
||||
phy);
|
||||
|
||||
@@ -1867,8 +1867,8 @@ static void xelpdp_aux_power_well_enable(struct intel_display *display,
|
||||
* bit.
|
||||
*/
|
||||
if (DISPLAY_VER(display) >= 35) {
|
||||
if (intel_de_wait_for_set(display, XELPDP_DP_AUX_CH_CTL(display, aux_ch),
|
||||
XELPDP_DP_AUX_CH_CTL_POWER_STATUS, 2))
|
||||
if (intel_de_wait_for_set_ms(display, XELPDP_DP_AUX_CH_CTL(display, aux_ch),
|
||||
XELPDP_DP_AUX_CH_CTL_POWER_STATUS, 2))
|
||||
drm_warn(display->drm,
|
||||
"Timeout waiting for PHY %c AUX channel power to be up\n",
|
||||
phy_name(phy));
|
||||
@@ -1888,8 +1888,8 @@ static void xelpdp_aux_power_well_disable(struct intel_display *display,
|
||||
0);
|
||||
|
||||
if (DISPLAY_VER(display) >= 35) {
|
||||
if (intel_de_wait_for_clear(display, XELPDP_DP_AUX_CH_CTL(display, aux_ch),
|
||||
XELPDP_DP_AUX_CH_CTL_POWER_STATUS, 1))
|
||||
if (intel_de_wait_for_clear_ms(display, XELPDP_DP_AUX_CH_CTL(display, aux_ch),
|
||||
XELPDP_DP_AUX_CH_CTL_POWER_STATUS, 1))
|
||||
drm_warn(display->drm,
|
||||
"Timeout waiting for PHY %c AUX channel to powerdown\n",
|
||||
phy_name(phy));
|
||||
@@ -1913,8 +1913,8 @@ static void xe2lpd_pica_power_well_enable(struct intel_display *display,
|
||||
intel_de_write(display, XE2LPD_PICA_PW_CTL,
|
||||
XE2LPD_PICA_CTL_POWER_REQUEST);
|
||||
|
||||
if (intel_de_wait_for_set(display, XE2LPD_PICA_PW_CTL,
|
||||
XE2LPD_PICA_CTL_POWER_STATUS, 1)) {
|
||||
if (intel_de_wait_for_set_ms(display, XE2LPD_PICA_PW_CTL,
|
||||
XE2LPD_PICA_CTL_POWER_STATUS, 1)) {
|
||||
drm_dbg_kms(display->drm, "pica power well enable timeout\n");
|
||||
|
||||
drm_WARN(display->drm, 1, "Power well PICA timeout when enabled");
|
||||
@@ -1926,8 +1926,8 @@ static void xe2lpd_pica_power_well_disable(struct intel_display *display,
|
||||
{
|
||||
intel_de_write(display, XE2LPD_PICA_PW_CTL, 0);
|
||||
|
||||
if (intel_de_wait_for_clear(display, XE2LPD_PICA_PW_CTL,
|
||||
XE2LPD_PICA_CTL_POWER_STATUS, 1)) {
|
||||
if (intel_de_wait_for_clear_ms(display, XE2LPD_PICA_PW_CTL,
|
||||
XE2LPD_PICA_CTL_POWER_STATUS, 1)) {
|
||||
drm_dbg_kms(display->drm, "pica power well disable timeout\n");
|
||||
|
||||
drm_WARN(display->drm, 1, "Power well PICA timeout when disabled");
|
||||
|
||||
@@ -726,7 +726,6 @@ struct intel_initial_plane_config {
|
||||
struct intel_memory_region *mem;
|
||||
resource_size_t phys_base;
|
||||
struct i915_vma *vma;
|
||||
unsigned int tiling;
|
||||
int size;
|
||||
u32 base;
|
||||
u8 rotation;
|
||||
@@ -1564,8 +1563,8 @@ struct intel_plane {
|
||||
const struct drm_framebuffer *fb,
|
||||
int color_plane);
|
||||
unsigned int (*max_stride)(struct intel_plane *plane,
|
||||
u32 pixel_format, u64 modifier,
|
||||
unsigned int rotation);
|
||||
const struct drm_format_info *info,
|
||||
u64 modifier, unsigned int rotation);
|
||||
bool (*can_async_flip)(u64 modifier);
|
||||
/* Write all non-self arming plane registers */
|
||||
void (*update_noarm)(struct intel_dsb *dsb,
|
||||
|
||||
@@ -49,7 +49,8 @@ void intel_display_wa_apply(struct intel_display *display)
|
||||
*/
|
||||
static bool intel_display_needs_wa_16025573575(struct intel_display *display)
|
||||
{
|
||||
return DISPLAY_VERx100(display) == 3000 || DISPLAY_VERx100(display) == 3002;
|
||||
return DISPLAY_VERx100(display) == 3000 || DISPLAY_VERx100(display) == 3002 ||
|
||||
DISPLAY_VERx100(display) == 3500;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -127,6 +127,9 @@ static bool dmc_firmware_param_disabled(struct intel_display *display)
|
||||
#define DISPLAY_VER13_DMC_MAX_FW_SIZE 0x20000
|
||||
#define DISPLAY_VER12_DMC_MAX_FW_SIZE ICL_DMC_MAX_FW_SIZE
|
||||
|
||||
#define XE3P_LPD_DMC_PATH DMC_PATH(xe3p_lpd)
|
||||
MODULE_FIRMWARE(XE3P_LPD_DMC_PATH);
|
||||
|
||||
#define XE3LPD_3002_DMC_PATH DMC_PATH(xe3lpd_3002)
|
||||
MODULE_FIRMWARE(XE3LPD_3002_DMC_PATH);
|
||||
|
||||
@@ -186,7 +189,11 @@ static const char *dmc_firmware_default(struct intel_display *display, u32 *size
|
||||
{
|
||||
const char *fw_path = NULL;
|
||||
u32 max_fw_size = 0;
|
||||
if (DISPLAY_VERx100(display) == 3002) {
|
||||
|
||||
if (DISPLAY_VERx100(display) == 3500) {
|
||||
fw_path = XE3P_LPD_DMC_PATH;
|
||||
max_fw_size = XE2LPD_DMC_MAX_FW_SIZE;
|
||||
} else if (DISPLAY_VERx100(display) == 3002) {
|
||||
fw_path = XE3LPD_3002_DMC_PATH;
|
||||
max_fw_size = XE2LPD_DMC_MAX_FW_SIZE;
|
||||
} else if (DISPLAY_VERx100(display) == 3000) {
|
||||
@@ -711,11 +718,11 @@ static bool need_pipedmc_load_program(struct intel_display *display)
|
||||
static bool need_pipedmc_load_mmio(struct intel_display *display, enum pipe pipe)
|
||||
{
|
||||
/*
|
||||
* PTL:
|
||||
* Xe3_LPD/Xe3p_LPD:
|
||||
* - pipe A/B DMC doesn't need save/restore
|
||||
* - pipe C/D DMC is in PG0, needs manual save/restore
|
||||
*/
|
||||
if (DISPLAY_VER(display) == 30)
|
||||
if (IS_DISPLAY_VER(display, 30, 35))
|
||||
return pipe >= PIPE_C;
|
||||
|
||||
/*
|
||||
@@ -1712,14 +1719,14 @@ void intel_pipedmc_irq_handler(struct intel_display *display, enum pipe pipe)
|
||||
drm_err_ratelimited(display->drm, "[CRTC:%d:%s] PIPEDMC GTT fault\n",
|
||||
crtc->base.base.id, crtc->base.name);
|
||||
if (tmp & PIPEDMC_ERROR)
|
||||
drm_err(display->drm, "[CRTC:%d:%s]] PIPEDMC error\n",
|
||||
drm_err(display->drm, "[CRTC:%d:%s] PIPEDMC error\n",
|
||||
crtc->base.base.id, crtc->base.name);
|
||||
}
|
||||
|
||||
int_vector = intel_de_read(display, PIPEDMC_STATUS(pipe)) & PIPEDMC_INT_VECTOR_MASK;
|
||||
if (tmp == 0 && int_vector != 0)
|
||||
drm_err(display->drm, "[CRTC:%d:%s]] PIPEDMC interrupt vector 0x%x\n",
|
||||
crtc->base.base.id, crtc->base.name, tmp);
|
||||
drm_err(display->drm, "[CRTC:%d:%s] PIPEDMC interrupt vector 0x%x\n",
|
||||
crtc->base.base.id, crtc->base.name, int_vector);
|
||||
}
|
||||
|
||||
void intel_pipedmc_enable_event(struct intel_crtc *crtc,
|
||||
|
||||
@@ -179,11 +179,11 @@ static void intel_dmc_wl_work(struct work_struct *work)
|
||||
if (refcount_read(&wl->refcount))
|
||||
goto out_unlock;
|
||||
|
||||
__intel_de_rmw_nowl(display, DMC_WAKELOCK1_CTL, DMC_WAKELOCK_CTL_REQ, 0);
|
||||
intel_de_rmw_fw(display, DMC_WAKELOCK1_CTL, DMC_WAKELOCK_CTL_REQ, 0);
|
||||
|
||||
if (__intel_de_wait_for_register_atomic_nowl(display, DMC_WAKELOCK1_CTL,
|
||||
DMC_WAKELOCK_CTL_ACK, 0,
|
||||
DMC_WAKELOCK_CTL_TIMEOUT_US)) {
|
||||
if (intel_de_wait_fw_us_atomic(display, DMC_WAKELOCK1_CTL,
|
||||
DMC_WAKELOCK_CTL_ACK, 0,
|
||||
DMC_WAKELOCK_CTL_TIMEOUT_US, NULL)) {
|
||||
WARN_RATELIMIT(1, "DMC wakelock release timed out");
|
||||
goto out_unlock;
|
||||
}
|
||||
@@ -207,17 +207,16 @@ static void __intel_dmc_wl_take(struct intel_display *display)
|
||||
if (wl->taken)
|
||||
return;
|
||||
|
||||
__intel_de_rmw_nowl(display, DMC_WAKELOCK1_CTL, 0,
|
||||
DMC_WAKELOCK_CTL_REQ);
|
||||
intel_de_rmw_fw(display, DMC_WAKELOCK1_CTL, 0, DMC_WAKELOCK_CTL_REQ);
|
||||
|
||||
/*
|
||||
* We need to use the atomic variant of the waiting routine
|
||||
* because the DMC wakelock is also taken in atomic context.
|
||||
*/
|
||||
if (__intel_de_wait_for_register_atomic_nowl(display, DMC_WAKELOCK1_CTL,
|
||||
DMC_WAKELOCK_CTL_ACK,
|
||||
DMC_WAKELOCK_CTL_ACK,
|
||||
DMC_WAKELOCK_CTL_TIMEOUT_US)) {
|
||||
if (intel_de_wait_fw_us_atomic(display, DMC_WAKELOCK1_CTL,
|
||||
DMC_WAKELOCK_CTL_ACK,
|
||||
DMC_WAKELOCK_CTL_ACK,
|
||||
DMC_WAKELOCK_CTL_TIMEOUT_US, NULL)) {
|
||||
WARN_RATELIMIT(1, "DMC wakelock ack timed out");
|
||||
return;
|
||||
}
|
||||
@@ -360,7 +359,7 @@ void intel_dmc_wl_enable(struct intel_display *display, u32 dc_state)
|
||||
* wakelock, because we're just enabling it, so call the
|
||||
* non-locking version directly here.
|
||||
*/
|
||||
__intel_de_rmw_nowl(display, DMC_WAKELOCK_CFG, 0, DMC_WAKELOCK_CFG_ENABLE);
|
||||
intel_de_rmw_fw(display, DMC_WAKELOCK_CFG, 0, DMC_WAKELOCK_CFG_ENABLE);
|
||||
|
||||
wl->enabled = true;
|
||||
|
||||
@@ -402,7 +401,7 @@ void intel_dmc_wl_disable(struct intel_display *display)
|
||||
goto out_unlock;
|
||||
|
||||
/* Disable wakelock in DMC */
|
||||
__intel_de_rmw_nowl(display, DMC_WAKELOCK_CFG, DMC_WAKELOCK_CFG_ENABLE, 0);
|
||||
intel_de_rmw_fw(display, DMC_WAKELOCK_CFG, DMC_WAKELOCK_CFG_ENABLE, 0);
|
||||
|
||||
wl->enabled = false;
|
||||
|
||||
@@ -414,7 +413,7 @@ void intel_dmc_wl_disable(struct intel_display *display)
|
||||
*
|
||||
* TODO: Get the correct expectation from the hardware team.
|
||||
*/
|
||||
__intel_de_rmw_nowl(display, DMC_WAKELOCK1_CTL, DMC_WAKELOCK_CTL_REQ, 0);
|
||||
intel_de_rmw_fw(display, DMC_WAKELOCK1_CTL, DMC_WAKELOCK_CTL_REQ, 0);
|
||||
|
||||
wl->taken = false;
|
||||
|
||||
|
||||
@@ -62,9 +62,9 @@ intel_dp_aux_wait_done(struct intel_dp *intel_dp)
|
||||
u32 status;
|
||||
int ret;
|
||||
|
||||
ret = intel_de_wait_custom(display, ch_ctl, DP_AUX_CH_CTL_SEND_BUSY,
|
||||
0,
|
||||
2, timeout_ms, &status);
|
||||
ret = intel_de_wait_ms(display, ch_ctl,
|
||||
DP_AUX_CH_CTL_SEND_BUSY, 0,
|
||||
timeout_ms, &status);
|
||||
|
||||
if (ret == -ETIMEDOUT)
|
||||
drm_err(display->drm,
|
||||
|
||||
@@ -782,9 +782,9 @@ intel_dp_mst_hdcp_stream_encryption(struct intel_connector *connector,
|
||||
return -EINVAL;
|
||||
|
||||
/* Wait for encryption confirmation */
|
||||
if (intel_de_wait(display, HDCP_STATUS(display, cpu_transcoder, port),
|
||||
stream_enc_status, enable ? stream_enc_status : 0,
|
||||
HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS)) {
|
||||
if (intel_de_wait_ms(display, HDCP_STATUS(display, cpu_transcoder, port),
|
||||
stream_enc_status, enable ? stream_enc_status : 0,
|
||||
HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS, NULL)) {
|
||||
drm_err(display->drm, "Timed out waiting for transcoder: %s stream encryption %s\n",
|
||||
transcoder_name(cpu_transcoder), str_enabled_disabled(enable));
|
||||
return -ETIMEDOUT;
|
||||
@@ -821,10 +821,10 @@ intel_dp_mst_hdcp2_stream_encryption(struct intel_connector *connector,
|
||||
return ret;
|
||||
|
||||
/* Wait for encryption confirmation */
|
||||
if (intel_de_wait(display, HDCP2_STREAM_STATUS(display, cpu_transcoder, pipe),
|
||||
STREAM_ENCRYPTION_STATUS,
|
||||
enable ? STREAM_ENCRYPTION_STATUS : 0,
|
||||
HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS)) {
|
||||
if (intel_de_wait_ms(display, HDCP2_STREAM_STATUS(display, cpu_transcoder, pipe),
|
||||
STREAM_ENCRYPTION_STATUS,
|
||||
enable ? STREAM_ENCRYPTION_STATUS : 0,
|
||||
HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS, NULL)) {
|
||||
drm_err(display->drm, "Timed out waiting for transcoder: %s stream encryption %s\n",
|
||||
transcoder_name(cpu_transcoder), str_enabled_disabled(enable));
|
||||
return -ETIMEDOUT;
|
||||
|
||||
@@ -390,7 +390,7 @@ static u32 bxt_get_grc(struct intel_display *display, enum dpio_phy phy)
|
||||
static void bxt_phy_wait_grc_done(struct intel_display *display,
|
||||
enum dpio_phy phy)
|
||||
{
|
||||
if (intel_de_wait_for_set(display, BXT_PORT_REF_DW3(phy), GRC_DONE, 10))
|
||||
if (intel_de_wait_for_set_ms(display, BXT_PORT_REF_DW3(phy), GRC_DONE, 10))
|
||||
drm_err(display->drm, "timeout waiting for PHY%d GRC\n", phy);
|
||||
}
|
||||
|
||||
@@ -427,7 +427,7 @@ static void _bxt_dpio_phy_init(struct intel_display *display, enum dpio_phy phy)
|
||||
* The flag should get set in 100us according to the HW team, but
|
||||
* use 1ms due to occasional timeouts observed with that.
|
||||
*/
|
||||
if (intel_de_wait_fw(display, BXT_PORT_CL1CM_DW0(phy),
|
||||
if (intel_de_wait_ms(display, BXT_PORT_CL1CM_DW0(phy),
|
||||
PHY_RESERVED | PHY_POWER_GOOD, PHY_POWER_GOOD, 1, NULL))
|
||||
drm_err(display->drm, "timeout during PHY%d power on\n",
|
||||
phy);
|
||||
@@ -1173,6 +1173,7 @@ void vlv_wait_port_ready(struct intel_encoder *encoder,
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
u32 port_mask;
|
||||
i915_reg_t dpll_reg;
|
||||
u32 val;
|
||||
|
||||
switch (encoder->port) {
|
||||
default:
|
||||
@@ -1193,10 +1194,9 @@ void vlv_wait_port_ready(struct intel_encoder *encoder,
|
||||
break;
|
||||
}
|
||||
|
||||
if (intel_de_wait(display, dpll_reg, port_mask, expected_mask, 1000))
|
||||
if (intel_de_wait_ms(display, dpll_reg, port_mask, expected_mask, 1000, &val))
|
||||
drm_WARN(display->drm, 1,
|
||||
"timed out waiting for [ENCODER:%d:%s] port ready: got 0x%x, expected 0x%x\n",
|
||||
encoder->base.base.id, encoder->base.name,
|
||||
intel_de_read(display, dpll_reg) & port_mask,
|
||||
expected_mask);
|
||||
val & port_mask, expected_mask);
|
||||
}
|
||||
|
||||
@@ -2019,7 +2019,7 @@ static void _vlv_enable_pll(const struct intel_crtc_state *crtc_state)
|
||||
intel_de_posting_read(display, DPLL(display, pipe));
|
||||
udelay(150);
|
||||
|
||||
if (intel_de_wait_for_set(display, DPLL(display, pipe), DPLL_LOCK_VLV, 1))
|
||||
if (intel_de_wait_for_set_ms(display, DPLL(display, pipe), DPLL_LOCK_VLV, 1))
|
||||
drm_err(display->drm, "DPLL %d failed to lock\n", pipe);
|
||||
}
|
||||
|
||||
@@ -2165,7 +2165,7 @@ static void _chv_enable_pll(const struct intel_crtc_state *crtc_state)
|
||||
intel_de_write(display, DPLL(display, pipe), hw_state->dpll);
|
||||
|
||||
/* Check PLL is locked */
|
||||
if (intel_de_wait_for_set(display, DPLL(display, pipe), DPLL_LOCK_VLV, 1))
|
||||
if (intel_de_wait_for_set_ms(display, DPLL(display, pipe), DPLL_LOCK_VLV, 1))
|
||||
drm_err(display->drm, "PLL %d failed to lock\n", pipe);
|
||||
}
|
||||
|
||||
|
||||
@@ -1395,7 +1395,7 @@ static void skl_ddi_pll_enable(struct intel_display *display,
|
||||
/* the enable bit is always bit 31 */
|
||||
intel_de_rmw(display, regs[id].ctl, 0, LCPLL_PLL_ENABLE);
|
||||
|
||||
if (intel_de_wait_for_set(display, DPLL_STATUS, DPLL_LOCK(id), 5))
|
||||
if (intel_de_wait_for_set_ms(display, DPLL_STATUS, DPLL_LOCK(id), 5))
|
||||
drm_err(display->drm, "DPLL %d not locked\n", id);
|
||||
}
|
||||
|
||||
@@ -2057,9 +2057,9 @@ static void bxt_ddi_pll_enable(struct intel_display *display,
|
||||
intel_de_rmw(display, BXT_PORT_PLL_ENABLE(port),
|
||||
0, PORT_PLL_POWER_ENABLE);
|
||||
|
||||
ret = intel_de_wait_custom(display, BXT_PORT_PLL_ENABLE(port),
|
||||
PORT_PLL_POWER_STATE, PORT_PLL_POWER_STATE,
|
||||
200, 0, NULL);
|
||||
ret = intel_de_wait_for_set_us(display,
|
||||
BXT_PORT_PLL_ENABLE(port),
|
||||
PORT_PLL_POWER_STATE, 200);
|
||||
if (ret)
|
||||
drm_err(display->drm,
|
||||
"Power state not set for PLL:%d\n", port);
|
||||
@@ -2122,9 +2122,8 @@ static void bxt_ddi_pll_enable(struct intel_display *display,
|
||||
intel_de_rmw(display, BXT_PORT_PLL_ENABLE(port), 0, PORT_PLL_ENABLE);
|
||||
intel_de_posting_read(display, BXT_PORT_PLL_ENABLE(port));
|
||||
|
||||
ret = intel_de_wait_custom(display, BXT_PORT_PLL_ENABLE(port),
|
||||
PORT_PLL_LOCK, PORT_PLL_LOCK,
|
||||
200, 0, NULL);
|
||||
ret = intel_de_wait_for_set_us(display, BXT_PORT_PLL_ENABLE(port),
|
||||
PORT_PLL_LOCK, 200);
|
||||
if (ret)
|
||||
drm_err(display->drm, "PLL %d not locked\n", port);
|
||||
|
||||
@@ -2158,9 +2157,9 @@ static void bxt_ddi_pll_disable(struct intel_display *display,
|
||||
intel_de_rmw(display, BXT_PORT_PLL_ENABLE(port),
|
||||
PORT_PLL_POWER_ENABLE, 0);
|
||||
|
||||
ret = intel_de_wait_custom(display, BXT_PORT_PLL_ENABLE(port),
|
||||
PORT_PLL_POWER_STATE, 0,
|
||||
200, 0, NULL);
|
||||
ret = intel_de_wait_for_clear_us(display,
|
||||
BXT_PORT_PLL_ENABLE(port),
|
||||
PORT_PLL_POWER_STATE, 200);
|
||||
if (ret)
|
||||
drm_err(display->drm,
|
||||
"Power state not reset for PLL:%d\n", port);
|
||||
@@ -3921,7 +3920,7 @@ static void icl_pll_power_enable(struct intel_display *display,
|
||||
* The spec says we need to "wait" but it also says it should be
|
||||
* immediate.
|
||||
*/
|
||||
if (intel_de_wait_for_set(display, enable_reg, PLL_POWER_STATE, 1))
|
||||
if (intel_de_wait_for_set_ms(display, enable_reg, PLL_POWER_STATE, 1))
|
||||
drm_err(display->drm, "PLL %d Power not enabled\n",
|
||||
pll->info->id);
|
||||
}
|
||||
@@ -3933,7 +3932,7 @@ static void icl_pll_enable(struct intel_display *display,
|
||||
intel_de_rmw(display, enable_reg, 0, PLL_ENABLE);
|
||||
|
||||
/* Timeout is actually 600us. */
|
||||
if (intel_de_wait_for_set(display, enable_reg, PLL_LOCK, 1))
|
||||
if (intel_de_wait_for_set_ms(display, enable_reg, PLL_LOCK, 1))
|
||||
drm_err(display->drm, "PLL %d not locked\n", pll->info->id);
|
||||
}
|
||||
|
||||
@@ -4046,7 +4045,7 @@ static void icl_pll_disable(struct intel_display *display,
|
||||
intel_de_rmw(display, enable_reg, PLL_ENABLE, 0);
|
||||
|
||||
/* Timeout is actually 1us. */
|
||||
if (intel_de_wait_for_clear(display, enable_reg, PLL_LOCK, 1))
|
||||
if (intel_de_wait_for_clear_ms(display, enable_reg, PLL_LOCK, 1))
|
||||
drm_err(display->drm, "PLL %d locked\n", pll->info->id);
|
||||
|
||||
/* DVFS post sequence would be here. See the comment above. */
|
||||
@@ -4057,7 +4056,7 @@ static void icl_pll_disable(struct intel_display *display,
|
||||
* The spec says we need to "wait" but it also says it should be
|
||||
* immediate.
|
||||
*/
|
||||
if (intel_de_wait_for_clear(display, enable_reg, PLL_POWER_STATE, 1))
|
||||
if (intel_de_wait_for_clear_ms(display, enable_reg, PLL_POWER_STATE, 1))
|
||||
drm_err(display->drm, "PLL %d Power not disabled\n",
|
||||
pll->info->id);
|
||||
}
|
||||
|
||||
@@ -171,6 +171,9 @@ static const u8 *mipi_exec_send_packet(struct intel_dsi *intel_dsi,
|
||||
case MIPI_DSI_DCS_LONG_WRITE:
|
||||
ret = mipi_dsi_dcs_write_buffer(dsi_device, data, len);
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
|
||||
@@ -1326,7 +1326,7 @@ static bool intel_plane_needs_remap(const struct intel_plane_state *plane_state)
|
||||
* unclear in Bspec, for now no checking.
|
||||
*/
|
||||
stride = intel_fb_pitch(fb, 0, rotation);
|
||||
max_stride = plane->max_stride(plane, fb->base.format->format,
|
||||
max_stride = plane->max_stride(plane, fb->base.format,
|
||||
fb->base.modifier, rotation);
|
||||
|
||||
return stride > max_stride;
|
||||
@@ -1972,7 +1972,8 @@ void intel_add_fb_offsets(int *x, int *y,
|
||||
|
||||
static
|
||||
u32 intel_fb_max_stride(struct intel_display *display,
|
||||
u32 pixel_format, u64 modifier)
|
||||
const struct drm_format_info *info,
|
||||
u64 modifier)
|
||||
{
|
||||
/*
|
||||
* Arbitrary limit for gen4+ chosen to match the
|
||||
@@ -1982,7 +1983,7 @@ u32 intel_fb_max_stride(struct intel_display *display,
|
||||
*/
|
||||
if (DISPLAY_VER(display) < 4 || intel_fb_is_ccs_modifier(modifier) ||
|
||||
intel_fb_modifier_uses_dpt(display, modifier))
|
||||
return intel_plane_fb_max_stride(display->drm, pixel_format, modifier);
|
||||
return intel_plane_fb_max_stride(display, info, modifier);
|
||||
else if (DISPLAY_VER(display) >= 7)
|
||||
return 256 * 1024;
|
||||
else
|
||||
@@ -1996,8 +1997,8 @@ intel_fb_stride_alignment(const struct drm_framebuffer *fb, int color_plane)
|
||||
unsigned int tile_width;
|
||||
|
||||
if (is_surface_linear(fb, color_plane)) {
|
||||
unsigned int max_stride = intel_plane_fb_max_stride(display->drm,
|
||||
fb->format->format,
|
||||
unsigned int max_stride = intel_plane_fb_max_stride(display,
|
||||
fb->format,
|
||||
fb->modifier);
|
||||
|
||||
/*
|
||||
@@ -2055,7 +2056,7 @@ static int intel_plane_check_stride(const struct intel_plane_state *plane_state)
|
||||
|
||||
/* FIXME other color planes? */
|
||||
stride = plane_state->view.color_plane[0].mapping_stride;
|
||||
max_stride = plane->max_stride(plane, fb->format->format,
|
||||
max_stride = plane->max_stride(plane, fb->format,
|
||||
fb->modifier, rotation);
|
||||
|
||||
if (stride > max_stride) {
|
||||
@@ -2194,7 +2195,6 @@ static int intel_user_framebuffer_dirty(struct drm_framebuffer *fb,
|
||||
return ret;
|
||||
|
||||
flush:
|
||||
intel_bo_flush_if_display(obj);
|
||||
intel_frontbuffer_flush(front, ORIGIN_DIRTYFB);
|
||||
return ret;
|
||||
}
|
||||
@@ -2234,24 +2234,24 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
|
||||
if (ret)
|
||||
goto err_frontbuffer_put;
|
||||
|
||||
ret = -EINVAL;
|
||||
if (!drm_any_plane_has_format(display->drm,
|
||||
mode_cmd->pixel_format,
|
||||
mode_cmd->modifier[0])) {
|
||||
drm_dbg_kms(display->drm,
|
||||
"unsupported pixel format %p4cc / modifier 0x%llx\n",
|
||||
&mode_cmd->pixel_format, mode_cmd->modifier[0]);
|
||||
ret = -EINVAL;
|
||||
goto err_bo_framebuffer_fini;
|
||||
}
|
||||
|
||||
max_stride = intel_fb_max_stride(display, mode_cmd->pixel_format,
|
||||
mode_cmd->modifier[0]);
|
||||
max_stride = intel_fb_max_stride(display, info, mode_cmd->modifier[0]);
|
||||
if (mode_cmd->pitches[0] > max_stride) {
|
||||
drm_dbg_kms(display->drm,
|
||||
"%s pitch (%u) must be at most %d\n",
|
||||
mode_cmd->modifier[0] != DRM_FORMAT_MOD_LINEAR ?
|
||||
"tiled" : "linear",
|
||||
mode_cmd->pitches[0], max_stride);
|
||||
ret = -EINVAL;
|
||||
goto err_bo_framebuffer_fini;
|
||||
}
|
||||
|
||||
@@ -2260,6 +2260,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
|
||||
drm_dbg_kms(display->drm,
|
||||
"plane 0 offset (0x%08x) must be 0\n",
|
||||
mode_cmd->offsets[0]);
|
||||
ret = -EINVAL;
|
||||
goto err_bo_framebuffer_fini;
|
||||
}
|
||||
|
||||
@@ -2270,6 +2271,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
|
||||
|
||||
if (mode_cmd->handles[i] != mode_cmd->handles[0]) {
|
||||
drm_dbg_kms(display->drm, "bad plane %d handle\n", i);
|
||||
ret = -EINVAL;
|
||||
goto err_bo_framebuffer_fini;
|
||||
}
|
||||
|
||||
@@ -2278,6 +2280,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
|
||||
drm_dbg_kms(display->drm,
|
||||
"plane %d pitch (%d) must be at least %u byte aligned\n",
|
||||
i, fb->pitches[i], stride_alignment);
|
||||
ret = -EINVAL;
|
||||
goto err_bo_framebuffer_fini;
|
||||
}
|
||||
|
||||
@@ -2288,6 +2291,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
|
||||
drm_dbg_kms(display->drm,
|
||||
"ccs aux plane %d pitch (%d) must be %d\n",
|
||||
i, fb->pitches[i], ccs_aux_stride);
|
||||
ret = -EINVAL;
|
||||
goto err_bo_framebuffer_fini;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -328,8 +328,8 @@ static void i8xx_fbc_deactivate(struct intel_fbc *fbc)
|
||||
intel_de_write(display, FBC_CONTROL, fbc_ctl);
|
||||
|
||||
/* Wait for compressing bit to clear */
|
||||
if (intel_de_wait_for_clear(display, FBC_STATUS,
|
||||
FBC_STAT_COMPRESSING, 10)) {
|
||||
if (intel_de_wait_for_clear_ms(display, FBC_STATUS,
|
||||
FBC_STAT_COMPRESSING, 10)) {
|
||||
drm_dbg_kms(display->drm, "FBC idle timed out\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -163,10 +163,10 @@ static void intel_flipq_preempt(struct intel_crtc *crtc, bool preempt)
|
||||
PIPEDMC_FQ_CTRL_PREEMPT, preempt ? PIPEDMC_FQ_CTRL_PREEMPT : 0);
|
||||
|
||||
if (preempt &&
|
||||
intel_de_wait_for_clear(display,
|
||||
PIPEDMC_FQ_STATUS(crtc->pipe),
|
||||
PIPEDMC_FQ_STATUS_BUSY,
|
||||
intel_flipq_preempt_timeout_ms(display)))
|
||||
intel_de_wait_for_clear_ms(display,
|
||||
PIPEDMC_FQ_STATUS(crtc->pipe),
|
||||
PIPEDMC_FQ_STATUS_BUSY,
|
||||
intel_flipq_preempt_timeout_ms(display)))
|
||||
drm_err(display->drm, "[CRTC:%d:%s] flip queue preempt timeout\n",
|
||||
crtc->base.base.id, crtc->base.name);
|
||||
}
|
||||
|
||||
@@ -58,8 +58,6 @@
|
||||
#include <drm/drm_gem.h>
|
||||
#include <drm/drm_print.h>
|
||||
|
||||
#include "i915_active.h"
|
||||
#include "i915_vma.h"
|
||||
#include "intel_bo.h"
|
||||
#include "intel_display_trace.h"
|
||||
#include "intel_display_types.h"
|
||||
@@ -103,51 +101,6 @@ static void frontbuffer_flush(struct intel_display *display,
|
||||
intel_fbc_flush(display, frontbuffer_bits, origin);
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_frontbuffer_flip_prepare - prepare asynchronous frontbuffer flip
|
||||
* @display: display device
|
||||
* @frontbuffer_bits: frontbuffer plane tracking bits
|
||||
*
|
||||
* This function gets called after scheduling a flip on @obj. The actual
|
||||
* frontbuffer flushing will be delayed until completion is signalled with
|
||||
* intel_frontbuffer_flip_complete. If an invalidate happens in between this
|
||||
* flush will be cancelled.
|
||||
*
|
||||
* Can be called without any locks held.
|
||||
*/
|
||||
void intel_frontbuffer_flip_prepare(struct intel_display *display,
|
||||
unsigned frontbuffer_bits)
|
||||
{
|
||||
spin_lock(&display->fb_tracking.lock);
|
||||
display->fb_tracking.flip_bits |= frontbuffer_bits;
|
||||
/* Remove stale busy bits due to the old buffer. */
|
||||
display->fb_tracking.busy_bits &= ~frontbuffer_bits;
|
||||
spin_unlock(&display->fb_tracking.lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_frontbuffer_flip_complete - complete asynchronous frontbuffer flip
|
||||
* @display: display device
|
||||
* @frontbuffer_bits: frontbuffer plane tracking bits
|
||||
*
|
||||
* This function gets called after the flip has been latched and will complete
|
||||
* on the next vblank. It will execute the flush if it hasn't been cancelled yet.
|
||||
*
|
||||
* Can be called without any locks held.
|
||||
*/
|
||||
void intel_frontbuffer_flip_complete(struct intel_display *display,
|
||||
unsigned frontbuffer_bits)
|
||||
{
|
||||
spin_lock(&display->fb_tracking.lock);
|
||||
/* Mask any cancelled flips. */
|
||||
frontbuffer_bits &= display->fb_tracking.flip_bits;
|
||||
display->fb_tracking.flip_bits &= ~frontbuffer_bits;
|
||||
spin_unlock(&display->fb_tracking.lock);
|
||||
|
||||
if (frontbuffer_bits)
|
||||
frontbuffer_flush(display, frontbuffer_bits, ORIGIN_FLIP);
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_frontbuffer_flip - synchronous frontbuffer flip
|
||||
* @display: display device
|
||||
@@ -174,12 +127,11 @@ void __intel_fb_invalidate(struct intel_frontbuffer *front,
|
||||
enum fb_op_origin origin,
|
||||
unsigned int frontbuffer_bits)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(front->obj->dev);
|
||||
struct intel_display *display = front->display;
|
||||
|
||||
if (origin == ORIGIN_CS) {
|
||||
spin_lock(&display->fb_tracking.lock);
|
||||
display->fb_tracking.busy_bits |= frontbuffer_bits;
|
||||
display->fb_tracking.flip_bits &= ~frontbuffer_bits;
|
||||
spin_unlock(&display->fb_tracking.lock);
|
||||
}
|
||||
|
||||
@@ -195,7 +147,10 @@ void __intel_fb_flush(struct intel_frontbuffer *front,
|
||||
enum fb_op_origin origin,
|
||||
unsigned int frontbuffer_bits)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(front->obj->dev);
|
||||
struct intel_display *display = front->display;
|
||||
|
||||
if (origin == ORIGIN_DIRTYFB)
|
||||
intel_bo_frontbuffer_flush_for_display(front);
|
||||
|
||||
if (origin == ORIGIN_CS) {
|
||||
spin_lock(&display->fb_tracking.lock);
|
||||
@@ -209,12 +164,16 @@ void __intel_fb_flush(struct intel_frontbuffer *front,
|
||||
frontbuffer_flush(display, frontbuffer_bits, origin);
|
||||
}
|
||||
|
||||
static void intel_frontbuffer_ref(struct intel_frontbuffer *front)
|
||||
{
|
||||
intel_bo_frontbuffer_ref(front);
|
||||
}
|
||||
|
||||
static void intel_frontbuffer_flush_work(struct work_struct *work)
|
||||
{
|
||||
struct intel_frontbuffer *front =
|
||||
container_of(work, struct intel_frontbuffer, flush_work);
|
||||
|
||||
intel_bo_flush_if_display(front->obj);
|
||||
intel_frontbuffer_flush(front, ORIGIN_DIRTYFB);
|
||||
intel_frontbuffer_put(front);
|
||||
}
|
||||
@@ -231,93 +190,31 @@ void intel_frontbuffer_queue_flush(struct intel_frontbuffer *front)
|
||||
if (!front)
|
||||
return;
|
||||
|
||||
kref_get(&front->ref);
|
||||
intel_frontbuffer_ref(front);
|
||||
if (!schedule_work(&front->flush_work))
|
||||
intel_frontbuffer_put(front);
|
||||
}
|
||||
|
||||
static int frontbuffer_active(struct i915_active *ref)
|
||||
void intel_frontbuffer_init(struct intel_frontbuffer *front, struct drm_device *drm)
|
||||
{
|
||||
struct intel_frontbuffer *front =
|
||||
container_of(ref, typeof(*front), write);
|
||||
|
||||
kref_get(&front->ref);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void frontbuffer_retire(struct i915_active *ref)
|
||||
{
|
||||
struct intel_frontbuffer *front =
|
||||
container_of(ref, typeof(*front), write);
|
||||
|
||||
intel_frontbuffer_flush(front, ORIGIN_CS);
|
||||
intel_frontbuffer_put(front);
|
||||
}
|
||||
|
||||
static void frontbuffer_release(struct kref *ref)
|
||||
__releases(&to_intel_display(front->obj->dev)->fb_tracking.lock)
|
||||
{
|
||||
struct intel_frontbuffer *ret, *front =
|
||||
container_of(ref, typeof(*front), ref);
|
||||
struct drm_gem_object *obj = front->obj;
|
||||
struct intel_display *display = to_intel_display(obj->dev);
|
||||
|
||||
drm_WARN_ON(display->drm, atomic_read(&front->bits));
|
||||
|
||||
i915_ggtt_clear_scanout(to_intel_bo(obj));
|
||||
|
||||
ret = intel_bo_set_frontbuffer(obj, NULL);
|
||||
drm_WARN_ON(display->drm, ret);
|
||||
spin_unlock(&display->fb_tracking.lock);
|
||||
|
||||
i915_active_fini(&front->write);
|
||||
|
||||
drm_gem_object_put(obj);
|
||||
kfree_rcu(front, rcu);
|
||||
}
|
||||
|
||||
struct intel_frontbuffer *
|
||||
intel_frontbuffer_get(struct drm_gem_object *obj)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(obj->dev);
|
||||
struct intel_frontbuffer *front, *cur;
|
||||
|
||||
front = intel_bo_get_frontbuffer(obj);
|
||||
if (front)
|
||||
return front;
|
||||
|
||||
front = kmalloc(sizeof(*front), GFP_KERNEL);
|
||||
if (!front)
|
||||
return NULL;
|
||||
|
||||
drm_gem_object_get(obj);
|
||||
|
||||
front->obj = obj;
|
||||
kref_init(&front->ref);
|
||||
front->display = to_intel_display(drm);
|
||||
atomic_set(&front->bits, 0);
|
||||
i915_active_init(&front->write,
|
||||
frontbuffer_active,
|
||||
frontbuffer_retire,
|
||||
I915_ACTIVE_RETIRE_SLEEPS);
|
||||
INIT_WORK(&front->flush_work, intel_frontbuffer_flush_work);
|
||||
}
|
||||
|
||||
spin_lock(&display->fb_tracking.lock);
|
||||
cur = intel_bo_set_frontbuffer(obj, front);
|
||||
spin_unlock(&display->fb_tracking.lock);
|
||||
void intel_frontbuffer_fini(struct intel_frontbuffer *front)
|
||||
{
|
||||
drm_WARN_ON(front->display->drm, atomic_read(&front->bits));
|
||||
}
|
||||
|
||||
if (cur != front) {
|
||||
drm_gem_object_put(obj);
|
||||
kfree(front);
|
||||
}
|
||||
|
||||
return cur;
|
||||
struct intel_frontbuffer *intel_frontbuffer_get(struct drm_gem_object *obj)
|
||||
{
|
||||
return intel_bo_frontbuffer_get(obj);
|
||||
}
|
||||
|
||||
void intel_frontbuffer_put(struct intel_frontbuffer *front)
|
||||
{
|
||||
kref_put_lock(&front->ref,
|
||||
frontbuffer_release,
|
||||
&to_intel_display(front->obj->dev)->fb_tracking.lock);
|
||||
intel_bo_frontbuffer_put(front);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -346,17 +243,13 @@ void intel_frontbuffer_track(struct intel_frontbuffer *old,
|
||||
BUILD_BUG_ON(I915_MAX_PLANES > INTEL_FRONTBUFFER_BITS_PER_PIPE);
|
||||
|
||||
if (old) {
|
||||
struct intel_display *display = to_intel_display(old->obj->dev);
|
||||
|
||||
drm_WARN_ON(display->drm,
|
||||
drm_WARN_ON(old->display->drm,
|
||||
!(atomic_read(&old->bits) & frontbuffer_bits));
|
||||
atomic_andnot(frontbuffer_bits, &old->bits);
|
||||
}
|
||||
|
||||
if (new) {
|
||||
struct intel_display *display = to_intel_display(new->obj->dev);
|
||||
|
||||
drm_WARN_ON(display->drm,
|
||||
drm_WARN_ON(new->display->drm,
|
||||
atomic_read(&new->bits) & frontbuffer_bits);
|
||||
atomic_or(frontbuffer_bits, &new->bits);
|
||||
}
|
||||
|
||||
@@ -26,10 +26,9 @@
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/bits.h>
|
||||
#include <linux/kref.h>
|
||||
|
||||
#include "i915_active_types.h"
|
||||
#include <linux/workqueue_types.h>
|
||||
|
||||
struct drm_device;
|
||||
struct drm_gem_object;
|
||||
struct intel_display;
|
||||
|
||||
@@ -42,12 +41,8 @@ enum fb_op_origin {
|
||||
};
|
||||
|
||||
struct intel_frontbuffer {
|
||||
struct kref ref;
|
||||
struct intel_display *display;
|
||||
atomic_t bits;
|
||||
struct i915_active write;
|
||||
struct drm_gem_object *obj;
|
||||
struct rcu_head rcu;
|
||||
|
||||
struct work_struct flush_work;
|
||||
};
|
||||
|
||||
@@ -68,10 +63,6 @@ struct intel_frontbuffer {
|
||||
GENMASK(INTEL_FRONTBUFFER_BITS_PER_PIPE * ((pipe) + 1) - 1, \
|
||||
INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe))
|
||||
|
||||
void intel_frontbuffer_flip_prepare(struct intel_display *display,
|
||||
unsigned frontbuffer_bits);
|
||||
void intel_frontbuffer_flip_complete(struct intel_display *display,
|
||||
unsigned frontbuffer_bits);
|
||||
void intel_frontbuffer_flip(struct intel_display *display,
|
||||
unsigned frontbuffer_bits);
|
||||
|
||||
@@ -144,4 +135,7 @@ void intel_frontbuffer_track(struct intel_frontbuffer *old,
|
||||
struct intel_frontbuffer *new,
|
||||
unsigned int frontbuffer_bits);
|
||||
|
||||
void intel_frontbuffer_init(struct intel_frontbuffer *front, struct drm_device *drm);
|
||||
void intel_frontbuffer_fini(struct intel_frontbuffer *front);
|
||||
|
||||
#endif /* __INTEL_FRONTBUFFER_H__ */
|
||||
|
||||
@@ -449,7 +449,7 @@ gmbus_wait_idle(struct intel_display *display)
|
||||
add_wait_queue(&display->gmbus.wait_queue, &wait);
|
||||
intel_de_write_fw(display, GMBUS4(display), irq_enable);
|
||||
|
||||
ret = intel_de_wait_fw(display, GMBUS2(display), GMBUS_ACTIVE, 0, 10, NULL);
|
||||
ret = intel_de_wait_fw_ms(display, GMBUS2(display), GMBUS_ACTIVE, 0, 10, NULL);
|
||||
|
||||
intel_de_write_fw(display, GMBUS4(display), 0);
|
||||
remove_wait_queue(&display->gmbus.wait_queue, &wait);
|
||||
|
||||
@@ -410,9 +410,8 @@ static int intel_hdcp_load_keys(struct intel_display *display)
|
||||
}
|
||||
|
||||
/* Wait for the keys to load (500us) */
|
||||
ret = intel_de_wait_custom(display, HDCP_KEY_STATUS,
|
||||
HDCP_KEY_LOAD_DONE, HDCP_KEY_LOAD_DONE,
|
||||
10, 1, &val);
|
||||
ret = intel_de_wait_ms(display, HDCP_KEY_STATUS, HDCP_KEY_LOAD_DONE,
|
||||
HDCP_KEY_LOAD_DONE, 1, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
else if (!(val & HDCP_KEY_LOAD_STATUS))
|
||||
@@ -428,7 +427,7 @@ static int intel_hdcp_load_keys(struct intel_display *display)
|
||||
static int intel_write_sha_text(struct intel_display *display, u32 sha_text)
|
||||
{
|
||||
intel_de_write(display, HDCP_SHA_TEXT, sha_text);
|
||||
if (intel_de_wait_for_set(display, HDCP_REP_CTL, HDCP_SHA1_READY, 1)) {
|
||||
if (intel_de_wait_for_set_ms(display, HDCP_REP_CTL, HDCP_SHA1_READY, 1)) {
|
||||
drm_err(display->drm, "Timed out waiting for SHA1 ready\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
@@ -707,8 +706,8 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector,
|
||||
/* Tell the HW we're done with the hash and wait for it to ACK */
|
||||
intel_de_write(display, HDCP_REP_CTL,
|
||||
rep_ctl | HDCP_SHA1_COMPLETE_HASH);
|
||||
if (intel_de_wait_for_set(display, HDCP_REP_CTL,
|
||||
HDCP_SHA1_COMPLETE, 1)) {
|
||||
if (intel_de_wait_for_set_ms(display, HDCP_REP_CTL,
|
||||
HDCP_SHA1_COMPLETE, 1)) {
|
||||
drm_err(display->drm, "Timed out waiting for SHA1 complete\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
@@ -856,9 +855,9 @@ static int intel_hdcp_auth(struct intel_connector *connector)
|
||||
HDCP_CONF_CAPTURE_AN);
|
||||
|
||||
/* Wait for An to be acquired */
|
||||
if (intel_de_wait_for_set(display,
|
||||
HDCP_STATUS(display, cpu_transcoder, port),
|
||||
HDCP_STATUS_AN_READY, 1)) {
|
||||
if (intel_de_wait_for_set_ms(display,
|
||||
HDCP_STATUS(display, cpu_transcoder, port),
|
||||
HDCP_STATUS_AN_READY, 1)) {
|
||||
drm_err(display->drm, "Timed out waiting for An\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
@@ -953,10 +952,10 @@ static int intel_hdcp_auth(struct intel_connector *connector)
|
||||
}
|
||||
|
||||
/* Wait for encryption confirmation */
|
||||
if (intel_de_wait_for_set(display,
|
||||
HDCP_STATUS(display, cpu_transcoder, port),
|
||||
HDCP_STATUS_ENC,
|
||||
HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS)) {
|
||||
if (intel_de_wait_for_set_ms(display,
|
||||
HDCP_STATUS(display, cpu_transcoder, port),
|
||||
HDCP_STATUS_ENC,
|
||||
HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS)) {
|
||||
drm_err(display->drm, "Timed out waiting for encryption\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
@@ -1013,9 +1012,9 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
|
||||
|
||||
hdcp->hdcp_encrypted = false;
|
||||
intel_de_write(display, HDCP_CONF(display, cpu_transcoder, port), 0);
|
||||
if (intel_de_wait_for_clear(display,
|
||||
HDCP_STATUS(display, cpu_transcoder, port),
|
||||
~0, HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS)) {
|
||||
if (intel_de_wait_for_clear_ms(display,
|
||||
HDCP_STATUS(display, cpu_transcoder, port),
|
||||
~0, HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS)) {
|
||||
drm_err(display->drm,
|
||||
"Failed to disable HDCP, timeout clearing status\n");
|
||||
return -ETIMEDOUT;
|
||||
@@ -1940,11 +1939,10 @@ static int hdcp2_enable_encryption(struct intel_connector *connector)
|
||||
intel_de_rmw(display, HDCP2_CTL(display, cpu_transcoder, port),
|
||||
0, CTL_LINK_ENCRYPTION_REQ);
|
||||
|
||||
ret = intel_de_wait_for_set(display,
|
||||
HDCP2_STATUS(display, cpu_transcoder,
|
||||
port),
|
||||
LINK_ENCRYPTION_STATUS,
|
||||
HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS);
|
||||
ret = intel_de_wait_for_set_ms(display,
|
||||
HDCP2_STATUS(display, cpu_transcoder, port),
|
||||
LINK_ENCRYPTION_STATUS,
|
||||
HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS);
|
||||
dig_port->hdcp.auth_status = true;
|
||||
|
||||
return ret;
|
||||
@@ -1966,11 +1964,10 @@ static int hdcp2_disable_encryption(struct intel_connector *connector)
|
||||
intel_de_rmw(display, HDCP2_CTL(display, cpu_transcoder, port),
|
||||
CTL_LINK_ENCRYPTION_REQ, 0);
|
||||
|
||||
ret = intel_de_wait_for_clear(display,
|
||||
HDCP2_STATUS(display, cpu_transcoder,
|
||||
port),
|
||||
LINK_ENCRYPTION_STATUS,
|
||||
HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS);
|
||||
ret = intel_de_wait_for_clear_ms(display,
|
||||
HDCP2_STATUS(display, cpu_transcoder, port),
|
||||
LINK_ENCRYPTION_STATUS,
|
||||
HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS);
|
||||
if (ret == -ETIMEDOUT)
|
||||
drm_dbg_kms(display->drm, "Disable Encryption Timedout");
|
||||
|
||||
|
||||
@@ -1598,8 +1598,8 @@ bool intel_hdmi_hdcp_check_link_once(struct intel_digital_port *dig_port,
|
||||
intel_de_write(display, HDCP_RPRIME(display, cpu_transcoder, port), ri.reg);
|
||||
|
||||
/* Wait for Ri prime match */
|
||||
ret = intel_de_wait_for_set(display, HDCP_STATUS(display, cpu_transcoder, port),
|
||||
HDCP_STATUS_RI_MATCH | HDCP_STATUS_ENC, 1);
|
||||
ret = intel_de_wait_for_set_ms(display, HDCP_STATUS(display, cpu_transcoder, port),
|
||||
HDCP_STATUS_RI_MATCH | HDCP_STATUS_ENC, 1);
|
||||
if (ret) {
|
||||
drm_dbg_kms(display->drm, "Ri' mismatch detected (%x)\n",
|
||||
intel_de_read(display, HDCP_STATUS(display, cpu_transcoder,
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include <drm/drm_print.h>
|
||||
|
||||
#include "i915_reg.h"
|
||||
#include "i915_utils.h"
|
||||
#include "intel_cx0_phy.h"
|
||||
#include "intel_cx0_phy_regs.h"
|
||||
#include "intel_ddi.h"
|
||||
@@ -14,6 +13,7 @@
|
||||
#include "intel_de.h"
|
||||
#include "intel_display.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_display_utils.h"
|
||||
#include "intel_dpll_mgr.h"
|
||||
#include "intel_hdmi.h"
|
||||
#include "intel_lt_phy.h"
|
||||
@@ -31,6 +31,32 @@
|
||||
#define INTEL_LT_PHY_BOTH_LANES (INTEL_LT_PHY_LANE1 |\
|
||||
INTEL_LT_PHY_LANE0)
|
||||
#define MODE_DP 3
|
||||
#define Q32_TO_INT(x) ((x) >> 32)
|
||||
#define Q32_TO_FRAC(x) ((x) & 0xFFFFFFFF)
|
||||
#define DCO_MIN_FREQ_MHZ 11850
|
||||
#define REF_CLK_KHZ 38400
|
||||
#define TDC_RES_MULTIPLIER 10000000ULL
|
||||
|
||||
struct phy_param_t {
|
||||
u32 val;
|
||||
u32 addr;
|
||||
};
|
||||
|
||||
struct lt_phy_params {
|
||||
struct phy_param_t pll_reg4;
|
||||
struct phy_param_t pll_reg3;
|
||||
struct phy_param_t pll_reg5;
|
||||
struct phy_param_t pll_reg57;
|
||||
struct phy_param_t lf;
|
||||
struct phy_param_t tdc;
|
||||
struct phy_param_t ssc;
|
||||
struct phy_param_t bias2;
|
||||
struct phy_param_t bias_trim;
|
||||
struct phy_param_t dco_med;
|
||||
struct phy_param_t dco_fine;
|
||||
struct phy_param_t ssc_inj;
|
||||
struct phy_param_t surv_bonus;
|
||||
};
|
||||
|
||||
static const struct intel_lt_phy_pll_state xe3plpd_lt_dp_rbr = {
|
||||
.clock = 162000,
|
||||
@@ -1041,9 +1067,9 @@ static int __intel_lt_phy_p2p_write_once(struct intel_encoder *encoder,
|
||||
int ack;
|
||||
u32 val;
|
||||
|
||||
if (intel_de_wait_for_clear(display, XELPDP_PORT_M2P_MSGBUS_CTL(display, port, lane),
|
||||
XELPDP_PORT_P2P_TRANSACTION_PENDING,
|
||||
XELPDP_MSGBUS_TIMEOUT_SLOW)) {
|
||||
if (intel_de_wait_for_clear_ms(display, XELPDP_PORT_M2P_MSGBUS_CTL(display, port, lane),
|
||||
XELPDP_PORT_P2P_TRANSACTION_PENDING,
|
||||
XELPDP_MSGBUS_TIMEOUT_MS)) {
|
||||
drm_dbg_kms(display->drm,
|
||||
"PHY %c Timeout waiting for previous transaction to complete. Resetting bus.\n",
|
||||
phy_name(phy));
|
||||
@@ -1175,13 +1201,11 @@ intel_lt_phy_lane_reset(struct intel_encoder *encoder,
|
||||
XELPDP_LANE_PCLK_PLL_REQUEST(0),
|
||||
XELPDP_LANE_PCLK_PLL_REQUEST(0));
|
||||
|
||||
if (intel_de_wait_custom(display, XELPDP_PORT_CLOCK_CTL(display, port),
|
||||
XELPDP_LANE_PCLK_PLL_ACK(0),
|
||||
XELPDP_LANE_PCLK_PLL_ACK(0),
|
||||
XE3PLPD_MACCLK_TURNON_LATENCY_US,
|
||||
XE3PLPD_MACCLK_TURNON_LATENCY_MS, NULL))
|
||||
drm_warn(display->drm, "PHY %c PLL MacCLK assertion Ack not done after %dus.\n",
|
||||
phy_name(phy), XE3PLPD_MACCLK_TURNON_LATENCY_MS * 1000);
|
||||
if (intel_de_wait_for_set_ms(display, XELPDP_PORT_CLOCK_CTL(display, port),
|
||||
XELPDP_LANE_PCLK_PLL_ACK(0),
|
||||
XE3PLPD_MACCLK_TURNON_LATENCY_MS))
|
||||
drm_warn(display->drm, "PHY %c PLL MacCLK assertion ack not done\n",
|
||||
phy_name(phy));
|
||||
|
||||
intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, port),
|
||||
XELPDP_FORWARD_CLOCK_UNGATE,
|
||||
@@ -1190,18 +1214,17 @@ intel_lt_phy_lane_reset(struct intel_encoder *encoder,
|
||||
intel_de_rmw(display, XELPDP_PORT_BUF_CTL2(display, port),
|
||||
lane_pipe_reset | lane_phy_pulse_status, 0);
|
||||
|
||||
if (intel_de_wait_custom(display, XELPDP_PORT_BUF_CTL2(display, port),
|
||||
lane_phy_current_status, 0,
|
||||
XE3PLPD_RESET_END_LATENCY_US, 2, NULL))
|
||||
drm_warn(display->drm,
|
||||
"PHY %c failed to bring out of Lane reset after %dus.\n",
|
||||
phy_name(phy), XE3PLPD_RESET_END_LATENCY_US);
|
||||
if (intel_de_wait_for_clear_ms(display, XELPDP_PORT_BUF_CTL2(display, port),
|
||||
lane_phy_current_status,
|
||||
XE3PLPD_RESET_END_LATENCY_MS))
|
||||
drm_warn(display->drm, "PHY %c failed to bring out of lane reset\n",
|
||||
phy_name(phy));
|
||||
|
||||
if (intel_de_wait_custom(display, XELPDP_PORT_BUF_CTL2(display, port),
|
||||
lane_phy_pulse_status, lane_phy_pulse_status,
|
||||
XE3PLPD_RATE_CALIB_DONE_LATENCY_US, 0, NULL))
|
||||
drm_warn(display->drm, "PHY %c PLL rate not changed after %dus.\n",
|
||||
phy_name(phy), XE3PLPD_RATE_CALIB_DONE_LATENCY_US);
|
||||
if (intel_de_wait_for_set_ms(display, XELPDP_PORT_BUF_CTL2(display, port),
|
||||
lane_phy_pulse_status,
|
||||
XE3PLPD_RATE_CALIB_DONE_LATENCY_MS))
|
||||
drm_warn(display->drm, "PHY %c PLL rate not changed\n",
|
||||
phy_name(phy));
|
||||
|
||||
intel_de_rmw(display, XELPDP_PORT_BUF_CTL2(display, port), lane_phy_pulse_status, 0);
|
||||
}
|
||||
@@ -1356,10 +1379,308 @@ intel_lt_phy_pll_is_ssc_enabled(struct intel_crtc_state *crtc_state,
|
||||
return false;
|
||||
}
|
||||
|
||||
static int
|
||||
intel_lt_phy_calc_hdmi_port_clock(const struct intel_lt_phy_pll_state *lt_state)
|
||||
static u64 mul_q32_u32(u64 a_q32, u32 b)
|
||||
{
|
||||
u64 p0, p1, carry, result;
|
||||
u64 x_hi = a_q32 >> 32;
|
||||
u64 x_lo = a_q32 & 0xFFFFFFFFULL;
|
||||
|
||||
p0 = x_lo * (u64)b;
|
||||
p1 = x_hi * (u64)b;
|
||||
carry = p0 >> 32;
|
||||
result = (p1 << 32) + (carry << 32) + (p0 & 0xFFFFFFFFULL);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool
|
||||
calculate_target_dco_and_loop_cnt(u32 frequency_khz, u64 *target_dco_mhz, u32 *loop_cnt)
|
||||
{
|
||||
u32 ppm_value = 1;
|
||||
u32 dco_min_freq = DCO_MIN_FREQ_MHZ;
|
||||
u32 dco_max_freq = 16200;
|
||||
u32 dco_min_freq_low = 10000;
|
||||
u32 dco_max_freq_low = 12000;
|
||||
u64 val = 0;
|
||||
u64 refclk_khz = REF_CLK_KHZ;
|
||||
u64 m2div = 0;
|
||||
u64 val_with_frac = 0;
|
||||
u64 ppm = 0;
|
||||
u64 temp0 = 0, temp1, scale;
|
||||
int ppm_cnt, dco_count, y;
|
||||
|
||||
for (ppm_cnt = 0; ppm_cnt < 5; ppm_cnt++) {
|
||||
ppm_value = ppm_cnt == 2 ? 2 : 1;
|
||||
for (dco_count = 0; dco_count < 2; dco_count++) {
|
||||
if (dco_count == 1) {
|
||||
dco_min_freq = dco_min_freq_low;
|
||||
dco_max_freq = dco_max_freq_low;
|
||||
}
|
||||
for (y = 2; y <= 255; y += 2) {
|
||||
val = div64_u64((u64)y * frequency_khz, 200);
|
||||
m2div = div64_u64(((u64)(val) << 32), refclk_khz);
|
||||
m2div = mul_q32_u32(m2div, 500);
|
||||
val_with_frac = mul_q32_u32(m2div, refclk_khz);
|
||||
val_with_frac = div64_u64(val_with_frac, 500);
|
||||
temp1 = Q32_TO_INT(val_with_frac);
|
||||
temp0 = (temp1 > val) ? (temp1 - val) :
|
||||
(val - temp1);
|
||||
ppm = div64_u64(temp0, val);
|
||||
if (temp1 >= dco_min_freq &&
|
||||
temp1 <= dco_max_freq &&
|
||||
ppm < ppm_value) {
|
||||
/* Round to two places */
|
||||
scale = (1ULL << 32) / 100;
|
||||
temp0 = DIV_ROUND_UP_ULL(val_with_frac,
|
||||
scale);
|
||||
*target_dco_mhz = temp0 * scale;
|
||||
*loop_cnt = y;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void set_phy_vdr_addresses(struct lt_phy_params *p, int pll_type)
|
||||
{
|
||||
p->pll_reg4.addr = PLL_REG_ADDR(PLL_REG4_ADDR, pll_type);
|
||||
p->pll_reg3.addr = PLL_REG_ADDR(PLL_REG3_ADDR, pll_type);
|
||||
p->pll_reg5.addr = PLL_REG_ADDR(PLL_REG5_ADDR, pll_type);
|
||||
p->pll_reg57.addr = PLL_REG_ADDR(PLL_REG57_ADDR, pll_type);
|
||||
p->lf.addr = PLL_REG_ADDR(PLL_LF_ADDR, pll_type);
|
||||
p->tdc.addr = PLL_REG_ADDR(PLL_TDC_ADDR, pll_type);
|
||||
p->ssc.addr = PLL_REG_ADDR(PLL_SSC_ADDR, pll_type);
|
||||
p->bias2.addr = PLL_REG_ADDR(PLL_BIAS2_ADDR, pll_type);
|
||||
p->bias_trim.addr = PLL_REG_ADDR(PLL_BIAS_TRIM_ADDR, pll_type);
|
||||
p->dco_med.addr = PLL_REG_ADDR(PLL_DCO_MED_ADDR, pll_type);
|
||||
p->dco_fine.addr = PLL_REG_ADDR(PLL_DCO_FINE_ADDR, pll_type);
|
||||
p->ssc_inj.addr = PLL_REG_ADDR(PLL_SSC_INJ_ADDR, pll_type);
|
||||
p->surv_bonus.addr = PLL_REG_ADDR(PLL_SURV_BONUS_ADDR, pll_type);
|
||||
}
|
||||
|
||||
static void compute_ssc(struct lt_phy_params *p, u32 ana_cfg)
|
||||
{
|
||||
int ssc_stepsize = 0;
|
||||
int ssc_steplen = 0;
|
||||
int ssc_steplog = 0;
|
||||
|
||||
p->ssc.val = (1 << 31) | (ana_cfg << 24) | (ssc_steplog << 16) |
|
||||
(ssc_stepsize << 8) | ssc_steplen;
|
||||
}
|
||||
|
||||
static void compute_bias2(struct lt_phy_params *p)
|
||||
{
|
||||
u32 ssc_en_local = 0;
|
||||
u64 dynctrl_ovrd_en = 0;
|
||||
|
||||
p->bias2.val = (dynctrl_ovrd_en << 31) | (ssc_en_local << 30) |
|
||||
(1 << 23) | (1 << 24) | (32 << 16) | (1 << 8);
|
||||
}
|
||||
|
||||
static void compute_tdc(struct lt_phy_params *p, u64 tdc_fine)
|
||||
{
|
||||
u32 settling_time = 15;
|
||||
u32 bias_ovr_en = 1;
|
||||
u32 coldstart = 1;
|
||||
u32 true_lock = 2;
|
||||
u32 early_lock = 1;
|
||||
u32 lock_ovr_en = 1;
|
||||
u32 lock_thr = tdc_fine ? 3 : 5;
|
||||
u32 unlock_thr = tdc_fine ? 5 : 11;
|
||||
|
||||
p->tdc.val = (u32)((2 << 30) + (settling_time << 16) + (bias_ovr_en << 15) +
|
||||
(lock_ovr_en << 14) + (coldstart << 12) + (true_lock << 10) +
|
||||
(early_lock << 8) + (unlock_thr << 4) + lock_thr);
|
||||
}
|
||||
|
||||
static void compute_dco_med(struct lt_phy_params *p)
|
||||
{
|
||||
u32 cselmed_en = 0;
|
||||
u32 cselmed_dyn_adj = 0;
|
||||
u32 cselmed_ratio = 39;
|
||||
u32 cselmed_thr = 8;
|
||||
|
||||
p->dco_med.val = (cselmed_en << 31) + (cselmed_dyn_adj << 30) +
|
||||
(cselmed_ratio << 24) + (cselmed_thr << 21);
|
||||
}
|
||||
|
||||
static void compute_dco_fine(struct lt_phy_params *p, u32 dco_12g)
|
||||
{
|
||||
u32 dco_fine0_tune_2_0 = 0;
|
||||
u32 dco_fine1_tune_2_0 = 0;
|
||||
u32 dco_fine2_tune_2_0 = 0;
|
||||
u32 dco_fine3_tune_2_0 = 0;
|
||||
u32 dco_dith0_tune_2_0 = 0;
|
||||
u32 dco_dith1_tune_2_0 = 0;
|
||||
|
||||
dco_fine0_tune_2_0 = dco_12g ? 4 : 3;
|
||||
dco_fine1_tune_2_0 = 2;
|
||||
dco_fine2_tune_2_0 = dco_12g ? 2 : 1;
|
||||
dco_fine3_tune_2_0 = 5;
|
||||
dco_dith0_tune_2_0 = dco_12g ? 4 : 3;
|
||||
dco_dith1_tune_2_0 = 2;
|
||||
|
||||
p->dco_fine.val = (dco_dith1_tune_2_0 << 19) +
|
||||
(dco_dith0_tune_2_0 << 16) +
|
||||
(dco_fine3_tune_2_0 << 11) +
|
||||
(dco_fine2_tune_2_0 << 8) +
|
||||
(dco_fine1_tune_2_0 << 3) +
|
||||
dco_fine0_tune_2_0;
|
||||
}
|
||||
|
||||
int
|
||||
intel_lt_phy_calculate_hdmi_state(struct intel_lt_phy_pll_state *lt_state,
|
||||
u32 frequency_khz)
|
||||
{
|
||||
#define DATA_ASSIGN(i, pll_reg) \
|
||||
do { \
|
||||
lt_state->data[i][0] = (u8)((((pll_reg).val) & 0xFF000000) >> 24); \
|
||||
lt_state->data[i][1] = (u8)((((pll_reg).val) & 0x00FF0000) >> 16); \
|
||||
lt_state->data[i][2] = (u8)((((pll_reg).val) & 0x0000FF00) >> 8); \
|
||||
lt_state->data[i][3] = (u8)((((pll_reg).val) & 0x000000FF)); \
|
||||
} while (0)
|
||||
#define ADDR_ASSIGN(i, pll_reg) \
|
||||
do { \
|
||||
lt_state->addr_msb[i] = ((pll_reg).addr >> 8) & 0xFF; \
|
||||
lt_state->addr_lsb[i] = (pll_reg).addr & 0xFF; \
|
||||
} while (0)
|
||||
|
||||
bool found = false;
|
||||
struct lt_phy_params p;
|
||||
u32 dco_fmin = DCO_MIN_FREQ_MHZ;
|
||||
u64 refclk_khz = REF_CLK_KHZ;
|
||||
u32 refclk_mhz_int = REF_CLK_KHZ / 1000;
|
||||
u64 m2div = 0;
|
||||
u64 target_dco_mhz = 0;
|
||||
u64 tdc_fine, tdc_targetcnt;
|
||||
u64 feedfwd_gain ,feedfwd_cal_en;
|
||||
u64 tdc_res = 30;
|
||||
u32 prop_coeff;
|
||||
u32 int_coeff;
|
||||
u32 ndiv = 1;
|
||||
u32 m1div = 1, m2div_int, m2div_frac;
|
||||
u32 frac_en;
|
||||
u32 ana_cfg;
|
||||
u32 loop_cnt = 0;
|
||||
u32 gain_ctrl = 2;
|
||||
u32 postdiv = 0;
|
||||
u32 dco_12g = 0;
|
||||
u32 pll_type = 0;
|
||||
u32 d1 = 2, d3 = 5, d4 = 0, d5 = 0;
|
||||
u32 d6 = 0, d6_new = 0;
|
||||
u32 d7, d8 = 0;
|
||||
u32 bonus_7_0 = 0;
|
||||
u32 csel2fo = 11;
|
||||
u32 csel2fo_ovrd_en = 1;
|
||||
u64 temp0, temp1, temp2, temp3;
|
||||
|
||||
p.surv_bonus.val = (bonus_7_0 << 16);
|
||||
p.pll_reg4.val = (refclk_mhz_int << 17) +
|
||||
(ndiv << 9) + (1 << 4);
|
||||
p.bias_trim.val = (csel2fo_ovrd_en << 30) + (csel2fo << 24);
|
||||
p.ssc_inj.val = 0;
|
||||
found = calculate_target_dco_and_loop_cnt(frequency_khz, &target_dco_mhz, &loop_cnt);
|
||||
if (!found)
|
||||
return -EINVAL;
|
||||
|
||||
m2div = div64_u64(target_dco_mhz, (refclk_khz * ndiv * m1div));
|
||||
m2div = mul_q32_u32(m2div, 1000);
|
||||
if (Q32_TO_INT(m2div) > 511)
|
||||
return -EINVAL;
|
||||
|
||||
m2div_int = (u32)Q32_TO_INT(m2div);
|
||||
m2div_frac = (u32)(Q32_TO_FRAC(m2div));
|
||||
frac_en = (m2div_frac > 0) ? 1 : 0;
|
||||
|
||||
if (frac_en > 0)
|
||||
tdc_res = 70;
|
||||
else
|
||||
tdc_res = 36;
|
||||
tdc_fine = tdc_res > 50 ? 1 : 0;
|
||||
temp0 = tdc_res * 40 * 11;
|
||||
temp1 = div64_u64(((4 * TDC_RES_MULTIPLIER) + temp0) * 500, temp0 * refclk_khz);
|
||||
temp2 = div64_u64(temp0 * refclk_khz, 1000);
|
||||
temp3 = div64_u64(((8 * TDC_RES_MULTIPLIER) + temp2), temp2);
|
||||
tdc_targetcnt = tdc_res < 50 ? (int)(temp1) : (int)(temp3);
|
||||
tdc_targetcnt = (int)(tdc_targetcnt / 2);
|
||||
temp0 = mul_q32_u32(target_dco_mhz, tdc_res);
|
||||
temp0 >>= 32;
|
||||
feedfwd_gain = (m2div_frac > 0) ? div64_u64(m1div * TDC_RES_MULTIPLIER, temp0) : 0;
|
||||
feedfwd_cal_en = frac_en;
|
||||
|
||||
temp0 = (u32)Q32_TO_INT(target_dco_mhz);
|
||||
prop_coeff = (temp0 >= dco_fmin) ? 3 : 4;
|
||||
int_coeff = (temp0 >= dco_fmin) ? 7 : 8;
|
||||
ana_cfg = (temp0 >= dco_fmin) ? 8 : 6;
|
||||
dco_12g = (temp0 >= dco_fmin) ? 0 : 1;
|
||||
|
||||
if (temp0 > 12960)
|
||||
d7 = 10;
|
||||
else
|
||||
d7 = 8;
|
||||
|
||||
d8 = loop_cnt / 2;
|
||||
d4 = d8 * 2;
|
||||
|
||||
/* Compute pll_reg3,5,57 & lf */
|
||||
p.pll_reg3.val = (u32)((d4 << 21) + (d3 << 18) + (d1 << 15) + (m2div_int << 5));
|
||||
p.pll_reg5.val = m2div_frac;
|
||||
postdiv = (d5 == 0) ? 9 : d5;
|
||||
d6_new = (d6 == 0) ? 40 : d6;
|
||||
p.pll_reg57.val = (d7 << 24) + (postdiv << 15) + (d8 << 7) + d6_new;
|
||||
p.lf.val = (u32)((frac_en << 31) + (1 << 30) + (frac_en << 29) +
|
||||
(feedfwd_cal_en << 28) + (tdc_fine << 27) +
|
||||
(gain_ctrl << 24) + (feedfwd_gain << 16) +
|
||||
(int_coeff << 12) + (prop_coeff << 8) + tdc_targetcnt);
|
||||
|
||||
compute_ssc(&p, ana_cfg);
|
||||
compute_bias2(&p);
|
||||
compute_tdc(&p, tdc_fine);
|
||||
compute_dco_med(&p);
|
||||
compute_dco_fine(&p, dco_12g);
|
||||
|
||||
pll_type = ((frequency_khz == 10000) || (frequency_khz == 20000) ||
|
||||
(frequency_khz == 2500) || (dco_12g == 1)) ? 0 : 1;
|
||||
set_phy_vdr_addresses(&p, pll_type);
|
||||
|
||||
lt_state->config[0] = 0x84;
|
||||
lt_state->config[1] = 0x2d;
|
||||
ADDR_ASSIGN(0, p.pll_reg4);
|
||||
ADDR_ASSIGN(1, p.pll_reg3);
|
||||
ADDR_ASSIGN(2, p.pll_reg5);
|
||||
ADDR_ASSIGN(3, p.pll_reg57);
|
||||
ADDR_ASSIGN(4, p.lf);
|
||||
ADDR_ASSIGN(5, p.tdc);
|
||||
ADDR_ASSIGN(6, p.ssc);
|
||||
ADDR_ASSIGN(7, p.bias2);
|
||||
ADDR_ASSIGN(8, p.bias_trim);
|
||||
ADDR_ASSIGN(9, p.dco_med);
|
||||
ADDR_ASSIGN(10, p.dco_fine);
|
||||
ADDR_ASSIGN(11, p.ssc_inj);
|
||||
ADDR_ASSIGN(12, p.surv_bonus);
|
||||
DATA_ASSIGN(0, p.pll_reg4);
|
||||
DATA_ASSIGN(1, p.pll_reg3);
|
||||
DATA_ASSIGN(2, p.pll_reg5);
|
||||
DATA_ASSIGN(3, p.pll_reg57);
|
||||
DATA_ASSIGN(4, p.lf);
|
||||
DATA_ASSIGN(5, p.tdc);
|
||||
DATA_ASSIGN(6, p.ssc);
|
||||
DATA_ASSIGN(7, p.bias2);
|
||||
DATA_ASSIGN(8, p.bias_trim);
|
||||
DATA_ASSIGN(9, p.dco_med);
|
||||
DATA_ASSIGN(10, p.dco_fine);
|
||||
DATA_ASSIGN(11, p.ssc_inj);
|
||||
DATA_ASSIGN(12, p.surv_bonus);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
intel_lt_phy_calc_hdmi_port_clock(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
#define REF_CLK_KHZ 38400
|
||||
#define REGVAL(i) ( \
|
||||
(lt_state->data[i][3]) | \
|
||||
(lt_state->data[i][2] << 8) | \
|
||||
@@ -1367,6 +1688,9 @@ intel_lt_phy_calc_hdmi_port_clock(const struct intel_lt_phy_pll_state *lt_state)
|
||||
(lt_state->data[i][0] << 24) \
|
||||
)
|
||||
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
const struct intel_lt_phy_pll_state *lt_state =
|
||||
&crtc_state->dpll_hw_state.ltpll;
|
||||
int clk = 0;
|
||||
u32 d8, pll_reg_5, pll_reg_3, pll_reg_57, m2div_frac, m2div_int;
|
||||
u64 temp0, temp1;
|
||||
@@ -1409,11 +1733,14 @@ intel_lt_phy_calc_hdmi_port_clock(const struct intel_lt_phy_pll_state *lt_state)
|
||||
* frequency = (m2div * refclk_khz / (d8 * 10))
|
||||
*/
|
||||
d8 = (pll_reg_57 & REG_GENMASK(14, 7)) >> 7;
|
||||
if (d8 == 0) {
|
||||
drm_WARN_ON(display->drm,
|
||||
"Invalid port clock using lowest HDMI portclock\n");
|
||||
return xe3plpd_lt_hdmi_252.clock;
|
||||
}
|
||||
m2div_int = (pll_reg_3 & REG_GENMASK(14, 5)) >> 5;
|
||||
temp0 = ((u64)m2div_frac * REF_CLK_KHZ) >> 32;
|
||||
temp1 = (u64)m2div_int * REF_CLK_KHZ;
|
||||
if (d8 == 0)
|
||||
return 0;
|
||||
|
||||
clk = div_u64((temp1 + temp0), d8 * 10);
|
||||
|
||||
@@ -1442,7 +1769,7 @@ intel_lt_phy_calc_port_clock(struct intel_encoder *encoder,
|
||||
lt_state->config[0]);
|
||||
clk = intel_lt_phy_get_dp_clock(rate);
|
||||
} else {
|
||||
clk = intel_lt_phy_calc_hdmi_port_clock(lt_state);
|
||||
clk = intel_lt_phy_calc_hdmi_port_clock(crtc_state);
|
||||
}
|
||||
|
||||
return clk;
|
||||
@@ -1472,7 +1799,10 @@ intel_lt_phy_pll_calc_state(struct intel_crtc_state *crtc_state,
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: Add a function to compute the data for HDMI TMDS*/
|
||||
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
|
||||
return intel_lt_phy_calculate_hdmi_state(&crtc_state->dpll_hw_state.ltpll,
|
||||
crtc_state->port_clock);
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -1651,11 +1981,11 @@ void intel_lt_phy_pll_enable(struct intel_encoder *encoder,
|
||||
XELPDP_LANE_PCLK_PLL_REQUEST(0), 0);
|
||||
|
||||
/* 8. Poll for PORT_CLOCK_CTL[PCLK PLL Ack LN0]= 0. */
|
||||
if (intel_de_wait_custom(display, XELPDP_PORT_CLOCK_CTL(display, port),
|
||||
XELPDP_LANE_PCLK_PLL_ACK(0), 0,
|
||||
XE3PLPD_MACCLK_TURNOFF_LATENCY_US, 0, NULL))
|
||||
drm_warn(display->drm, "PHY %c PLL MacCLK Ack deassertion Timeout after %dus.\n",
|
||||
phy_name(phy), XE3PLPD_MACCLK_TURNOFF_LATENCY_US);
|
||||
if (intel_de_wait_for_clear_us(display, XELPDP_PORT_CLOCK_CTL(display, port),
|
||||
XELPDP_LANE_PCLK_PLL_ACK(0),
|
||||
XE3PLPD_MACCLK_TURNOFF_LATENCY_US))
|
||||
drm_warn(display->drm, "PHY %c PLL MacCLK ack deassertion timeout\n",
|
||||
phy_name(phy));
|
||||
|
||||
/*
|
||||
* 9. Follow the Display Voltage Frequency Switching - Sequence Before Frequency
|
||||
@@ -1671,12 +2001,11 @@ void intel_lt_phy_pll_enable(struct intel_encoder *encoder,
|
||||
XELPDP_LANE_PCLK_PLL_REQUEST(0));
|
||||
|
||||
/* 12. Poll for PORT_CLOCK_CTL[PCLK PLL Ack LN0]= 1. */
|
||||
if (intel_de_wait_custom(display, XELPDP_PORT_CLOCK_CTL(display, port),
|
||||
XELPDP_LANE_PCLK_PLL_ACK(0),
|
||||
XELPDP_LANE_PCLK_PLL_ACK(0),
|
||||
XE3PLPD_MACCLK_TURNON_LATENCY_US, 2, NULL))
|
||||
drm_warn(display->drm, "PHY %c PLL MacCLK Ack assertion Timeout after %dus.\n",
|
||||
phy_name(phy), XE3PLPD_MACCLK_TURNON_LATENCY_US);
|
||||
if (intel_de_wait_for_set_ms(display, XELPDP_PORT_CLOCK_CTL(display, port),
|
||||
XELPDP_LANE_PCLK_PLL_ACK(0),
|
||||
XE3PLPD_MACCLK_TURNON_LATENCY_MS))
|
||||
drm_warn(display->drm, "PHY %c PLL MacCLK ack assertion timeout\n",
|
||||
phy_name(phy));
|
||||
|
||||
/*
|
||||
* 13. Ungate the forward clock by setting
|
||||
@@ -1700,11 +2029,11 @@ void intel_lt_phy_pll_enable(struct intel_encoder *encoder,
|
||||
rate_update, MB_WRITE_COMMITTED);
|
||||
|
||||
/* 16. Poll for PORT_BUF_CTL2 register PHY Pulse Status = 1 for Owned PHY Lanes. */
|
||||
if (intel_de_wait_custom(display, XELPDP_PORT_BUF_CTL2(display, port),
|
||||
lane_phy_pulse_status, lane_phy_pulse_status,
|
||||
XE3PLPD_RATE_CALIB_DONE_LATENCY_US, 2, NULL))
|
||||
drm_warn(display->drm, "PHY %c PLL rate not changed after %dus.\n",
|
||||
phy_name(phy), XE3PLPD_RATE_CALIB_DONE_LATENCY_US);
|
||||
if (intel_de_wait_for_set_ms(display, XELPDP_PORT_BUF_CTL2(display, port),
|
||||
lane_phy_pulse_status,
|
||||
XE3PLPD_RATE_CALIB_DONE_LATENCY_MS))
|
||||
drm_warn(display->drm, "PHY %c PLL rate not changed\n",
|
||||
phy_name(phy));
|
||||
|
||||
/* 17. SW clears PORT_BUF_CTL2 [PHY Pulse Status]. */
|
||||
intel_de_rmw(display, XELPDP_PORT_BUF_CTL2(display, port),
|
||||
@@ -1758,13 +2087,11 @@ void intel_lt_phy_pll_disable(struct intel_encoder *encoder)
|
||||
lane_pipe_reset);
|
||||
|
||||
/* 3. Poll for PORT_BUF_CTL2<port> Lane<PHY Lanes Owned> PHY Current Status == 1. */
|
||||
if (intel_de_wait_custom(display, XELPDP_PORT_BUF_CTL2(display, port),
|
||||
lane_phy_current_status,
|
||||
lane_phy_current_status,
|
||||
XE3PLPD_RESET_START_LATENCY_US, 0, NULL))
|
||||
drm_warn(display->drm,
|
||||
"PHY %c failed to reset Lane after %dms.\n",
|
||||
phy_name(phy), XE3PLPD_RESET_START_LATENCY_US);
|
||||
if (intel_de_wait_for_set_us(display, XELPDP_PORT_BUF_CTL2(display, port),
|
||||
lane_phy_current_status,
|
||||
XE3PLPD_RESET_START_LATENCY_US))
|
||||
drm_warn(display->drm, "PHY %c failed to reset lane\n",
|
||||
phy_name(phy));
|
||||
|
||||
/* 4. Clear for PHY pulse status on owned PHY lanes. */
|
||||
intel_de_rmw(display, XELPDP_PORT_BUF_CTL2(display, port),
|
||||
@@ -1783,11 +2110,11 @@ void intel_lt_phy_pll_disable(struct intel_encoder *encoder)
|
||||
intel_de_write(display, DDI_CLK_VALFREQ(encoder->port), 0);
|
||||
|
||||
/* 8. Poll for PORT_CLOCK_CTL[PCLK PLL Ack LN0]= 0. */
|
||||
if (intel_de_wait_custom(display, XELPDP_PORT_CLOCK_CTL(display, port),
|
||||
XELPDP_LANE_PCLK_PLL_ACK(0), 0,
|
||||
XE3PLPD_MACCLK_TURNOFF_LATENCY_US, 0, NULL))
|
||||
drm_warn(display->drm, "PHY %c PLL MacCLK Ack deassertion Timeout after %dus.\n",
|
||||
phy_name(phy), XE3PLPD_MACCLK_TURNOFF_LATENCY_US);
|
||||
if (intel_de_wait_for_clear_us(display, XELPDP_PORT_CLOCK_CTL(display, port),
|
||||
XELPDP_LANE_PCLK_PLL_ACK(0),
|
||||
XE3PLPD_MACCLK_TURNOFF_LATENCY_US))
|
||||
drm_warn(display->drm, "PHY %c PLL MacCLK ack deassertion timeout\n",
|
||||
phy_name(phy));
|
||||
|
||||
/*
|
||||
* 9. Follow the Display Voltage Frequency Switching -
|
||||
|
||||
@@ -35,6 +35,9 @@ void intel_lt_phy_pll_readout_hw_state(struct intel_encoder *encoder,
|
||||
struct intel_lt_phy_pll_state *pll_state);
|
||||
void intel_lt_phy_pll_state_verify(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc);
|
||||
int
|
||||
intel_lt_phy_calculate_hdmi_state(struct intel_lt_phy_pll_state *lt_state,
|
||||
u32 frequency_khz);
|
||||
void intel_xe3plpd_pll_enable(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state);
|
||||
void intel_xe3plpd_pll_disable(struct intel_encoder *encoder);
|
||||
|
||||
@@ -7,13 +7,12 @@
|
||||
#define __INTEL_LT_PHY_REGS_H__
|
||||
|
||||
#define XE3PLPD_MSGBUS_TIMEOUT_FAST_US 500
|
||||
#define XE3PLPD_MACCLK_TURNON_LATENCY_MS 1
|
||||
#define XE3PLPD_MACCLK_TURNON_LATENCY_US 21
|
||||
#define XE3PLPD_MACCLK_TURNON_LATENCY_MS 2
|
||||
#define XE3PLPD_MACCLK_TURNOFF_LATENCY_US 1
|
||||
#define XE3PLPD_RATE_CALIB_DONE_LATENCY_US 50
|
||||
#define XE3PLPD_RATE_CALIB_DONE_LATENCY_MS 1
|
||||
#define XE3PLPD_RESET_START_LATENCY_US 10
|
||||
#define XE3PLPD_PWRDN_TO_RDY_LATENCY_US 4
|
||||
#define XE3PLPD_RESET_END_LATENCY_US 200
|
||||
#define XE3PLPD_RESET_END_LATENCY_MS 2
|
||||
|
||||
/* LT Phy MAC Register */
|
||||
#define LT_PHY_MAC_VDR _MMIO(0xC00)
|
||||
@@ -72,4 +71,20 @@
|
||||
#define XE3PLPD_PORT_P2M_MSGBUS_STATUS_P2P(port, lane) _XE3PLPD_PORT_P2M_MSGBUS_STATUS_P2P(__xe2lpd_port_idx(port), \
|
||||
lane)
|
||||
#define XE3LPD_PORT_P2M_ADDR_MASK REG_GENMASK(11, 0)
|
||||
|
||||
#define PLL_REG4_ADDR 0x8510
|
||||
#define PLL_REG3_ADDR 0x850C
|
||||
#define PLL_REG5_ADDR 0x8514
|
||||
#define PLL_REG57_ADDR 0x85E4
|
||||
#define PLL_LF_ADDR 0x860C
|
||||
#define PLL_TDC_ADDR 0x8610
|
||||
#define PLL_SSC_ADDR 0x8614
|
||||
#define PLL_BIAS2_ADDR 0x8618
|
||||
#define PLL_BIAS_TRIM_ADDR 0x8648
|
||||
#define PLL_DCO_MED_ADDR 0x8640
|
||||
#define PLL_DCO_FINE_ADDR 0x864C
|
||||
#define PLL_SSC_INJ_ADDR 0x8624
|
||||
#define PLL_SURV_BONUS_ADDR 0x8644
|
||||
#define PLL_TYPE_OFFSET 0x200
|
||||
#define PLL_REG_ADDR(base, pll_type) ((pll_type) ? (base) + PLL_TYPE_OFFSET : (base))
|
||||
#endif /* __INTEL_LT_PHY_REGS_H__ */
|
||||
|
||||
@@ -329,7 +329,7 @@ static void intel_enable_lvds(struct intel_atomic_state *state,
|
||||
intel_de_rmw(display, PP_CONTROL(display, 0), 0, PANEL_POWER_ON);
|
||||
intel_de_posting_read(display, lvds_encoder->reg);
|
||||
|
||||
if (intel_de_wait_for_set(display, PP_STATUS(display, 0), PP_ON, 5000))
|
||||
if (intel_de_wait_for_set_ms(display, PP_STATUS(display, 0), PP_ON, 5000))
|
||||
drm_err(display->drm,
|
||||
"timed out waiting for panel to power on\n");
|
||||
|
||||
@@ -345,7 +345,7 @@ static void intel_disable_lvds(struct intel_atomic_state *state,
|
||||
struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(encoder);
|
||||
|
||||
intel_de_rmw(display, PP_CONTROL(display, 0), PANEL_POWER_ON, 0);
|
||||
if (intel_de_wait_for_clear(display, PP_STATUS(display, 0), PP_ON, 1000))
|
||||
if (intel_de_wait_for_clear_ms(display, PP_STATUS(display, 0), PP_ON, 1000))
|
||||
drm_err(display->drm,
|
||||
"timed out waiting for panel to power off\n");
|
||||
|
||||
@@ -384,7 +384,7 @@ static void intel_lvds_shutdown(struct intel_encoder *encoder)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
|
||||
if (intel_de_wait_for_clear(display, PP_STATUS(display, 0), PP_CYCLE_DELAY_ACTIVE, 5000))
|
||||
if (intel_de_wait_for_clear_ms(display, PP_STATUS(display, 0), PP_CYCLE_DELAY_ACTIVE, 5000))
|
||||
drm_err(display->drm,
|
||||
"timed out waiting for panel power cycle delay\n");
|
||||
}
|
||||
|
||||
@@ -308,8 +308,6 @@ static void intel_overlay_flip_prepare(struct intel_overlay *overlay,
|
||||
intel_frontbuffer_put(overlay->frontbuffer);
|
||||
overlay->frontbuffer = frontbuffer;
|
||||
|
||||
intel_frontbuffer_flip_prepare(display, INTEL_FRONTBUFFER_OVERLAY(pipe));
|
||||
|
||||
overlay->old_vma = overlay->vma;
|
||||
if (vma)
|
||||
overlay->vma = i915_vma_get(vma);
|
||||
@@ -366,7 +364,7 @@ static void intel_overlay_release_old_vma(struct intel_overlay *overlay)
|
||||
if (drm_WARN_ON(display->drm, !vma))
|
||||
return;
|
||||
|
||||
intel_frontbuffer_flip_complete(display, INTEL_FRONTBUFFER_OVERLAY(overlay->crtc->pipe));
|
||||
intel_frontbuffer_flip(display, INTEL_FRONTBUFFER_OVERLAY(overlay->crtc->pipe));
|
||||
|
||||
i915_vma_unpin(vma);
|
||||
i915_vma_put(vma);
|
||||
@@ -822,8 +820,6 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
|
||||
goto out_pin_section;
|
||||
}
|
||||
|
||||
i915_gem_object_flush_frontbuffer(new_bo, ORIGIN_DIRTYFB);
|
||||
|
||||
if (!overlay->active) {
|
||||
const struct intel_crtc_state *crtc_state =
|
||||
overlay->crtc->config;
|
||||
|
||||
@@ -305,7 +305,7 @@ static void ilk_enable_pch_transcoder(const struct intel_crtc_state *crtc_state)
|
||||
}
|
||||
|
||||
intel_de_write(display, reg, val | TRANS_ENABLE);
|
||||
if (intel_de_wait_for_set(display, reg, TRANS_STATE_ENABLE, 100))
|
||||
if (intel_de_wait_for_set_ms(display, reg, TRANS_STATE_ENABLE, 100))
|
||||
drm_err(display->drm, "failed to enable transcoder %c\n",
|
||||
pipe_name(pipe));
|
||||
}
|
||||
@@ -326,7 +326,7 @@ static void ilk_disable_pch_transcoder(struct intel_crtc *crtc)
|
||||
reg = PCH_TRANSCONF(pipe);
|
||||
intel_de_rmw(display, reg, TRANS_ENABLE, 0);
|
||||
/* wait for PCH transcoder off, transcoder state */
|
||||
if (intel_de_wait_for_clear(display, reg, TRANS_STATE_ENABLE, 50))
|
||||
if (intel_de_wait_for_clear_ms(display, reg, TRANS_STATE_ENABLE, 50))
|
||||
drm_err(display->drm, "failed to disable transcoder %c\n",
|
||||
pipe_name(pipe));
|
||||
|
||||
@@ -572,8 +572,8 @@ static void lpt_enable_pch_transcoder(const struct intel_crtc_state *crtc_state)
|
||||
val |= TRANS_INTERLACE_PROGRESSIVE;
|
||||
|
||||
intel_de_write(display, LPT_TRANSCONF, val);
|
||||
if (intel_de_wait_for_set(display, LPT_TRANSCONF,
|
||||
TRANS_STATE_ENABLE, 100))
|
||||
if (intel_de_wait_for_set_ms(display, LPT_TRANSCONF,
|
||||
TRANS_STATE_ENABLE, 100))
|
||||
drm_err(display->drm, "Failed to enable PCH transcoder\n");
|
||||
}
|
||||
|
||||
@@ -581,8 +581,8 @@ static void lpt_disable_pch_transcoder(struct intel_display *display)
|
||||
{
|
||||
intel_de_rmw(display, LPT_TRANSCONF, TRANS_ENABLE, 0);
|
||||
/* wait for PCH transcoder off, transcoder state */
|
||||
if (intel_de_wait_for_clear(display, LPT_TRANSCONF,
|
||||
TRANS_STATE_ENABLE, 50))
|
||||
if (intel_de_wait_for_clear_ms(display, LPT_TRANSCONF,
|
||||
TRANS_STATE_ENABLE, 50))
|
||||
drm_err(display->drm, "Failed to disable PCH transcoder\n");
|
||||
|
||||
/* Workaround: clear timing override bit. */
|
||||
|
||||
@@ -21,17 +21,15 @@ static void lpt_fdi_reset_mphy(struct intel_display *display)
|
||||
|
||||
intel_de_rmw(display, SOUTH_CHICKEN2, 0, FDI_MPHY_IOSFSB_RESET_CTL);
|
||||
|
||||
ret = intel_de_wait_custom(display, SOUTH_CHICKEN2,
|
||||
FDI_MPHY_IOSFSB_RESET_STATUS, FDI_MPHY_IOSFSB_RESET_STATUS,
|
||||
100, 0, NULL);
|
||||
ret = intel_de_wait_for_set_us(display, SOUTH_CHICKEN2,
|
||||
FDI_MPHY_IOSFSB_RESET_STATUS, 100);
|
||||
if (ret)
|
||||
drm_err(display->drm, "FDI mPHY reset assert timeout\n");
|
||||
|
||||
intel_de_rmw(display, SOUTH_CHICKEN2, FDI_MPHY_IOSFSB_RESET_CTL, 0);
|
||||
|
||||
ret = intel_de_wait_custom(display, SOUTH_CHICKEN2,
|
||||
FDI_MPHY_IOSFSB_RESET_STATUS, 0,
|
||||
100, 0, NULL);
|
||||
ret = intel_de_wait_for_clear_us(display, SOUTH_CHICKEN2,
|
||||
FDI_MPHY_IOSFSB_RESET_STATUS, 100);
|
||||
if (ret)
|
||||
drm_err(display->drm, "FDI mPHY reset de-assert timeout\n");
|
||||
}
|
||||
|
||||
@@ -1051,6 +1051,9 @@ int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state)
|
||||
DISPLAY_VERx100(display) == 3002) &&
|
||||
src_x % 2 != 0)
|
||||
hsub = 2;
|
||||
|
||||
if (DISPLAY_VER(display) == 35)
|
||||
vsub = 2;
|
||||
} else {
|
||||
hsub = fb->format->hsub;
|
||||
vsub = fb->format->vsub;
|
||||
|
||||
@@ -133,6 +133,7 @@ initial_plane_vma(struct intel_display *display,
|
||||
struct drm_mm_node orig_mm = {};
|
||||
struct i915_vma *vma;
|
||||
resource_size_t phys_base;
|
||||
unsigned int tiling;
|
||||
u32 base, size;
|
||||
u64 pinctl;
|
||||
|
||||
@@ -179,17 +180,19 @@ initial_plane_vma(struct intel_display *display,
|
||||
i915_gem_object_set_cache_coherency(obj, HAS_WT(i915) ?
|
||||
I915_CACHE_WT : I915_CACHE_NONE);
|
||||
|
||||
switch (plane_config->tiling) {
|
||||
tiling = intel_fb_modifier_to_tiling(plane_config->fb->base.modifier);
|
||||
|
||||
switch (tiling) {
|
||||
case I915_TILING_NONE:
|
||||
break;
|
||||
case I915_TILING_X:
|
||||
case I915_TILING_Y:
|
||||
obj->tiling_and_stride =
|
||||
plane_config->fb->base.pitches[0] |
|
||||
plane_config->tiling;
|
||||
tiling;
|
||||
break;
|
||||
default:
|
||||
MISSING_CASE(plane_config->tiling);
|
||||
MISSING_CASE(tiling);
|
||||
goto err_obj;
|
||||
}
|
||||
|
||||
@@ -374,7 +377,7 @@ valid_fb:
|
||||
plane_state->uapi.crtc_w = fb->width;
|
||||
plane_state->uapi.crtc_h = fb->height;
|
||||
|
||||
if (plane_config->tiling)
|
||||
if (fb->modifier != DRM_FORMAT_MOD_LINEAR)
|
||||
dev_priv->preserve_bios_swizzle = true;
|
||||
|
||||
plane_state->uapi.fb = fb;
|
||||
|
||||
@@ -390,12 +390,12 @@ int intel_pmdemand_atomic_check(struct intel_atomic_state *state)
|
||||
|
||||
static bool intel_pmdemand_check_prev_transaction(struct intel_display *display)
|
||||
{
|
||||
return !(intel_de_wait_for_clear(display,
|
||||
XELPDP_INITIATE_PMDEMAND_REQUEST(1),
|
||||
XELPDP_PMDEMAND_REQ_ENABLE, 10) ||
|
||||
intel_de_wait_for_clear(display,
|
||||
GEN12_DCPR_STATUS_1,
|
||||
XELPDP_PMDEMAND_INFLIGHT_STATUS, 10));
|
||||
return !(intel_de_wait_for_clear_ms(display,
|
||||
XELPDP_INITIATE_PMDEMAND_REQUEST(1),
|
||||
XELPDP_PMDEMAND_REQ_ENABLE, 10) ||
|
||||
intel_de_wait_for_clear_ms(display,
|
||||
GEN12_DCPR_STATUS_1,
|
||||
XELPDP_PMDEMAND_INFLIGHT_STATUS, 10));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -462,9 +462,9 @@ static void intel_pmdemand_poll(struct intel_display *display)
|
||||
u32 status;
|
||||
int ret;
|
||||
|
||||
ret = intel_de_wait_custom(display, XELPDP_INITIATE_PMDEMAND_REQUEST(1),
|
||||
XELPDP_PMDEMAND_REQ_ENABLE, 0,
|
||||
50, timeout_ms, &status);
|
||||
ret = intel_de_wait_ms(display, XELPDP_INITIATE_PMDEMAND_REQUEST(1),
|
||||
XELPDP_PMDEMAND_REQ_ENABLE, 0,
|
||||
timeout_ms, &status);
|
||||
|
||||
if (ret == -ETIMEDOUT)
|
||||
drm_err(display->drm,
|
||||
|
||||
@@ -626,6 +626,10 @@ static void _panel_replay_init_dpcd(struct intel_dp *intel_dp)
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
int ret;
|
||||
|
||||
/* TODO: Enable Panel Replay on MST once it's properly implemented. */
|
||||
if (intel_dp->mst_detect == DRM_DP_MST)
|
||||
return;
|
||||
|
||||
ret = drm_dp_dpcd_read_data(&intel_dp->aux, DP_PANEL_REPLAY_CAP_SUPPORT,
|
||||
&intel_dp->pr_dpcd, sizeof(intel_dp->pr_dpcd));
|
||||
if (ret < 0)
|
||||
@@ -932,7 +936,8 @@ static bool is_dc5_dc6_blocked(struct intel_dp *intel_dp)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
u32 current_dc_state = intel_display_power_get_current_dc_state(display);
|
||||
struct drm_vblank_crtc *vblank = &display->drm->vblank[intel_dp->psr.pipe];
|
||||
struct intel_crtc *crtc = intel_crtc_for_pipe(display, intel_dp->psr.pipe);
|
||||
struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(&crtc->base);
|
||||
|
||||
return (current_dc_state != DC_STATE_EN_UPTO_DC5 &&
|
||||
current_dc_state != DC_STATE_EN_UPTO_DC6) ||
|
||||
@@ -2272,8 +2277,8 @@ static void intel_psr_wait_exit_locked(struct intel_dp *intel_dp)
|
||||
}
|
||||
|
||||
/* Wait till PSR is idle */
|
||||
if (intel_de_wait_for_clear(display, psr_status,
|
||||
psr_status_mask, 2000))
|
||||
if (intel_de_wait_for_clear_ms(display, psr_status,
|
||||
psr_status_mask, 2000))
|
||||
drm_err(display->drm, "Timed out waiting PSR idle state\n");
|
||||
}
|
||||
|
||||
@@ -3161,7 +3166,7 @@ _psr2_ready_for_pipe_update_locked(const struct intel_crtc_state *new_crtc_state
|
||||
return true;
|
||||
}
|
||||
|
||||
return intel_de_wait_for_clear(display,
|
||||
return intel_de_wait_for_clear_ms(display,
|
||||
EDP_PSR2_STATUS(display, cpu_transcoder),
|
||||
EDP_PSR2_STATUS_STATE_DEEP_SLEEP,
|
||||
PSR_IDLE_TIMEOUT_MS);
|
||||
@@ -3181,7 +3186,7 @@ _psr1_ready_for_pipe_update_locked(const struct intel_crtc_state *new_crtc_state
|
||||
return true;
|
||||
}
|
||||
|
||||
return intel_de_wait_for_clear(display,
|
||||
return intel_de_wait_for_clear_ms(display,
|
||||
psr_status_reg(display, cpu_transcoder),
|
||||
EDP_PSR_STATUS_STATE_MASK,
|
||||
PSR_IDLE_TIMEOUT_MS);
|
||||
@@ -3259,7 +3264,7 @@ static bool __psr_wait_for_idle_locked(struct intel_dp *intel_dp)
|
||||
|
||||
mutex_unlock(&intel_dp->psr.lock);
|
||||
|
||||
err = intel_de_wait_for_clear(display, reg, mask, 50);
|
||||
err = intel_de_wait_for_clear_ms(display, reg, mask, 50);
|
||||
if (err)
|
||||
drm_err(display->drm,
|
||||
"Timed out waiting for PSR Idle for re-enable\n");
|
||||
|
||||
@@ -21,7 +21,8 @@ static int intel_sbi_rw(struct intel_display *display, u16 reg,
|
||||
|
||||
lockdep_assert_held(&display->sbi.lock);
|
||||
|
||||
if (intel_de_wait_fw(display, SBI_CTL_STAT, SBI_STATUS_MASK, SBI_STATUS_READY, 100, NULL)) {
|
||||
if (intel_de_wait_fw_ms(display, SBI_CTL_STAT,
|
||||
SBI_STATUS_MASK, SBI_STATUS_READY, 100, NULL)) {
|
||||
drm_err(display->drm, "timeout waiting for SBI to become ready\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
@@ -37,7 +38,8 @@ static int intel_sbi_rw(struct intel_display *display, u16 reg,
|
||||
cmd |= SBI_CTL_OP_WR;
|
||||
intel_de_write_fw(display, SBI_CTL_STAT, cmd | SBI_STATUS_BUSY);
|
||||
|
||||
if (intel_de_wait_fw(display, SBI_CTL_STAT, SBI_STATUS_MASK, SBI_STATUS_READY, 100, &cmd)) {
|
||||
if (intel_de_wait_fw_ms(display, SBI_CTL_STAT,
|
||||
SBI_STATUS_MASK, SBI_STATUS_READY, 100, &cmd)) {
|
||||
drm_err(display->drm, "timeout waiting for SBI to complete read\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
@@ -42,8 +42,8 @@ void intel_snps_phy_wait_for_calibration(struct intel_display *display)
|
||||
* which phy was affected and skip setup of the corresponding
|
||||
* output later.
|
||||
*/
|
||||
if (intel_de_wait_for_clear(display, DG2_PHY_MISC(phy),
|
||||
DG2_PHY_DP_TX_ACK_MASK, 25))
|
||||
if (intel_de_wait_for_clear_ms(display, DG2_PHY_MISC(phy),
|
||||
DG2_PHY_DP_TX_ACK_MASK, 25))
|
||||
display->snps.phy_failed_calibration |= BIT(phy);
|
||||
}
|
||||
}
|
||||
@@ -1863,7 +1863,7 @@ void intel_mpllb_enable(struct intel_encoder *encoder,
|
||||
* is locked at new settings. This register bit is sampling PHY
|
||||
* dp_mpllb_state interface signal.
|
||||
*/
|
||||
if (intel_de_wait_for_set(display, enable_reg, PLL_LOCK, 5))
|
||||
if (intel_de_wait_for_set_ms(display, enable_reg, PLL_LOCK, 5))
|
||||
drm_dbg_kms(display->drm, "Port %c PLL not locked\n", phy_name(phy));
|
||||
|
||||
/*
|
||||
@@ -1903,7 +1903,7 @@ void intel_mpllb_disable(struct intel_encoder *encoder)
|
||||
* 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(display, enable_reg, PLL_LOCK, 5))
|
||||
if (intel_de_wait_for_clear_ms(display, enable_reg, PLL_LOCK, 5))
|
||||
drm_err(display->drm, "Port %c PLL not locked\n", phy_name(phy));
|
||||
|
||||
/*
|
||||
|
||||
@@ -958,10 +958,9 @@ static int g4x_sprite_min_cdclk(const struct intel_crtc_state *crtc_state,
|
||||
|
||||
static unsigned int
|
||||
g4x_sprite_max_stride(struct intel_plane *plane,
|
||||
u32 pixel_format, u64 modifier,
|
||||
unsigned int rotation)
|
||||
const struct drm_format_info *info,
|
||||
u64 modifier, unsigned int rotation)
|
||||
{
|
||||
const struct drm_format_info *info = drm_format_info(pixel_format);
|
||||
int cpp = info->cpp[0];
|
||||
|
||||
/* Limit to 4k pixels to guarantee TILEOFF.x doesn't get too big. */
|
||||
@@ -973,10 +972,9 @@ g4x_sprite_max_stride(struct intel_plane *plane,
|
||||
|
||||
static unsigned int
|
||||
hsw_sprite_max_stride(struct intel_plane *plane,
|
||||
u32 pixel_format, u64 modifier,
|
||||
unsigned int rotation)
|
||||
const struct drm_format_info *info,
|
||||
u64 modifier, unsigned int rotation)
|
||||
{
|
||||
const struct drm_format_info *info = drm_format_info(pixel_format);
|
||||
int cpp = info->cpp[0];
|
||||
|
||||
/* Limit to 8k pixels to guarantee OFFSET.x doesn't get too big. */
|
||||
|
||||
@@ -1076,8 +1076,8 @@ xelpdp_tc_phy_wait_for_tcss_power(struct intel_tc_port *tc, bool enabled)
|
||||
static void xelpdp_tc_power_request_wa(struct intel_display *display, bool enable)
|
||||
{
|
||||
/* check if mailbox is running busy */
|
||||
if (intel_de_wait_for_clear(display, TCSS_DISP_MAILBOX_IN_CMD,
|
||||
TCSS_DISP_MAILBOX_IN_CMD_RUN_BUSY, 10)) {
|
||||
if (intel_de_wait_for_clear_ms(display, TCSS_DISP_MAILBOX_IN_CMD,
|
||||
TCSS_DISP_MAILBOX_IN_CMD_RUN_BUSY, 10)) {
|
||||
drm_dbg_kms(display->drm,
|
||||
"Timeout waiting for TCSS mailbox run/busy bit to clear\n");
|
||||
return;
|
||||
@@ -1089,8 +1089,8 @@ static void xelpdp_tc_power_request_wa(struct intel_display *display, bool enabl
|
||||
TCSS_DISP_MAILBOX_IN_CMD_DATA(0x1));
|
||||
|
||||
/* wait to clear mailbox running busy bit before continuing */
|
||||
if (intel_de_wait_for_clear(display, TCSS_DISP_MAILBOX_IN_CMD,
|
||||
TCSS_DISP_MAILBOX_IN_CMD_RUN_BUSY, 10)) {
|
||||
if (intel_de_wait_for_clear_ms(display, TCSS_DISP_MAILBOX_IN_CMD,
|
||||
TCSS_DISP_MAILBOX_IN_CMD_RUN_BUSY, 10)) {
|
||||
drm_dbg_kms(display->drm,
|
||||
"Timeout after writing data to mailbox. Mailbox run/busy bit did not clear\n");
|
||||
return;
|
||||
|
||||
@@ -716,9 +716,9 @@ static void intel_vrr_tg_disable(const struct intel_crtc_state *old_crtc_state)
|
||||
intel_de_write(display, TRANS_VRR_CTL(display, cpu_transcoder),
|
||||
trans_vrr_ctl(old_crtc_state));
|
||||
|
||||
if (intel_de_wait_for_clear(display,
|
||||
TRANS_VRR_STATUS(display, cpu_transcoder),
|
||||
VRR_STATUS_VRR_EN_LIVE, 1000))
|
||||
if (intel_de_wait_for_clear_ms(display,
|
||||
TRANS_VRR_STATUS(display, cpu_transcoder),
|
||||
VRR_STATUS_VRR_EN_LIVE, 1000))
|
||||
drm_err(display->drm, "Timed out waiting for VRR live status to clear\n");
|
||||
|
||||
intel_de_write(display, TRANS_PUSH(display, cpu_transcoder), 0);
|
||||
|
||||
@@ -465,12 +465,11 @@ static int icl_plane_max_height(const struct drm_framebuffer *fb,
|
||||
|
||||
static unsigned int
|
||||
plane_max_stride(struct intel_plane *plane,
|
||||
u32 pixel_format, u64 modifier,
|
||||
unsigned int rotation,
|
||||
const struct drm_format_info *info,
|
||||
u64 modifier, unsigned int rotation,
|
||||
unsigned int max_pixels,
|
||||
unsigned int max_bytes)
|
||||
{
|
||||
const struct drm_format_info *info = drm_format_info(pixel_format);
|
||||
int cpp = info->cpp[0];
|
||||
|
||||
if (drm_rotation_90_or_270(rotation))
|
||||
@@ -481,26 +480,26 @@ plane_max_stride(struct intel_plane *plane,
|
||||
|
||||
static unsigned int
|
||||
adl_plane_max_stride(struct intel_plane *plane,
|
||||
u32 pixel_format, u64 modifier,
|
||||
unsigned int rotation)
|
||||
const struct drm_format_info *info,
|
||||
u64 modifier, unsigned int rotation)
|
||||
{
|
||||
unsigned int max_pixels = 65536; /* PLANE_OFFSET limit */
|
||||
unsigned int max_bytes = 128 * 1024;
|
||||
|
||||
return plane_max_stride(plane, pixel_format,
|
||||
return plane_max_stride(plane, info,
|
||||
modifier, rotation,
|
||||
max_pixels, max_bytes);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
skl_plane_max_stride(struct intel_plane *plane,
|
||||
u32 pixel_format, u64 modifier,
|
||||
unsigned int rotation)
|
||||
const struct drm_format_info *info,
|
||||
u64 modifier, unsigned int rotation)
|
||||
{
|
||||
unsigned int max_pixels = 8192; /* PLANE_OFFSET limit */
|
||||
unsigned int max_bytes = 32 * 1024;
|
||||
|
||||
return plane_max_stride(plane, pixel_format,
|
||||
return plane_max_stride(plane, info,
|
||||
modifier, rotation,
|
||||
max_pixels, max_bytes);
|
||||
}
|
||||
@@ -1748,7 +1747,8 @@ static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state,
|
||||
}
|
||||
|
||||
if (rotation & DRM_MODE_REFLECT_X &&
|
||||
fb->modifier == DRM_FORMAT_MOD_LINEAR) {
|
||||
fb->modifier == DRM_FORMAT_MOD_LINEAR &&
|
||||
DISPLAY_VER(display) < 35) {
|
||||
drm_dbg_kms(display->drm,
|
||||
"[PLANE:%d:%s] horizontal flip is not supported with linear surface formats\n",
|
||||
plane->base.base.id, plane->base.name);
|
||||
@@ -3083,7 +3083,6 @@ skl_get_initial_plane_config(struct intel_crtc *crtc,
|
||||
|
||||
fourcc = skl_format_to_fourcc(pixel_format,
|
||||
val & PLANE_CTL_ORDER_RGBX, alpha);
|
||||
fb->format = drm_format_info(fourcc);
|
||||
|
||||
tiling = val & PLANE_CTL_TILED_MASK;
|
||||
switch (tiling) {
|
||||
@@ -3091,11 +3090,9 @@ skl_get_initial_plane_config(struct intel_crtc *crtc,
|
||||
fb->modifier = DRM_FORMAT_MOD_LINEAR;
|
||||
break;
|
||||
case PLANE_CTL_TILED_X:
|
||||
plane_config->tiling = I915_TILING_X;
|
||||
fb->modifier = I915_FORMAT_MOD_X_TILED;
|
||||
break;
|
||||
case PLANE_CTL_TILED_Y:
|
||||
plane_config->tiling = I915_TILING_Y;
|
||||
if (val & PLANE_CTL_RENDER_DECOMPRESSION_ENABLE)
|
||||
if (DISPLAY_VER(display) >= 14)
|
||||
fb->modifier = I915_FORMAT_MOD_4_TILED_MTL_RC_CCS;
|
||||
@@ -3136,6 +3133,8 @@ skl_get_initial_plane_config(struct intel_crtc *crtc,
|
||||
goto error;
|
||||
}
|
||||
|
||||
fb->format = drm_get_format_info(display->drm, fourcc, fb->modifier);
|
||||
|
||||
if (!display->params.enable_dpt &&
|
||||
intel_fb_modifier_uses_dpt(display, fb->modifier)) {
|
||||
drm_dbg_kms(display->drm, "DPT disabled, skipping initial FB\n");
|
||||
|
||||
@@ -324,7 +324,7 @@
|
||||
#define PLANE_WM_IGNORE_LINES REG_BIT(30)
|
||||
#define PLANE_WM_AUTO_MIN_ALLOC_EN REG_BIT(29)
|
||||
#define PLANE_WM_LINES_MASK REG_GENMASK(26, 14)
|
||||
#define PLANE_WM_BLOCKS_MASK REG_GENMASK(11, 0)
|
||||
#define PLANE_WM_BLOCKS_MASK REG_GENMASK(12, 0)
|
||||
|
||||
#define _PLANE_WM_SAGV_1_A 0x70258
|
||||
#define _PLANE_WM_SAGV_1_B 0x71258
|
||||
@@ -375,10 +375,10 @@
|
||||
_PLANE_BUF_CFG_1_A, _PLANE_BUF_CFG_1_B, \
|
||||
_PLANE_BUF_CFG_2_A, _PLANE_BUF_CFG_2_B)
|
||||
|
||||
/* skl+: 10 bits, icl+ 11 bits, adlp+ 12 bits */
|
||||
#define PLANE_BUF_END_MASK REG_GENMASK(27, 16)
|
||||
/* skl+: 10 bits, icl+ 11 bits, adlp+ 12 bits, xe3p_lpd 13 bits */
|
||||
#define PLANE_BUF_END_MASK REG_GENMASK(28, 16)
|
||||
#define PLANE_BUF_END(end) REG_FIELD_PREP(PLANE_BUF_END_MASK, (end))
|
||||
#define PLANE_BUF_START_MASK REG_GENMASK(11, 0)
|
||||
#define PLANE_BUF_START_MASK REG_GENMASK(12, 0)
|
||||
#define PLANE_BUF_START(start) REG_FIELD_PREP(PLANE_BUF_START_MASK, (start))
|
||||
|
||||
#define _PLANE_MIN_BUF_CFG_1_A 0x70274
|
||||
@@ -389,9 +389,9 @@
|
||||
_PLANE_MIN_BUF_CFG_1_A, _PLANE_MIN_BUF_CFG_1_B, \
|
||||
_PLANE_MIN_BUF_CFG_2_A, _PLANE_MIN_BUF_CFG_2_B)
|
||||
#define PLANE_AUTO_MIN_DBUF_EN REG_BIT(31)
|
||||
#define PLANE_MIN_DBUF_BLOCKS_MASK REG_GENMASK(27, 16)
|
||||
#define PLANE_MIN_DBUF_BLOCKS_MASK REG_GENMASK(28, 16)
|
||||
#define PLANE_MIN_DBUF_BLOCKS(val) REG_FIELD_PREP(PLANE_MIN_DBUF_BLOCKS_MASK, (val))
|
||||
#define PLANE_INTERIM_DBUF_BLOCKS_MASK REG_GENMASK(11, 0)
|
||||
#define PLANE_INTERIM_DBUF_BLOCKS_MASK REG_GENMASK(12, 0)
|
||||
#define PLANE_INTERIM_DBUF_BLOCKS(val) REG_FIELD_PREP(PLANE_INTERIM_DBUF_BLOCKS_MASK, (val))
|
||||
|
||||
/* tgl+ */
|
||||
|
||||
@@ -635,15 +635,22 @@ skl_cursor_allocation(const struct intel_crtc_state *crtc_state,
|
||||
{
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
struct intel_plane *plane = to_intel_plane(crtc_state->uapi.crtc->cursor);
|
||||
const struct drm_mode_config *mode_config = &display->drm->mode_config;
|
||||
const struct drm_format_info *info;
|
||||
struct skl_wm_level wm = {};
|
||||
int ret, min_ddb_alloc = 0;
|
||||
struct skl_wm_params wp;
|
||||
u64 modifier;
|
||||
u32 format;
|
||||
int level;
|
||||
|
||||
ret = skl_compute_wm_params(crtc_state, 256,
|
||||
drm_format_info(DRM_FORMAT_ARGB8888),
|
||||
DRM_FORMAT_MOD_LINEAR,
|
||||
DRM_MODE_ROTATE_0,
|
||||
format = DRM_FORMAT_ARGB8888;
|
||||
modifier = DRM_FORMAT_MOD_LINEAR;
|
||||
|
||||
info = drm_get_format_info(display->drm, format, modifier);
|
||||
|
||||
ret = skl_compute_wm_params(crtc_state, mode_config->cursor_width,
|
||||
info, modifier, DRM_MODE_ROTATE_0,
|
||||
crtc_state->pixel_rate, &wp, 0, 0);
|
||||
drm_WARN_ON(display->drm, ret);
|
||||
|
||||
@@ -1812,6 +1819,8 @@ static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state,
|
||||
|
||||
if (wp->y_tiled) {
|
||||
selected_result = max_fixed16(method2, wp->y_tile_minimum);
|
||||
} else if (DISPLAY_VER(display) >= 35) {
|
||||
selected_result = method2;
|
||||
} else {
|
||||
if ((wp->cpp * crtc_state->hw.pipe_mode.crtc_htotal /
|
||||
wp->dbuf_block_size < 1) &&
|
||||
@@ -3182,6 +3191,13 @@ static void sanitize_wm_latency(struct intel_display *display)
|
||||
u16 *wm = display->wm.skl_latency;
|
||||
int level, num_levels = display->wm.num_levels;
|
||||
|
||||
/*
|
||||
* Xe3p and beyond should ignore level 0's reported latency and
|
||||
* always apply WaWmMemoryReadLatency logic.
|
||||
*/
|
||||
if (DISPLAY_VER(display) >= 35)
|
||||
wm[0] = 0;
|
||||
|
||||
/*
|
||||
* If a level n (n > 1) has a 0us latency, all levels m (m >= n)
|
||||
* need to be disabled. We make sure to sanitize the values out
|
||||
@@ -3477,7 +3493,10 @@ void intel_dbuf_mdclk_cdclk_ratio_update(struct intel_display *display,
|
||||
if (!HAS_MBUS_JOINING(display))
|
||||
return;
|
||||
|
||||
if (DISPLAY_VER(display) >= 20)
|
||||
if (DISPLAY_VER(display) >= 35)
|
||||
intel_de_rmw(display, MBUS_CTL, XE3P_MBUS_TRANSLATION_THROTTLE_MIN_MASK,
|
||||
XE3P_MBUS_TRANSLATION_THROTTLE_MIN(ratio - 1));
|
||||
else if (DISPLAY_VER(display) >= 20)
|
||||
intel_de_rmw(display, MBUS_CTL, MBUS_TRANSLATION_THROTTLE_MIN_MASK,
|
||||
MBUS_TRANSLATION_THROTTLE_MIN(ratio - 1));
|
||||
|
||||
@@ -3488,9 +3507,14 @@ void intel_dbuf_mdclk_cdclk_ratio_update(struct intel_display *display,
|
||||
ratio, str_yes_no(joined_mbus));
|
||||
|
||||
for_each_dbuf_slice(display, slice)
|
||||
intel_de_rmw(display, DBUF_CTL_S(slice),
|
||||
DBUF_MIN_TRACKER_STATE_SERVICE_MASK,
|
||||
DBUF_MIN_TRACKER_STATE_SERVICE(ratio - 1));
|
||||
if (DISPLAY_VER(display) >= 35)
|
||||
intel_de_rmw(display, DBUF_CTL_S(slice),
|
||||
XE3P_DBUF_MIN_TRACKER_STATE_SERVICE_MASK,
|
||||
XE3P_DBUF_MIN_TRACKER_STATE_SERVICE(ratio - 1));
|
||||
else
|
||||
intel_de_rmw(display, DBUF_CTL_S(slice),
|
||||
DBUF_MIN_TRACKER_STATE_SERVICE_MASK,
|
||||
DBUF_MIN_TRACKER_STATE_SERVICE(ratio - 1));
|
||||
}
|
||||
|
||||
static void intel_dbuf_mdclk_min_tracker_update(struct intel_atomic_state *state)
|
||||
|
||||
@@ -32,16 +32,18 @@
|
||||
#define MBUS_BBOX_CTL_S1 _MMIO(0x45040)
|
||||
#define MBUS_BBOX_CTL_S2 _MMIO(0x45044)
|
||||
|
||||
#define MBUS_CTL _MMIO(0x4438C)
|
||||
#define MBUS_JOIN REG_BIT(31)
|
||||
#define MBUS_HASHING_MODE_MASK REG_BIT(30)
|
||||
#define MBUS_HASHING_MODE_2x2 REG_FIELD_PREP(MBUS_HASHING_MODE_MASK, 0)
|
||||
#define MBUS_HASHING_MODE_1x4 REG_FIELD_PREP(MBUS_HASHING_MODE_MASK, 1)
|
||||
#define MBUS_JOIN_PIPE_SELECT_MASK REG_GENMASK(28, 26)
|
||||
#define MBUS_JOIN_PIPE_SELECT(pipe) REG_FIELD_PREP(MBUS_JOIN_PIPE_SELECT_MASK, pipe)
|
||||
#define MBUS_JOIN_PIPE_SELECT_NONE MBUS_JOIN_PIPE_SELECT(7)
|
||||
#define MBUS_TRANSLATION_THROTTLE_MIN_MASK REG_GENMASK(15, 13)
|
||||
#define MBUS_TRANSLATION_THROTTLE_MIN(val) REG_FIELD_PREP(MBUS_TRANSLATION_THROTTLE_MIN_MASK, val)
|
||||
#define MBUS_CTL _MMIO(0x4438C)
|
||||
#define MBUS_JOIN REG_BIT(31)
|
||||
#define MBUS_HASHING_MODE_MASK REG_BIT(30)
|
||||
#define MBUS_HASHING_MODE_2x2 REG_FIELD_PREP(MBUS_HASHING_MODE_MASK, 0)
|
||||
#define MBUS_HASHING_MODE_1x4 REG_FIELD_PREP(MBUS_HASHING_MODE_MASK, 1)
|
||||
#define MBUS_JOIN_PIPE_SELECT_MASK REG_GENMASK(28, 26)
|
||||
#define MBUS_JOIN_PIPE_SELECT(pipe) REG_FIELD_PREP(MBUS_JOIN_PIPE_SELECT_MASK, pipe)
|
||||
#define MBUS_JOIN_PIPE_SELECT_NONE MBUS_JOIN_PIPE_SELECT(7)
|
||||
#define XE3P_MBUS_TRANSLATION_THROTTLE_MIN_MASK REG_GENMASK(16, 13)
|
||||
#define XE3P_MBUS_TRANSLATION_THROTTLE_MIN(val) REG_FIELD_PREP(XE3P_MBUS_TRANSLATION_THROTTLE_MIN_MASK, val)
|
||||
#define MBUS_TRANSLATION_THROTTLE_MIN_MASK REG_GENMASK(15, 13)
|
||||
#define MBUS_TRANSLATION_THROTTLE_MIN(val) REG_FIELD_PREP(MBUS_TRANSLATION_THROTTLE_MIN_MASK, val)
|
||||
|
||||
/*
|
||||
* The below are numbered starting from "S1" on gen11/gen12, but starting
|
||||
@@ -51,20 +53,22 @@
|
||||
* way things will be named by the hardware team going forward, plus it's more
|
||||
* consistent with how most of the rest of our registers are named.
|
||||
*/
|
||||
#define _DBUF_CTL_S0 0x45008
|
||||
#define _DBUF_CTL_S1 0x44FE8
|
||||
#define _DBUF_CTL_S2 0x44300
|
||||
#define _DBUF_CTL_S3 0x44304
|
||||
#define DBUF_CTL_S(slice) _MMIO(_PICK(slice, \
|
||||
_DBUF_CTL_S0, \
|
||||
_DBUF_CTL_S1, \
|
||||
_DBUF_CTL_S2, \
|
||||
_DBUF_CTL_S3))
|
||||
#define DBUF_POWER_REQUEST REG_BIT(31)
|
||||
#define DBUF_POWER_STATE REG_BIT(30)
|
||||
#define DBUF_TRACKER_STATE_SERVICE_MASK REG_GENMASK(23, 19)
|
||||
#define DBUF_TRACKER_STATE_SERVICE(x) REG_FIELD_PREP(DBUF_TRACKER_STATE_SERVICE_MASK, x)
|
||||
#define DBUF_MIN_TRACKER_STATE_SERVICE_MASK REG_GENMASK(18, 16) /* ADL-P+ */
|
||||
#define _DBUF_CTL_S0 0x45008
|
||||
#define _DBUF_CTL_S1 0x44FE8
|
||||
#define _DBUF_CTL_S2 0x44300
|
||||
#define _DBUF_CTL_S3 0x44304
|
||||
#define DBUF_CTL_S(slice) _MMIO(_PICK(slice, \
|
||||
_DBUF_CTL_S0, \
|
||||
_DBUF_CTL_S1, \
|
||||
_DBUF_CTL_S2, \
|
||||
_DBUF_CTL_S3))
|
||||
#define DBUF_POWER_REQUEST REG_BIT(31)
|
||||
#define DBUF_POWER_STATE REG_BIT(30)
|
||||
#define DBUF_TRACKER_STATE_SERVICE_MASK REG_GENMASK(23, 19)
|
||||
#define DBUF_TRACKER_STATE_SERVICE(x) REG_FIELD_PREP(DBUF_TRACKER_STATE_SERVICE_MASK, x)
|
||||
#define XE3P_DBUF_MIN_TRACKER_STATE_SERVICE_MASK REG_GENMASK(20, 16)
|
||||
#define XE3P_DBUF_MIN_TRACKER_STATE_SERVICE(x) REG_FIELD_PREP(XE3P_DBUF_MIN_TRACKER_STATE_SERVICE_MASK, x)
|
||||
#define DBUF_MIN_TRACKER_STATE_SERVICE_MASK REG_GENMASK(18, 16) /* ADL-P+ */
|
||||
#define DBUF_MIN_TRACKER_STATE_SERVICE(x) REG_FIELD_PREP(DBUF_MIN_TRACKER_STATE_SERVICE_MASK, x) /* ADL-P+ */
|
||||
|
||||
#define MTL_LATENCY_LP0_LP1 _MMIO(0x45780)
|
||||
|
||||
@@ -94,8 +94,8 @@ void vlv_dsi_wait_for_fifo_empty(struct intel_dsi *intel_dsi, enum port port)
|
||||
mask = LP_CTRL_FIFO_EMPTY | HS_CTRL_FIFO_EMPTY |
|
||||
LP_DATA_FIFO_EMPTY | HS_DATA_FIFO_EMPTY;
|
||||
|
||||
if (intel_de_wait_for_set(display, MIPI_GEN_FIFO_STAT(display, port),
|
||||
mask, 100))
|
||||
if (intel_de_wait_for_set_ms(display, MIPI_GEN_FIFO_STAT(display, port),
|
||||
mask, 100))
|
||||
drm_err(display->drm, "DPI FIFOs are not empty\n");
|
||||
}
|
||||
|
||||
@@ -162,8 +162,8 @@ static ssize_t intel_dsi_host_transfer(struct mipi_dsi_host *host,
|
||||
|
||||
/* note: this is never true for reads */
|
||||
if (packet.payload_length) {
|
||||
if (intel_de_wait_for_clear(display, MIPI_GEN_FIFO_STAT(display, port),
|
||||
data_mask, 50))
|
||||
if (intel_de_wait_for_clear_ms(display, MIPI_GEN_FIFO_STAT(display, port),
|
||||
data_mask, 50))
|
||||
drm_err(display->drm,
|
||||
"Timeout waiting for HS/LP DATA FIFO !full\n");
|
||||
|
||||
@@ -176,8 +176,8 @@ static ssize_t intel_dsi_host_transfer(struct mipi_dsi_host *host,
|
||||
GEN_READ_DATA_AVAIL);
|
||||
}
|
||||
|
||||
if (intel_de_wait_for_clear(display, MIPI_GEN_FIFO_STAT(display, port),
|
||||
ctrl_mask, 50)) {
|
||||
if (intel_de_wait_for_clear_ms(display, MIPI_GEN_FIFO_STAT(display, port),
|
||||
ctrl_mask, 50)) {
|
||||
drm_err(display->drm,
|
||||
"Timeout waiting for HS/LP CTRL FIFO !full\n");
|
||||
}
|
||||
@@ -188,8 +188,8 @@ static ssize_t intel_dsi_host_transfer(struct mipi_dsi_host *host,
|
||||
/* ->rx_len is set only for reads */
|
||||
if (msg->rx_len) {
|
||||
data_mask = GEN_READ_DATA_AVAIL;
|
||||
if (intel_de_wait_for_set(display, MIPI_INTR_STAT(display, port),
|
||||
data_mask, 50))
|
||||
if (intel_de_wait_for_set_ms(display, MIPI_INTR_STAT(display, port),
|
||||
data_mask, 50))
|
||||
drm_err(display->drm,
|
||||
"Timeout waiting for read data.\n");
|
||||
|
||||
@@ -246,7 +246,7 @@ static int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd, bool hs,
|
||||
intel_de_write(display, MIPI_DPI_CONTROL(display, port), cmd);
|
||||
|
||||
mask = SPL_PKT_SENT_INTERRUPT;
|
||||
if (intel_de_wait_for_set(display, MIPI_INTR_STAT(display, port), mask, 100))
|
||||
if (intel_de_wait_for_set_ms(display, MIPI_INTR_STAT(display, port), mask, 100))
|
||||
drm_err(display->drm,
|
||||
"Video mode command 0x%08x send failed.\n", cmd);
|
||||
|
||||
@@ -352,8 +352,8 @@ static bool glk_dsi_enable_io(struct intel_encoder *encoder)
|
||||
|
||||
/* Wait for Pwr ACK */
|
||||
for_each_dsi_port(port, intel_dsi->ports) {
|
||||
if (intel_de_wait_for_set(display, MIPI_CTRL(display, port),
|
||||
GLK_MIPIIO_PORT_POWERED, 20))
|
||||
if (intel_de_wait_for_set_ms(display, MIPI_CTRL(display, port),
|
||||
GLK_MIPIIO_PORT_POWERED, 20))
|
||||
drm_err(display->drm, "MIPIO port is powergated\n");
|
||||
}
|
||||
|
||||
@@ -374,8 +374,8 @@ static void glk_dsi_device_ready(struct intel_encoder *encoder)
|
||||
|
||||
/* Wait for MIPI PHY status bit to set */
|
||||
for_each_dsi_port(port, intel_dsi->ports) {
|
||||
if (intel_de_wait_for_set(display, MIPI_CTRL(display, port),
|
||||
GLK_PHY_STATUS_PORT_READY, 20))
|
||||
if (intel_de_wait_for_set_ms(display, MIPI_CTRL(display, port),
|
||||
GLK_PHY_STATUS_PORT_READY, 20))
|
||||
drm_err(display->drm, "PHY is not ON\n");
|
||||
}
|
||||
|
||||
@@ -394,8 +394,8 @@ static void glk_dsi_device_ready(struct intel_encoder *encoder)
|
||||
ULPS_STATE_MASK, ULPS_STATE_ENTER | DEVICE_READY);
|
||||
|
||||
/* Wait for ULPS active */
|
||||
if (intel_de_wait_for_clear(display, MIPI_CTRL(display, port),
|
||||
GLK_ULPS_NOT_ACTIVE, 20))
|
||||
if (intel_de_wait_for_clear_ms(display, MIPI_CTRL(display, port),
|
||||
GLK_ULPS_NOT_ACTIVE, 20))
|
||||
drm_err(display->drm, "ULPS not active\n");
|
||||
|
||||
/* Exit ULPS */
|
||||
@@ -413,16 +413,16 @@ static void glk_dsi_device_ready(struct intel_encoder *encoder)
|
||||
|
||||
/* Wait for Stop state */
|
||||
for_each_dsi_port(port, intel_dsi->ports) {
|
||||
if (intel_de_wait_for_set(display, MIPI_CTRL(display, port),
|
||||
GLK_DATA_LANE_STOP_STATE, 20))
|
||||
if (intel_de_wait_for_set_ms(display, MIPI_CTRL(display, port),
|
||||
GLK_DATA_LANE_STOP_STATE, 20))
|
||||
drm_err(display->drm,
|
||||
"Date lane not in STOP state\n");
|
||||
}
|
||||
|
||||
/* Wait for AFE LATCH */
|
||||
for_each_dsi_port(port, intel_dsi->ports) {
|
||||
if (intel_de_wait_for_set(display, BXT_MIPI_PORT_CTRL(port),
|
||||
AFE_LATCHOUT, 20))
|
||||
if (intel_de_wait_for_set_ms(display, BXT_MIPI_PORT_CTRL(port),
|
||||
AFE_LATCHOUT, 20))
|
||||
drm_err(display->drm,
|
||||
"D-PHY not entering LP-11 state\n");
|
||||
}
|
||||
@@ -519,15 +519,15 @@ static void glk_dsi_enter_low_power_mode(struct intel_encoder *encoder)
|
||||
|
||||
/* Wait for MIPI PHY status bit to unset */
|
||||
for_each_dsi_port(port, intel_dsi->ports) {
|
||||
if (intel_de_wait_for_clear(display, MIPI_CTRL(display, port),
|
||||
GLK_PHY_STATUS_PORT_READY, 20))
|
||||
if (intel_de_wait_for_clear_ms(display, MIPI_CTRL(display, port),
|
||||
GLK_PHY_STATUS_PORT_READY, 20))
|
||||
drm_err(display->drm, "PHY is not turning OFF\n");
|
||||
}
|
||||
|
||||
/* Wait for Pwr ACK bit to unset */
|
||||
for_each_dsi_port(port, intel_dsi->ports) {
|
||||
if (intel_de_wait_for_clear(display, MIPI_CTRL(display, port),
|
||||
GLK_MIPIIO_PORT_POWERED, 20))
|
||||
if (intel_de_wait_for_clear_ms(display, MIPI_CTRL(display, port),
|
||||
GLK_MIPIIO_PORT_POWERED, 20))
|
||||
drm_err(display->drm,
|
||||
"MIPI IO Port is not powergated\n");
|
||||
}
|
||||
@@ -544,8 +544,8 @@ static void glk_dsi_disable_mipi_io(struct intel_encoder *encoder)
|
||||
|
||||
/* Wait for MIPI PHY status bit to unset */
|
||||
for_each_dsi_port(port, intel_dsi->ports) {
|
||||
if (intel_de_wait_for_clear(display, MIPI_CTRL(display, port),
|
||||
GLK_PHY_STATUS_PORT_READY, 20))
|
||||
if (intel_de_wait_for_clear_ms(display, MIPI_CTRL(display, port),
|
||||
GLK_PHY_STATUS_PORT_READY, 20))
|
||||
drm_err(display->drm, "PHY is not turning OFF\n");
|
||||
}
|
||||
|
||||
@@ -595,8 +595,8 @@ static void vlv_dsi_clear_device_ready(struct intel_encoder *encoder)
|
||||
* Port A only. MIPI Port C has no similar bit for checking.
|
||||
*/
|
||||
if ((display->platform.broxton || port == PORT_A) &&
|
||||
intel_de_wait_for_clear(display, port_ctrl,
|
||||
AFE_LATCHOUT, 30))
|
||||
intel_de_wait_for_clear_ms(display, port_ctrl,
|
||||
AFE_LATCHOUT, 30))
|
||||
drm_err(display->drm, "DSI LP not going Low\n");
|
||||
|
||||
/* Disable MIPI PHY transparent latch */
|
||||
|
||||
@@ -319,8 +319,8 @@ void bxt_dsi_pll_disable(struct intel_encoder *encoder)
|
||||
* PLL lock should deassert within 200us.
|
||||
* Wait up to 1ms before timing out.
|
||||
*/
|
||||
if (intel_de_wait_for_clear(display, BXT_DSI_PLL_ENABLE,
|
||||
BXT_DSI_PLL_LOCKED, 1))
|
||||
if (intel_de_wait_for_clear_ms(display, BXT_DSI_PLL_ENABLE,
|
||||
BXT_DSI_PLL_LOCKED, 1))
|
||||
drm_err(display->drm,
|
||||
"Timeout waiting for PLL lock deassertion\n");
|
||||
}
|
||||
@@ -568,8 +568,8 @@ void bxt_dsi_pll_enable(struct intel_encoder *encoder,
|
||||
intel_de_rmw(display, BXT_DSI_PLL_ENABLE, 0, BXT_DSI_PLL_DO_ENABLE);
|
||||
|
||||
/* Timeout and fail if PLL not locked */
|
||||
if (intel_de_wait_for_set(display, BXT_DSI_PLL_ENABLE,
|
||||
BXT_DSI_PLL_LOCKED, 1)) {
|
||||
if (intel_de_wait_for_set_ms(display, BXT_DSI_PLL_ENABLE,
|
||||
BXT_DSI_PLL_LOCKED, 1)) {
|
||||
drm_err(display->drm,
|
||||
"Timed out waiting for DSI PLL to lock\n");
|
||||
return;
|
||||
|
||||
@@ -194,8 +194,8 @@ i915_gem_dumb_create(struct drm_file *file,
|
||||
args->pitch = ALIGN(args->width * cpp, 64);
|
||||
|
||||
/* align stride to page size so that we can remap */
|
||||
if (args->pitch > intel_plane_fb_max_stride(dev, format,
|
||||
DRM_FORMAT_MOD_LINEAR))
|
||||
if (args->pitch > intel_dumb_fb_max_stride(dev, format,
|
||||
DRM_FORMAT_MOD_LINEAR))
|
||||
args->pitch = ALIGN(args->pitch, 4096);
|
||||
|
||||
if (args->pitch < args->width)
|
||||
|
||||
@@ -477,24 +477,24 @@ static void i915_gem_free_object(struct drm_gem_object *gem_obj)
|
||||
void __i915_gem_object_flush_frontbuffer(struct drm_i915_gem_object *obj,
|
||||
enum fb_op_origin origin)
|
||||
{
|
||||
struct intel_frontbuffer *front;
|
||||
struct i915_frontbuffer *front;
|
||||
|
||||
front = i915_gem_object_get_frontbuffer(obj);
|
||||
front = i915_gem_object_frontbuffer_lookup(obj);
|
||||
if (front) {
|
||||
intel_frontbuffer_flush(front, origin);
|
||||
intel_frontbuffer_put(front);
|
||||
intel_frontbuffer_flush(&front->base, origin);
|
||||
i915_gem_object_frontbuffer_put(front);
|
||||
}
|
||||
}
|
||||
|
||||
void __i915_gem_object_invalidate_frontbuffer(struct drm_i915_gem_object *obj,
|
||||
enum fb_op_origin origin)
|
||||
{
|
||||
struct intel_frontbuffer *front;
|
||||
struct i915_frontbuffer *front;
|
||||
|
||||
front = i915_gem_object_get_frontbuffer(obj);
|
||||
front = i915_gem_object_frontbuffer_lookup(obj);
|
||||
if (front) {
|
||||
intel_frontbuffer_invalidate(front, origin);
|
||||
intel_frontbuffer_put(front);
|
||||
intel_frontbuffer_invalidate(&front->base, origin);
|
||||
i915_gem_object_frontbuffer_put(front);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
103
drivers/gpu/drm/i915/gem/i915_gem_object_frontbuffer.c
Normal file
103
drivers/gpu/drm/i915/gem/i915_gem_object_frontbuffer.c
Normal file
@@ -0,0 +1,103 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
/* Copyright © 2025 Intel Corporation */
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_gem_object_frontbuffer.h"
|
||||
|
||||
static int frontbuffer_active(struct i915_active *ref)
|
||||
{
|
||||
struct i915_frontbuffer *front =
|
||||
container_of(ref, typeof(*front), write);
|
||||
|
||||
kref_get(&front->ref);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void frontbuffer_retire(struct i915_active *ref)
|
||||
{
|
||||
struct i915_frontbuffer *front =
|
||||
container_of(ref, typeof(*front), write);
|
||||
|
||||
intel_frontbuffer_flush(&front->base, ORIGIN_CS);
|
||||
i915_gem_object_frontbuffer_put(front);
|
||||
}
|
||||
|
||||
struct i915_frontbuffer *
|
||||
i915_gem_object_frontbuffer_get(struct drm_i915_gem_object *obj)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(obj->base.dev);
|
||||
struct i915_frontbuffer *front, *cur;
|
||||
|
||||
front = i915_gem_object_frontbuffer_lookup(obj);
|
||||
if (front)
|
||||
return front;
|
||||
|
||||
front = kmalloc(sizeof(*front), GFP_KERNEL);
|
||||
if (!front)
|
||||
return NULL;
|
||||
|
||||
intel_frontbuffer_init(&front->base, &i915->drm);
|
||||
|
||||
kref_init(&front->ref);
|
||||
i915_gem_object_get(obj);
|
||||
front->obj = obj;
|
||||
|
||||
i915_active_init(&front->write,
|
||||
frontbuffer_active,
|
||||
frontbuffer_retire,
|
||||
I915_ACTIVE_RETIRE_SLEEPS);
|
||||
|
||||
spin_lock(&i915->frontbuffer_lock);
|
||||
if (rcu_access_pointer(obj->frontbuffer)) {
|
||||
cur = rcu_dereference_protected(obj->frontbuffer, true);
|
||||
kref_get(&cur->ref);
|
||||
} else {
|
||||
cur = front;
|
||||
rcu_assign_pointer(obj->frontbuffer, front);
|
||||
}
|
||||
spin_unlock(&i915->frontbuffer_lock);
|
||||
|
||||
if (cur != front) {
|
||||
i915_gem_object_put(obj);
|
||||
intel_frontbuffer_fini(&front->base);
|
||||
kfree(front);
|
||||
}
|
||||
|
||||
return cur;
|
||||
}
|
||||
|
||||
void i915_gem_object_frontbuffer_ref(struct i915_frontbuffer *front)
|
||||
{
|
||||
kref_get(&front->ref);
|
||||
}
|
||||
|
||||
static void frontbuffer_release(struct kref *ref)
|
||||
__releases(&i915->frontbuffer_lock)
|
||||
{
|
||||
struct i915_frontbuffer *front =
|
||||
container_of(ref, typeof(*front), ref);
|
||||
struct drm_i915_gem_object *obj = front->obj;
|
||||
struct drm_i915_private *i915 = to_i915(obj->base.dev);
|
||||
|
||||
i915_ggtt_clear_scanout(obj);
|
||||
|
||||
RCU_INIT_POINTER(obj->frontbuffer, NULL);
|
||||
|
||||
spin_unlock(&i915->frontbuffer_lock);
|
||||
|
||||
i915_active_fini(&front->write);
|
||||
|
||||
i915_gem_object_put(obj);
|
||||
|
||||
intel_frontbuffer_fini(&front->base);
|
||||
|
||||
kfree_rcu(front, rcu);
|
||||
}
|
||||
|
||||
void i915_gem_object_frontbuffer_put(struct i915_frontbuffer *front)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(front->obj->base.dev);
|
||||
|
||||
kref_put_lock(&front->ref, frontbuffer_release,
|
||||
&i915->frontbuffer_lock);
|
||||
}
|
||||
@@ -12,6 +12,14 @@
|
||||
#include "display/intel_frontbuffer.h"
|
||||
#include "i915_gem_object_types.h"
|
||||
|
||||
struct i915_frontbuffer {
|
||||
struct intel_frontbuffer base;
|
||||
struct drm_i915_gem_object *obj;
|
||||
struct i915_active write;
|
||||
struct rcu_head rcu;
|
||||
struct kref ref;
|
||||
};
|
||||
|
||||
void __i915_gem_object_flush_frontbuffer(struct drm_i915_gem_object *obj,
|
||||
enum fb_op_origin origin);
|
||||
void __i915_gem_object_invalidate_frontbuffer(struct drm_i915_gem_object *obj,
|
||||
@@ -33,19 +41,23 @@ i915_gem_object_invalidate_frontbuffer(struct drm_i915_gem_object *obj,
|
||||
__i915_gem_object_invalidate_frontbuffer(obj, origin);
|
||||
}
|
||||
|
||||
struct i915_frontbuffer *i915_gem_object_frontbuffer_get(struct drm_i915_gem_object *obj);
|
||||
void i915_gem_object_frontbuffer_ref(struct i915_frontbuffer *front);
|
||||
void i915_gem_object_frontbuffer_put(struct i915_frontbuffer *front);
|
||||
|
||||
/**
|
||||
* i915_gem_object_get_frontbuffer - Get the object's frontbuffer
|
||||
* @obj: The object whose frontbuffer to get.
|
||||
* i915_gem_object_frontbuffer_lookup - Look up the object's frontbuffer
|
||||
* @obj: The object whose frontbuffer to look up.
|
||||
*
|
||||
* Get pointer to object's frontbuffer if such exists. Please note that RCU
|
||||
* mechanism is used to handle e.g. ongoing removal of frontbuffer pointer.
|
||||
*
|
||||
* Return: pointer to object's frontbuffer is such exists or NULL
|
||||
*/
|
||||
static inline struct intel_frontbuffer *
|
||||
i915_gem_object_get_frontbuffer(const struct drm_i915_gem_object *obj)
|
||||
static inline struct i915_frontbuffer *
|
||||
i915_gem_object_frontbuffer_lookup(const struct drm_i915_gem_object *obj)
|
||||
{
|
||||
struct intel_frontbuffer *front;
|
||||
struct i915_frontbuffer *front;
|
||||
|
||||
if (likely(!rcu_access_pointer(obj->frontbuffer)))
|
||||
return NULL;
|
||||
@@ -62,41 +74,11 @@ i915_gem_object_get_frontbuffer(const struct drm_i915_gem_object *obj)
|
||||
if (likely(front == rcu_access_pointer(obj->frontbuffer)))
|
||||
break;
|
||||
|
||||
intel_frontbuffer_put(front);
|
||||
i915_gem_object_frontbuffer_put(front);
|
||||
} while (1);
|
||||
rcu_read_unlock();
|
||||
|
||||
return front;
|
||||
}
|
||||
|
||||
/**
|
||||
* i915_gem_object_set_frontbuffer - Set the object's frontbuffer
|
||||
* @obj: The object whose frontbuffer to set.
|
||||
* @front: The frontbuffer to set
|
||||
*
|
||||
* Set object's frontbuffer pointer. If frontbuffer is already set for the
|
||||
* object keep it and return it's pointer to the caller. Please note that RCU
|
||||
* mechanism is used to handle e.g. ongoing removal of frontbuffer pointer. This
|
||||
* function is protected by i915->display->fb_tracking.lock
|
||||
*
|
||||
* Return: pointer to frontbuffer which was set.
|
||||
*/
|
||||
static inline struct intel_frontbuffer *
|
||||
i915_gem_object_set_frontbuffer(struct drm_i915_gem_object *obj,
|
||||
struct intel_frontbuffer *front)
|
||||
{
|
||||
struct intel_frontbuffer *cur = front;
|
||||
|
||||
if (!front) {
|
||||
RCU_INIT_POINTER(obj->frontbuffer, NULL);
|
||||
} else if (rcu_access_pointer(obj->frontbuffer)) {
|
||||
cur = rcu_dereference_protected(obj->frontbuffer, true);
|
||||
kref_get(&cur->ref);
|
||||
} else {
|
||||
rcu_assign_pointer(obj->frontbuffer, front);
|
||||
}
|
||||
|
||||
return cur;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -574,7 +574,7 @@ struct drm_i915_gem_object {
|
||||
*/
|
||||
u16 write_domain;
|
||||
|
||||
struct intel_frontbuffer __rcu *frontbuffer;
|
||||
struct i915_frontbuffer __rcu *frontbuffer;
|
||||
|
||||
/** Current tiling stride for the object, if it's tiled. */
|
||||
unsigned int tiling_and_stride;
|
||||
|
||||
@@ -311,6 +311,8 @@ struct drm_i915_private {
|
||||
struct file *mmap_singleton;
|
||||
} gem;
|
||||
|
||||
spinlock_t frontbuffer_lock; /* protects obj->frontbuffer (write-side) */
|
||||
|
||||
struct intel_pxp *pxp;
|
||||
|
||||
struct i915_pmu pmu;
|
||||
|
||||
@@ -1299,6 +1299,8 @@ void i915_gem_init_early(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
i915_gem_init__mm(dev_priv);
|
||||
i915_gem_init__contexts(dev_priv);
|
||||
|
||||
spin_lock_init(&dev_priv->frontbuffer_lock);
|
||||
}
|
||||
|
||||
void i915_gem_cleanup_early(struct drm_i915_private *dev_priv)
|
||||
|
||||
@@ -1233,6 +1233,7 @@
|
||||
#define OROM_OFFSET_MASK REG_GENMASK(20, 16)
|
||||
|
||||
#define MTL_MEM_SS_INFO_GLOBAL _MMIO(0x45700)
|
||||
#define XE3P_ECC_IMPACTING_DE REG_BIT(12)
|
||||
#define MTL_N_OF_ENABLED_QGV_POINTS_MASK REG_GENMASK(11, 8)
|
||||
#define MTL_N_OF_POPULATED_CH_MASK REG_GENMASK(7, 4)
|
||||
#define MTL_DDR_TYPE_MASK REG_GENMASK(3, 0)
|
||||
|
||||
@@ -1992,13 +1992,13 @@ int _i915_vma_move_to_active(struct i915_vma *vma,
|
||||
}
|
||||
|
||||
if (flags & EXEC_OBJECT_WRITE) {
|
||||
struct intel_frontbuffer *front;
|
||||
struct i915_frontbuffer *front;
|
||||
|
||||
front = i915_gem_object_get_frontbuffer(obj);
|
||||
front = i915_gem_object_frontbuffer_lookup(obj);
|
||||
if (unlikely(front)) {
|
||||
if (intel_frontbuffer_invalidate(front, ORIGIN_CS))
|
||||
if (intel_frontbuffer_invalidate(&front->base, ORIGIN_CS))
|
||||
i915_active_add_request(&front->write, rq);
|
||||
intel_frontbuffer_put(front);
|
||||
i915_gem_object_frontbuffer_put(front);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -686,6 +686,7 @@ static int gen12_get_dram_info(struct drm_i915_private *i915, struct dram_info *
|
||||
|
||||
static int xelpdp_get_dram_info(struct drm_i915_private *i915, struct dram_info *dram_info)
|
||||
{
|
||||
struct intel_display *display = i915->display;
|
||||
u32 val = intel_uncore_read(&i915->uncore, MTL_MEM_SS_INFO_GLOBAL);
|
||||
|
||||
switch (REG_FIELD_GET(MTL_DDR_TYPE_MASK, val)) {
|
||||
@@ -724,6 +725,9 @@ static int xelpdp_get_dram_info(struct drm_i915_private *i915, struct dram_info
|
||||
dram_info->num_qgv_points = REG_FIELD_GET(MTL_N_OF_ENABLED_QGV_POINTS_MASK, val);
|
||||
/* PSF GV points not supported in D14+ */
|
||||
|
||||
if (DISPLAY_VER(display) >= 35)
|
||||
dram_info->ecc_impacting_de_bw = REG_FIELD_GET(XE3P_ECC_IMPACTING_DE, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ struct dram_info {
|
||||
u8 num_channels;
|
||||
u8 num_qgv_points;
|
||||
u8 num_psf_gv_points;
|
||||
bool ecc_impacting_de_bw; /* Only valid from Xe3p_LPD onward. */
|
||||
bool symmetric_memory;
|
||||
bool has_16gb_dimms;
|
||||
};
|
||||
|
||||
@@ -39,8 +39,9 @@ static u16 spi_read16(struct intel_rom *rom, loff_t offset)
|
||||
return spi_read32(rom, offset) & 0xffff;
|
||||
}
|
||||
|
||||
struct intel_rom *intel_rom_spi(struct drm_i915_private *i915)
|
||||
struct intel_rom *intel_rom_spi(struct drm_device *drm)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(drm);
|
||||
struct intel_rom *rom;
|
||||
u32 static_region;
|
||||
|
||||
@@ -85,7 +86,7 @@ static void pci_free(struct intel_rom *rom)
|
||||
pci_unmap_rom(rom->pdev, rom->oprom);
|
||||
}
|
||||
|
||||
struct intel_rom *intel_rom_pci(struct drm_i915_private *i915)
|
||||
struct intel_rom *intel_rom_pci(struct drm_device *drm)
|
||||
{
|
||||
struct intel_rom *rom;
|
||||
|
||||
@@ -93,7 +94,7 @@ struct intel_rom *intel_rom_pci(struct drm_i915_private *i915)
|
||||
if (!rom)
|
||||
return NULL;
|
||||
|
||||
rom->pdev = to_pci_dev(i915->drm.dev);
|
||||
rom->pdev = to_pci_dev(drm->dev);
|
||||
|
||||
rom->oprom = pci_map_rom(rom->pdev, &rom->size);
|
||||
if (!rom->oprom) {
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct drm_i915_private;
|
||||
struct drm_device;
|
||||
struct intel_rom;
|
||||
|
||||
struct intel_rom *intel_rom_spi(struct drm_i915_private *i915);
|
||||
struct intel_rom *intel_rom_pci(struct drm_i915_private *i915);
|
||||
struct intel_rom *intel_rom_spi(struct drm_device *drm);
|
||||
struct intel_rom *intel_rom_pci(struct drm_device *drm);
|
||||
|
||||
u32 intel_rom_read32(struct intel_rom *rom, loff_t offset);
|
||||
u16 intel_rom_read16(struct intel_rom *rom, loff_t offset);
|
||||
|
||||
@@ -26,8 +26,6 @@ struct i915_vma {
|
||||
struct xe_ggtt_node *node;
|
||||
};
|
||||
|
||||
#define i915_ggtt_clear_scanout(bo) do { } while (0)
|
||||
|
||||
#define i915_vma_fence_id(vma) -1
|
||||
|
||||
static inline u32 i915_ggtt_offset(const struct i915_vma *vma)
|
||||
|
||||
@@ -91,27 +91,6 @@ static inline u32 intel_uncore_rmw(struct intel_uncore *uncore,
|
||||
return xe_mmio_rmw32(__compat_uncore_to_mmio(uncore), reg, clear, set);
|
||||
}
|
||||
|
||||
static inline int intel_wait_for_register(struct intel_uncore *uncore,
|
||||
i915_reg_t i915_reg, u32 mask,
|
||||
u32 value, unsigned int timeout)
|
||||
{
|
||||
struct xe_reg reg = XE_REG(i915_mmio_reg_offset(i915_reg));
|
||||
|
||||
return xe_mmio_wait32(__compat_uncore_to_mmio(uncore), reg, mask, value,
|
||||
timeout * USEC_PER_MSEC, NULL, false);
|
||||
}
|
||||
|
||||
static inline int intel_wait_for_register_fw(struct intel_uncore *uncore,
|
||||
i915_reg_t i915_reg, u32 mask,
|
||||
u32 value, unsigned int timeout,
|
||||
u32 *out_value)
|
||||
{
|
||||
struct xe_reg reg = XE_REG(i915_mmio_reg_offset(i915_reg));
|
||||
|
||||
return xe_mmio_wait32(__compat_uncore_to_mmio(uncore), reg, mask, value,
|
||||
timeout * USEC_PER_MSEC, out_value, false);
|
||||
}
|
||||
|
||||
static inline int
|
||||
__intel_wait_for_register(struct intel_uncore *uncore, i915_reg_t i915_reg,
|
||||
u32 mask, u32 value, unsigned int fast_timeout_us,
|
||||
@@ -133,6 +112,16 @@ __intel_wait_for_register(struct intel_uncore *uncore, i915_reg_t i915_reg,
|
||||
out_value, atomic);
|
||||
}
|
||||
|
||||
static inline int
|
||||
__intel_wait_for_register_fw(struct intel_uncore *uncore, i915_reg_t i915_reg,
|
||||
u32 mask, u32 value, unsigned int fast_timeout_us,
|
||||
unsigned int slow_timeout_ms, u32 *out_value)
|
||||
{
|
||||
return __intel_wait_for_register(uncore, i915_reg, mask, value,
|
||||
fast_timeout_us, slow_timeout_ms,
|
||||
out_value);
|
||||
}
|
||||
|
||||
static inline u32 intel_uncore_read_fw(struct intel_uncore *uncore,
|
||||
i915_reg_t i915_reg)
|
||||
{
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "xe_bo.h"
|
||||
#include "intel_bo.h"
|
||||
#include "intel_frontbuffer.h"
|
||||
|
||||
bool intel_bo_is_tiled(struct drm_gem_object *obj)
|
||||
{
|
||||
@@ -28,10 +29,6 @@ bool intel_bo_is_protected(struct drm_gem_object *obj)
|
||||
return xe_bo_is_protected(gem_to_xe_bo(obj));
|
||||
}
|
||||
|
||||
void intel_bo_flush_if_display(struct drm_gem_object *obj)
|
||||
{
|
||||
}
|
||||
|
||||
int intel_bo_fb_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
|
||||
{
|
||||
return drm_gem_prime_mmap(obj, vma);
|
||||
@@ -44,15 +41,60 @@ int intel_bo_read_from_page(struct drm_gem_object *obj, u64 offset, void *dst, i
|
||||
return xe_bo_read(bo, offset, dst, size);
|
||||
}
|
||||
|
||||
struct intel_frontbuffer *intel_bo_get_frontbuffer(struct drm_gem_object *obj)
|
||||
struct xe_frontbuffer {
|
||||
struct intel_frontbuffer base;
|
||||
struct drm_gem_object *obj;
|
||||
struct kref ref;
|
||||
};
|
||||
|
||||
struct intel_frontbuffer *intel_bo_frontbuffer_get(struct drm_gem_object *obj)
|
||||
{
|
||||
return NULL;
|
||||
struct xe_frontbuffer *front;
|
||||
|
||||
front = kmalloc(sizeof(*front), GFP_KERNEL);
|
||||
if (!front)
|
||||
return NULL;
|
||||
|
||||
intel_frontbuffer_init(&front->base, obj->dev);
|
||||
|
||||
kref_init(&front->ref);
|
||||
|
||||
drm_gem_object_get(obj);
|
||||
front->obj = obj;
|
||||
|
||||
return &front->base;
|
||||
}
|
||||
|
||||
struct intel_frontbuffer *intel_bo_set_frontbuffer(struct drm_gem_object *obj,
|
||||
struct intel_frontbuffer *front)
|
||||
void intel_bo_frontbuffer_ref(struct intel_frontbuffer *_front)
|
||||
{
|
||||
struct xe_frontbuffer *front =
|
||||
container_of(_front, typeof(*front), base);
|
||||
|
||||
kref_get(&front->ref);
|
||||
}
|
||||
|
||||
static void frontbuffer_release(struct kref *ref)
|
||||
{
|
||||
struct xe_frontbuffer *front =
|
||||
container_of(ref, typeof(*front), ref);
|
||||
|
||||
intel_frontbuffer_fini(&front->base);
|
||||
|
||||
drm_gem_object_put(front->obj);
|
||||
|
||||
kfree(front);
|
||||
}
|
||||
|
||||
void intel_bo_frontbuffer_put(struct intel_frontbuffer *_front)
|
||||
{
|
||||
struct xe_frontbuffer *front =
|
||||
container_of(_front, typeof(*front), base);
|
||||
|
||||
kref_put(&front->ref, frontbuffer_release);
|
||||
}
|
||||
|
||||
void intel_bo_frontbuffer_flush_for_display(struct intel_frontbuffer *front)
|
||||
{
|
||||
return front;
|
||||
}
|
||||
|
||||
void intel_bo_describe(struct seq_file *m, struct drm_gem_object *obj)
|
||||
|
||||
@@ -656,9 +656,6 @@ struct xe_device {
|
||||
*/
|
||||
u32 edram_size_mb;
|
||||
|
||||
/* To shut up runtime pm macros.. */
|
||||
struct xe_runtime_pm {} runtime_pm;
|
||||
|
||||
struct intel_uncore {
|
||||
spinlock_t lock;
|
||||
} uncore;
|
||||
|
||||
Reference in New Issue
Block a user