Skip to content

Commit 7124e13

Browse files
committed
drm/i915/xe3lpd: Power request asserting/deasserting
There is a HW issue that arises when there are race conditions between TCSS entering/exiting TC7 or TC10 states while the driver is asserting/deasserting TCSS power request. As a workaround, Display driver will implement a mailbox sequence to ensure that the TCSS is in TC0 when TCSS power request is asserted/deasserted. The sequence is the following 1. Read mailbox command status and wait until run/busy bit is clear 2. Write mailbox data value '1' for power request asserting and '0' for power request deasserting 3. Write mailbox command run/busy bit and command value with 0x1 4. Read mailbox command and wait until run/busy bit is clear before continuing power request. v2: Rename WA function (Gustavo) Limit WA only for PTL platform with a TODO note (Gustavo) Add TCSS_DISP_MAILBOX_IN_CMD_RUN_BUSY for clarity when writing register data (Gustavo) Move register defs from i915_reg.h to intel_cx0_phy_regs.h (Gustavo) v3: Use "struct intel_display" instead of "struct drm_i915_private" (Jani) Move defs above C10 definitions in the intel_cx0_phy_regs.h file (Gustavo) Move drm_WARN_ON() inside WA function (Gustavo) Rename workaround function as wa_14020908590() (Gustvo) Use boolean enable instead of if-else structure (Raag) v4: Drop drm_WARN_ON() (Raag) Fix function definition to fit into a single line (Raag) v5: Drop TCSS_DISP_MAILBOX_IN_CMD_RUN_BUSY from TCSS_DISP_MAILBOX_IN_CMD_DATA(val) macro (Jani) Rename WA function with some meaningful name and add comment on WA number (Jani) Use struct intel_display on WA calling function (Jani) Reviewed-by: Raag Jadav <[email protected]> (v4) Acked-by: Jani Nikula <[email protected]> (v5) Signed-off-by: Mika Kahola <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 125a66a commit 7124e13

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,13 @@
200200
#define XELPDP_SSC_ENABLE_PLLA REG_BIT(1)
201201
#define XELPDP_SSC_ENABLE_PLLB REG_BIT(0)
202202

203+
#define TCSS_DISP_MAILBOX_IN_CMD _MMIO(0x161300)
204+
#define TCSS_DISP_MAILBOX_IN_CMD_RUN_BUSY REG_BIT(31)
205+
#define TCSS_DISP_MAILBOX_IN_CMD_CMD_MASK REG_GENMASK(7, 0)
206+
#define TCSS_DISP_MAILBOX_IN_CMD_DATA(val) REG_FIELD_PREP(TCSS_DISP_MAILBOX_IN_CMD_CMD_MASK, val)
207+
208+
#define TCSS_DISP_MAILBOX_IN_DATA _MMIO(0x161304)
209+
203210
/* C10 Vendor Registers */
204211
#define PHY_C10_VDR_PLL(idx) (0xC00 + (idx))
205212
#define C10_PLL0_FRACEN REG_BIT8(4)

drivers/gpu/drm/i915/display/intel_tc.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,15 +1013,47 @@ xelpdp_tc_phy_wait_for_tcss_power(struct intel_tc_port *tc, bool enabled)
10131013
return true;
10141014
}
10151015

1016+
/*
1017+
* Gfx driver WA 14020908590 for PTL tcss_rxdetect_clkswb_req/ack
1018+
* handshake violation when pwwreq= 0->1 during TC7/10 entry
1019+
*/
1020+
static void xelpdp_tc_power_request_wa(struct intel_display *display, bool enable)
1021+
{
1022+
/* check if mailbox is running busy */
1023+
if (intel_de_wait_for_clear(display, TCSS_DISP_MAILBOX_IN_CMD,
1024+
TCSS_DISP_MAILBOX_IN_CMD_RUN_BUSY, 10)) {
1025+
drm_dbg_kms(display->drm,
1026+
"Timeout waiting for TCSS mailbox run/busy bit to clear\n");
1027+
return;
1028+
}
1029+
1030+
intel_de_write(display, TCSS_DISP_MAILBOX_IN_DATA, enable ? 1 : 0);
1031+
intel_de_write(display, TCSS_DISP_MAILBOX_IN_CMD,
1032+
TCSS_DISP_MAILBOX_IN_CMD_RUN_BUSY |
1033+
TCSS_DISP_MAILBOX_IN_CMD_DATA(0x1));
1034+
1035+
/* wait to clear mailbox running busy bit before continuing */
1036+
if (intel_de_wait_for_clear(display, TCSS_DISP_MAILBOX_IN_CMD,
1037+
TCSS_DISP_MAILBOX_IN_CMD_RUN_BUSY, 10)) {
1038+
drm_dbg_kms(display->drm,
1039+
"Timeout after writing data to mailbox. Mailbox run/busy bit did not clear\n");
1040+
return;
1041+
}
1042+
}
1043+
10161044
static void __xelpdp_tc_phy_enable_tcss_power(struct intel_tc_port *tc, bool enable)
10171045
{
10181046
struct drm_i915_private *i915 = tc_to_i915(tc);
1047+
struct intel_display *display = &i915->display;
10191048
enum port port = tc->dig_port->base.port;
10201049
i915_reg_t reg = XELPDP_PORT_BUF_CTL1(i915, port);
10211050
u32 val;
10221051

10231052
assert_tc_cold_blocked(tc);
10241053

1054+
if (DISPLAY_VER(display) == 30)
1055+
xelpdp_tc_power_request_wa(display, enable);
1056+
10251057
val = intel_de_read(i915, reg);
10261058
if (enable)
10271059
val |= XELPDP_TCSS_POWER_REQUEST;

0 commit comments

Comments
 (0)