mirror of https://github.com/torvalds/linux.git
Merge tag 'drm-intel-next-2025-06-18' of https://gitlab.freedesktop.org/drm/i915/kernel into drm-next
drm/i915 feature pull for v6.17: Features and functionality: - Add support for DSC fractional link bpp on DP MST (Imre) - Add support for simultaneous Panel Replay and Adaptive Sync (Jouni) - Add support for PTL+ double buffered LUT registers (Chaitanya, Ville) - Add PIPEDMC event handling in preparation for flip queue (Ville) Refactoring and cleanups: - Rename lots of DPLL interfaces to unify them (Suraj) - Allocate struct intel_display dynamically (Jani) - Abstract VLV IOSF sideband better (Jani) - Use str_true_false() helper (Yumeng Fang) - Refactor DSB code in preparation for flip queue (Ville) - Use drm_modeset_lock_assert_held() instead of open coding (Luca) - Remove unused arg from skl_scaler_get_filter_select() (Luca) - Split out a separate display register header (Jani) - Abstract DRAM detection better (Jani) - Convert LPT/WPT SBI sideband to struct intel_display (Jani) Fixes: - Fix DSI HS command dispatch with forced pipeline flush (Gareth Yu) - Fix BMG and LNL+ DP adaptive sync SDP programming (Ankit) - Fix error path for xe display workqueue allocation (Haoxiang Li) - Disable DP AUX access probe where not required (Imre) - Fix DKL PHY access if the port is invalid (Luca) - Fix PSR2_SU_STATUS access on ADL+ (Jouni) - Add sanity checks for porch and sync on BXT/GLK DSI (Ville) DRM core changes: - Change AUX DPCD access probe address (Imre) - Refactor EDID quirks, amd make them available to drivers (Imre) - Add quirk for DPCD access probe (Imre) - Add DPCD definitions for Panel Replay capabilities (Jouni) Merges: - Backmerges to sync with v6.15-rcs and v6.16-rc1 (Jani) Signed-off-by: Dave Airlie <airlied@redhat.com> From: Jani Nikula <jani.nikula@intel.com> Link: https://lore.kernel.org/r/fff9f231850ed410bd81b53de43eff0b98240d31@intel.com
This commit is contained in:
commit
36c52fb703
|
|
@ -692,6 +692,34 @@ void drm_dp_dpcd_set_powered(struct drm_dp_aux *aux, bool powered)
|
|||
}
|
||||
EXPORT_SYMBOL(drm_dp_dpcd_set_powered);
|
||||
|
||||
/**
|
||||
* drm_dp_dpcd_set_probe() - Set whether a probing before DPCD access is done
|
||||
* @aux: DisplayPort AUX channel
|
||||
* @enable: Enable the probing if required
|
||||
*/
|
||||
void drm_dp_dpcd_set_probe(struct drm_dp_aux *aux, bool enable)
|
||||
{
|
||||
WRITE_ONCE(aux->dpcd_probe_disabled, !enable);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_dp_dpcd_set_probe);
|
||||
|
||||
static bool dpcd_access_needs_probe(struct drm_dp_aux *aux)
|
||||
{
|
||||
/*
|
||||
* HP ZR24w corrupts the first DPCD access after entering power save
|
||||
* mode. Eg. on a read, the entire buffer will be filled with the same
|
||||
* byte. Do a throw away read to avoid corrupting anything we care
|
||||
* about. Afterwards things will work correctly until the monitor
|
||||
* gets woken up and subsequently re-enters power save mode.
|
||||
*
|
||||
* The user pressing any button on the monitor is enough to wake it
|
||||
* up, so there is no particularly good place to do the workaround.
|
||||
* We just have to do it before any DPCD access and hope that the
|
||||
* monitor doesn't power down exactly after the throw away read.
|
||||
*/
|
||||
return !aux->is_remote && !READ_ONCE(aux->dpcd_probe_disabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_dp_dpcd_read() - read a series of bytes from the DPCD
|
||||
* @aux: DisplayPort AUX channel (SST or MST)
|
||||
|
|
@ -713,20 +741,8 @@ ssize_t drm_dp_dpcd_read(struct drm_dp_aux *aux, unsigned int offset,
|
|||
{
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* HP ZR24w corrupts the first DPCD access after entering power save
|
||||
* mode. Eg. on a read, the entire buffer will be filled with the same
|
||||
* byte. Do a throw away read to avoid corrupting anything we care
|
||||
* about. Afterwards things will work correctly until the monitor
|
||||
* gets woken up and subsequently re-enters power save mode.
|
||||
*
|
||||
* The user pressing any button on the monitor is enough to wake it
|
||||
* up, so there is no particularly good place to do the workaround.
|
||||
* We just have to do it before any DPCD access and hope that the
|
||||
* monitor doesn't power down exactly after the throw away read.
|
||||
*/
|
||||
if (!aux->is_remote) {
|
||||
ret = drm_dp_dpcd_probe(aux, DP_DPCD_REV);
|
||||
if (dpcd_access_needs_probe(aux)) {
|
||||
ret = drm_dp_dpcd_probe(aux, DP_LANE0_1_STATUS);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,34 +67,36 @@ static int oui(u8 first, u8 second, u8 third)
|
|||
* on as many displays as possible).
|
||||
*/
|
||||
|
||||
/* First detailed mode wrong, use largest 60Hz mode */
|
||||
#define EDID_QUIRK_PREFER_LARGE_60 (1 << 0)
|
||||
/* Reported 135MHz pixel clock is too high, needs adjustment */
|
||||
#define EDID_QUIRK_135_CLOCK_TOO_HIGH (1 << 1)
|
||||
/* Prefer the largest mode at 75 Hz */
|
||||
#define EDID_QUIRK_PREFER_LARGE_75 (1 << 2)
|
||||
/* Detail timing is in cm not mm */
|
||||
#define EDID_QUIRK_DETAILED_IN_CM (1 << 3)
|
||||
/* Detailed timing descriptors have bogus size values, so just take the
|
||||
* maximum size and use that.
|
||||
*/
|
||||
#define EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE (1 << 4)
|
||||
/* use +hsync +vsync for detailed mode */
|
||||
#define EDID_QUIRK_DETAILED_SYNC_PP (1 << 6)
|
||||
/* Force reduced-blanking timings for detailed modes */
|
||||
#define EDID_QUIRK_FORCE_REDUCED_BLANKING (1 << 7)
|
||||
/* Force 8bpc */
|
||||
#define EDID_QUIRK_FORCE_8BPC (1 << 8)
|
||||
/* Force 12bpc */
|
||||
#define EDID_QUIRK_FORCE_12BPC (1 << 9)
|
||||
/* Force 6bpc */
|
||||
#define EDID_QUIRK_FORCE_6BPC (1 << 10)
|
||||
/* Force 10bpc */
|
||||
#define EDID_QUIRK_FORCE_10BPC (1 << 11)
|
||||
/* Non desktop display (i.e. HMD) */
|
||||
#define EDID_QUIRK_NON_DESKTOP (1 << 12)
|
||||
/* Cap the DSC target bitrate to 15bpp */
|
||||
#define EDID_QUIRK_CAP_DSC_15BPP (1 << 13)
|
||||
enum drm_edid_internal_quirk {
|
||||
/* First detailed mode wrong, use largest 60Hz mode */
|
||||
EDID_QUIRK_PREFER_LARGE_60 = DRM_EDID_QUIRK_NUM,
|
||||
/* Reported 135MHz pixel clock is too high, needs adjustment */
|
||||
EDID_QUIRK_135_CLOCK_TOO_HIGH,
|
||||
/* Prefer the largest mode at 75 Hz */
|
||||
EDID_QUIRK_PREFER_LARGE_75,
|
||||
/* Detail timing is in cm not mm */
|
||||
EDID_QUIRK_DETAILED_IN_CM,
|
||||
/* Detailed timing descriptors have bogus size values, so just take the
|
||||
* maximum size and use that.
|
||||
*/
|
||||
EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE,
|
||||
/* use +hsync +vsync for detailed mode */
|
||||
EDID_QUIRK_DETAILED_SYNC_PP,
|
||||
/* Force reduced-blanking timings for detailed modes */
|
||||
EDID_QUIRK_FORCE_REDUCED_BLANKING,
|
||||
/* Force 8bpc */
|
||||
EDID_QUIRK_FORCE_8BPC,
|
||||
/* Force 12bpc */
|
||||
EDID_QUIRK_FORCE_12BPC,
|
||||
/* Force 6bpc */
|
||||
EDID_QUIRK_FORCE_6BPC,
|
||||
/* Force 10bpc */
|
||||
EDID_QUIRK_FORCE_10BPC,
|
||||
/* Non desktop display (i.e. HMD) */
|
||||
EDID_QUIRK_NON_DESKTOP,
|
||||
/* Cap the DSC target bitrate to 15bpp */
|
||||
EDID_QUIRK_CAP_DSC_15BPP,
|
||||
};
|
||||
|
||||
#define MICROSOFT_IEEE_OUI 0xca125c
|
||||
|
||||
|
|
@ -129,124 +131,132 @@ static const struct edid_quirk {
|
|||
u32 quirks;
|
||||
} edid_quirk_list[] = {
|
||||
/* Acer AL1706 */
|
||||
EDID_QUIRK('A', 'C', 'R', 44358, EDID_QUIRK_PREFER_LARGE_60),
|
||||
EDID_QUIRK('A', 'C', 'R', 44358, BIT(EDID_QUIRK_PREFER_LARGE_60)),
|
||||
/* Acer F51 */
|
||||
EDID_QUIRK('A', 'P', 'I', 0x7602, EDID_QUIRK_PREFER_LARGE_60),
|
||||
EDID_QUIRK('A', 'P', 'I', 0x7602, BIT(EDID_QUIRK_PREFER_LARGE_60)),
|
||||
|
||||
/* AEO model 0 reports 8 bpc, but is a 6 bpc panel */
|
||||
EDID_QUIRK('A', 'E', 'O', 0, EDID_QUIRK_FORCE_6BPC),
|
||||
EDID_QUIRK('A', 'E', 'O', 0, BIT(EDID_QUIRK_FORCE_6BPC)),
|
||||
|
||||
/* BenQ GW2765 */
|
||||
EDID_QUIRK('B', 'N', 'Q', 0x78d6, EDID_QUIRK_FORCE_8BPC),
|
||||
EDID_QUIRK('B', 'N', 'Q', 0x78d6, BIT(EDID_QUIRK_FORCE_8BPC)),
|
||||
|
||||
/* BOE model on HP Pavilion 15-n233sl reports 8 bpc, but is a 6 bpc panel */
|
||||
EDID_QUIRK('B', 'O', 'E', 0x78b, EDID_QUIRK_FORCE_6BPC),
|
||||
EDID_QUIRK('B', 'O', 'E', 0x78b, BIT(EDID_QUIRK_FORCE_6BPC)),
|
||||
|
||||
/* CPT panel of Asus UX303LA reports 8 bpc, but is a 6 bpc panel */
|
||||
EDID_QUIRK('C', 'P', 'T', 0x17df, EDID_QUIRK_FORCE_6BPC),
|
||||
EDID_QUIRK('C', 'P', 'T', 0x17df, BIT(EDID_QUIRK_FORCE_6BPC)),
|
||||
|
||||
/* SDC panel of Lenovo B50-80 reports 8 bpc, but is a 6 bpc panel */
|
||||
EDID_QUIRK('S', 'D', 'C', 0x3652, EDID_QUIRK_FORCE_6BPC),
|
||||
EDID_QUIRK('S', 'D', 'C', 0x3652, BIT(EDID_QUIRK_FORCE_6BPC)),
|
||||
|
||||
/* BOE model 0x0771 reports 8 bpc, but is a 6 bpc panel */
|
||||
EDID_QUIRK('B', 'O', 'E', 0x0771, EDID_QUIRK_FORCE_6BPC),
|
||||
EDID_QUIRK('B', 'O', 'E', 0x0771, BIT(EDID_QUIRK_FORCE_6BPC)),
|
||||
|
||||
/* Belinea 10 15 55 */
|
||||
EDID_QUIRK('M', 'A', 'X', 1516, EDID_QUIRK_PREFER_LARGE_60),
|
||||
EDID_QUIRK('M', 'A', 'X', 0x77e, EDID_QUIRK_PREFER_LARGE_60),
|
||||
EDID_QUIRK('M', 'A', 'X', 1516, BIT(EDID_QUIRK_PREFER_LARGE_60)),
|
||||
EDID_QUIRK('M', 'A', 'X', 0x77e, BIT(EDID_QUIRK_PREFER_LARGE_60)),
|
||||
|
||||
/* Envision Peripherals, Inc. EN-7100e */
|
||||
EDID_QUIRK('E', 'P', 'I', 59264, EDID_QUIRK_135_CLOCK_TOO_HIGH),
|
||||
EDID_QUIRK('E', 'P', 'I', 59264, BIT(EDID_QUIRK_135_CLOCK_TOO_HIGH)),
|
||||
/* Envision EN2028 */
|
||||
EDID_QUIRK('E', 'P', 'I', 8232, EDID_QUIRK_PREFER_LARGE_60),
|
||||
EDID_QUIRK('E', 'P', 'I', 8232, BIT(EDID_QUIRK_PREFER_LARGE_60)),
|
||||
|
||||
/* Funai Electronics PM36B */
|
||||
EDID_QUIRK('F', 'C', 'M', 13600, EDID_QUIRK_PREFER_LARGE_75 |
|
||||
EDID_QUIRK_DETAILED_IN_CM),
|
||||
EDID_QUIRK('F', 'C', 'M', 13600, BIT(EDID_QUIRK_PREFER_LARGE_75) |
|
||||
BIT(EDID_QUIRK_DETAILED_IN_CM)),
|
||||
|
||||
/* LG 27GP950 */
|
||||
EDID_QUIRK('G', 'S', 'M', 0x5bbf, EDID_QUIRK_CAP_DSC_15BPP),
|
||||
EDID_QUIRK('G', 'S', 'M', 0x5bbf, BIT(EDID_QUIRK_CAP_DSC_15BPP)),
|
||||
|
||||
/* LG 27GN950 */
|
||||
EDID_QUIRK('G', 'S', 'M', 0x5b9a, EDID_QUIRK_CAP_DSC_15BPP),
|
||||
EDID_QUIRK('G', 'S', 'M', 0x5b9a, BIT(EDID_QUIRK_CAP_DSC_15BPP)),
|
||||
|
||||
/* LGD panel of HP zBook 17 G2, eDP 10 bpc, but reports unknown bpc */
|
||||
EDID_QUIRK('L', 'G', 'D', 764, EDID_QUIRK_FORCE_10BPC),
|
||||
EDID_QUIRK('L', 'G', 'D', 764, BIT(EDID_QUIRK_FORCE_10BPC)),
|
||||
|
||||
/* LG Philips LCD LP154W01-A5 */
|
||||
EDID_QUIRK('L', 'P', 'L', 0, EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE),
|
||||
EDID_QUIRK('L', 'P', 'L', 0x2a00, EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE),
|
||||
EDID_QUIRK('L', 'P', 'L', 0, BIT(EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE)),
|
||||
EDID_QUIRK('L', 'P', 'L', 0x2a00, BIT(EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE)),
|
||||
|
||||
/* Samsung SyncMaster 205BW. Note: irony */
|
||||
EDID_QUIRK('S', 'A', 'M', 541, EDID_QUIRK_DETAILED_SYNC_PP),
|
||||
EDID_QUIRK('S', 'A', 'M', 541, BIT(EDID_QUIRK_DETAILED_SYNC_PP)),
|
||||
/* Samsung SyncMaster 22[5-6]BW */
|
||||
EDID_QUIRK('S', 'A', 'M', 596, EDID_QUIRK_PREFER_LARGE_60),
|
||||
EDID_QUIRK('S', 'A', 'M', 638, EDID_QUIRK_PREFER_LARGE_60),
|
||||
EDID_QUIRK('S', 'A', 'M', 596, BIT(EDID_QUIRK_PREFER_LARGE_60)),
|
||||
EDID_QUIRK('S', 'A', 'M', 638, BIT(EDID_QUIRK_PREFER_LARGE_60)),
|
||||
|
||||
/* Sony PVM-2541A does up to 12 bpc, but only reports max 8 bpc */
|
||||
EDID_QUIRK('S', 'N', 'Y', 0x2541, EDID_QUIRK_FORCE_12BPC),
|
||||
EDID_QUIRK('S', 'N', 'Y', 0x2541, BIT(EDID_QUIRK_FORCE_12BPC)),
|
||||
|
||||
/* ViewSonic VA2026w */
|
||||
EDID_QUIRK('V', 'S', 'C', 5020, EDID_QUIRK_FORCE_REDUCED_BLANKING),
|
||||
EDID_QUIRK('V', 'S', 'C', 5020, BIT(EDID_QUIRK_FORCE_REDUCED_BLANKING)),
|
||||
|
||||
/* Medion MD 30217 PG */
|
||||
EDID_QUIRK('M', 'E', 'D', 0x7b8, EDID_QUIRK_PREFER_LARGE_75),
|
||||
EDID_QUIRK('M', 'E', 'D', 0x7b8, BIT(EDID_QUIRK_PREFER_LARGE_75)),
|
||||
|
||||
/* Lenovo G50 */
|
||||
EDID_QUIRK('S', 'D', 'C', 18514, EDID_QUIRK_FORCE_6BPC),
|
||||
EDID_QUIRK('S', 'D', 'C', 18514, BIT(EDID_QUIRK_FORCE_6BPC)),
|
||||
|
||||
/* Panel in Samsung NP700G7A-S01PL notebook reports 6bpc */
|
||||
EDID_QUIRK('S', 'E', 'C', 0xd033, EDID_QUIRK_FORCE_8BPC),
|
||||
EDID_QUIRK('S', 'E', 'C', 0xd033, BIT(EDID_QUIRK_FORCE_8BPC)),
|
||||
|
||||
/* Rotel RSX-1058 forwards sink's EDID but only does HDMI 1.1*/
|
||||
EDID_QUIRK('E', 'T', 'R', 13896, EDID_QUIRK_FORCE_8BPC),
|
||||
EDID_QUIRK('E', 'T', 'R', 13896, BIT(EDID_QUIRK_FORCE_8BPC)),
|
||||
|
||||
/* Valve Index Headset */
|
||||
EDID_QUIRK('V', 'L', 'V', 0x91a8, EDID_QUIRK_NON_DESKTOP),
|
||||
EDID_QUIRK('V', 'L', 'V', 0x91b0, EDID_QUIRK_NON_DESKTOP),
|
||||
EDID_QUIRK('V', 'L', 'V', 0x91b1, EDID_QUIRK_NON_DESKTOP),
|
||||
EDID_QUIRK('V', 'L', 'V', 0x91b2, EDID_QUIRK_NON_DESKTOP),
|
||||
EDID_QUIRK('V', 'L', 'V', 0x91b3, EDID_QUIRK_NON_DESKTOP),
|
||||
EDID_QUIRK('V', 'L', 'V', 0x91b4, EDID_QUIRK_NON_DESKTOP),
|
||||
EDID_QUIRK('V', 'L', 'V', 0x91b5, EDID_QUIRK_NON_DESKTOP),
|
||||
EDID_QUIRK('V', 'L', 'V', 0x91b6, EDID_QUIRK_NON_DESKTOP),
|
||||
EDID_QUIRK('V', 'L', 'V', 0x91b7, EDID_QUIRK_NON_DESKTOP),
|
||||
EDID_QUIRK('V', 'L', 'V', 0x91b8, EDID_QUIRK_NON_DESKTOP),
|
||||
EDID_QUIRK('V', 'L', 'V', 0x91b9, EDID_QUIRK_NON_DESKTOP),
|
||||
EDID_QUIRK('V', 'L', 'V', 0x91ba, EDID_QUIRK_NON_DESKTOP),
|
||||
EDID_QUIRK('V', 'L', 'V', 0x91bb, EDID_QUIRK_NON_DESKTOP),
|
||||
EDID_QUIRK('V', 'L', 'V', 0x91bc, EDID_QUIRK_NON_DESKTOP),
|
||||
EDID_QUIRK('V', 'L', 'V', 0x91bd, EDID_QUIRK_NON_DESKTOP),
|
||||
EDID_QUIRK('V', 'L', 'V', 0x91be, EDID_QUIRK_NON_DESKTOP),
|
||||
EDID_QUIRK('V', 'L', 'V', 0x91bf, EDID_QUIRK_NON_DESKTOP),
|
||||
EDID_QUIRK('V', 'L', 'V', 0x91a8, BIT(EDID_QUIRK_NON_DESKTOP)),
|
||||
EDID_QUIRK('V', 'L', 'V', 0x91b0, BIT(EDID_QUIRK_NON_DESKTOP)),
|
||||
EDID_QUIRK('V', 'L', 'V', 0x91b1, BIT(EDID_QUIRK_NON_DESKTOP)),
|
||||
EDID_QUIRK('V', 'L', 'V', 0x91b2, BIT(EDID_QUIRK_NON_DESKTOP)),
|
||||
EDID_QUIRK('V', 'L', 'V', 0x91b3, BIT(EDID_QUIRK_NON_DESKTOP)),
|
||||
EDID_QUIRK('V', 'L', 'V', 0x91b4, BIT(EDID_QUIRK_NON_DESKTOP)),
|
||||
EDID_QUIRK('V', 'L', 'V', 0x91b5, BIT(EDID_QUIRK_NON_DESKTOP)),
|
||||
EDID_QUIRK('V', 'L', 'V', 0x91b6, BIT(EDID_QUIRK_NON_DESKTOP)),
|
||||
EDID_QUIRK('V', 'L', 'V', 0x91b7, BIT(EDID_QUIRK_NON_DESKTOP)),
|
||||
EDID_QUIRK('V', 'L', 'V', 0x91b8, BIT(EDID_QUIRK_NON_DESKTOP)),
|
||||
EDID_QUIRK('V', 'L', 'V', 0x91b9, BIT(EDID_QUIRK_NON_DESKTOP)),
|
||||
EDID_QUIRK('V', 'L', 'V', 0x91ba, BIT(EDID_QUIRK_NON_DESKTOP)),
|
||||
EDID_QUIRK('V', 'L', 'V', 0x91bb, BIT(EDID_QUIRK_NON_DESKTOP)),
|
||||
EDID_QUIRK('V', 'L', 'V', 0x91bc, BIT(EDID_QUIRK_NON_DESKTOP)),
|
||||
EDID_QUIRK('V', 'L', 'V', 0x91bd, BIT(EDID_QUIRK_NON_DESKTOP)),
|
||||
EDID_QUIRK('V', 'L', 'V', 0x91be, BIT(EDID_QUIRK_NON_DESKTOP)),
|
||||
EDID_QUIRK('V', 'L', 'V', 0x91bf, BIT(EDID_QUIRK_NON_DESKTOP)),
|
||||
|
||||
/* HTC Vive and Vive Pro VR Headsets */
|
||||
EDID_QUIRK('H', 'V', 'R', 0xaa01, EDID_QUIRK_NON_DESKTOP),
|
||||
EDID_QUIRK('H', 'V', 'R', 0xaa02, EDID_QUIRK_NON_DESKTOP),
|
||||
EDID_QUIRK('H', 'V', 'R', 0xaa01, BIT(EDID_QUIRK_NON_DESKTOP)),
|
||||
EDID_QUIRK('H', 'V', 'R', 0xaa02, BIT(EDID_QUIRK_NON_DESKTOP)),
|
||||
|
||||
/* Oculus Rift DK1, DK2, CV1 and Rift S VR Headsets */
|
||||
EDID_QUIRK('O', 'V', 'R', 0x0001, EDID_QUIRK_NON_DESKTOP),
|
||||
EDID_QUIRK('O', 'V', 'R', 0x0003, EDID_QUIRK_NON_DESKTOP),
|
||||
EDID_QUIRK('O', 'V', 'R', 0x0004, EDID_QUIRK_NON_DESKTOP),
|
||||
EDID_QUIRK('O', 'V', 'R', 0x0012, EDID_QUIRK_NON_DESKTOP),
|
||||
EDID_QUIRK('O', 'V', 'R', 0x0001, BIT(EDID_QUIRK_NON_DESKTOP)),
|
||||
EDID_QUIRK('O', 'V', 'R', 0x0003, BIT(EDID_QUIRK_NON_DESKTOP)),
|
||||
EDID_QUIRK('O', 'V', 'R', 0x0004, BIT(EDID_QUIRK_NON_DESKTOP)),
|
||||
EDID_QUIRK('O', 'V', 'R', 0x0012, BIT(EDID_QUIRK_NON_DESKTOP)),
|
||||
|
||||
/* Windows Mixed Reality Headsets */
|
||||
EDID_QUIRK('A', 'C', 'R', 0x7fce, EDID_QUIRK_NON_DESKTOP),
|
||||
EDID_QUIRK('L', 'E', 'N', 0x0408, EDID_QUIRK_NON_DESKTOP),
|
||||
EDID_QUIRK('F', 'U', 'J', 0x1970, EDID_QUIRK_NON_DESKTOP),
|
||||
EDID_QUIRK('D', 'E', 'L', 0x7fce, EDID_QUIRK_NON_DESKTOP),
|
||||
EDID_QUIRK('S', 'E', 'C', 0x144a, EDID_QUIRK_NON_DESKTOP),
|
||||
EDID_QUIRK('A', 'U', 'S', 0xc102, EDID_QUIRK_NON_DESKTOP),
|
||||
EDID_QUIRK('A', 'C', 'R', 0x7fce, BIT(EDID_QUIRK_NON_DESKTOP)),
|
||||
EDID_QUIRK('L', 'E', 'N', 0x0408, BIT(EDID_QUIRK_NON_DESKTOP)),
|
||||
EDID_QUIRK('F', 'U', 'J', 0x1970, BIT(EDID_QUIRK_NON_DESKTOP)),
|
||||
EDID_QUIRK('D', 'E', 'L', 0x7fce, BIT(EDID_QUIRK_NON_DESKTOP)),
|
||||
EDID_QUIRK('S', 'E', 'C', 0x144a, BIT(EDID_QUIRK_NON_DESKTOP)),
|
||||
EDID_QUIRK('A', 'U', 'S', 0xc102, BIT(EDID_QUIRK_NON_DESKTOP)),
|
||||
|
||||
/* Sony PlayStation VR Headset */
|
||||
EDID_QUIRK('S', 'N', 'Y', 0x0704, EDID_QUIRK_NON_DESKTOP),
|
||||
EDID_QUIRK('S', 'N', 'Y', 0x0704, BIT(EDID_QUIRK_NON_DESKTOP)),
|
||||
|
||||
/* Sensics VR Headsets */
|
||||
EDID_QUIRK('S', 'E', 'N', 0x1019, EDID_QUIRK_NON_DESKTOP),
|
||||
EDID_QUIRK('S', 'E', 'N', 0x1019, BIT(EDID_QUIRK_NON_DESKTOP)),
|
||||
|
||||
/* OSVR HDK and HDK2 VR Headsets */
|
||||
EDID_QUIRK('S', 'V', 'R', 0x1019, EDID_QUIRK_NON_DESKTOP),
|
||||
EDID_QUIRK('A', 'U', 'O', 0x1111, EDID_QUIRK_NON_DESKTOP),
|
||||
EDID_QUIRK('S', 'V', 'R', 0x1019, BIT(EDID_QUIRK_NON_DESKTOP)),
|
||||
EDID_QUIRK('A', 'U', 'O', 0x1111, BIT(EDID_QUIRK_NON_DESKTOP)),
|
||||
|
||||
/*
|
||||
* @drm_edid_internal_quirk entries end here, following with the
|
||||
* @drm_edid_quirk entries.
|
||||
*/
|
||||
|
||||
/* HP ZR24w DP AUX DPCD access requires probing to prevent corruption. */
|
||||
EDID_QUIRK('H', 'W', 'P', 0x2869, BIT(DRM_EDID_QUIRK_DP_DPCD_PROBE)),
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -2952,6 +2962,18 @@ static u32 edid_get_quirks(const struct drm_edid *drm_edid)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool drm_edid_has_internal_quirk(struct drm_connector *connector,
|
||||
enum drm_edid_internal_quirk quirk)
|
||||
{
|
||||
return connector->display_info.quirks & BIT(quirk);
|
||||
}
|
||||
|
||||
bool drm_edid_has_quirk(struct drm_connector *connector, enum drm_edid_quirk quirk)
|
||||
{
|
||||
return connector->display_info.quirks & BIT(quirk);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_edid_has_quirk);
|
||||
|
||||
#define MODE_SIZE(m) ((m)->hdisplay * (m)->vdisplay)
|
||||
#define MODE_REFRESH_DIFF(c,t) (abs((c) - (t)))
|
||||
|
||||
|
|
@ -2961,7 +2983,6 @@ static u32 edid_get_quirks(const struct drm_edid *drm_edid)
|
|||
*/
|
||||
static void edid_fixup_preferred(struct drm_connector *connector)
|
||||
{
|
||||
const struct drm_display_info *info = &connector->display_info;
|
||||
struct drm_display_mode *t, *cur_mode, *preferred_mode;
|
||||
int target_refresh = 0;
|
||||
int cur_vrefresh, preferred_vrefresh;
|
||||
|
|
@ -2969,9 +2990,9 @@ static void edid_fixup_preferred(struct drm_connector *connector)
|
|||
if (list_empty(&connector->probed_modes))
|
||||
return;
|
||||
|
||||
if (info->quirks & EDID_QUIRK_PREFER_LARGE_60)
|
||||
if (drm_edid_has_internal_quirk(connector, EDID_QUIRK_PREFER_LARGE_60))
|
||||
target_refresh = 60;
|
||||
if (info->quirks & EDID_QUIRK_PREFER_LARGE_75)
|
||||
if (drm_edid_has_internal_quirk(connector, EDID_QUIRK_PREFER_LARGE_75))
|
||||
target_refresh = 75;
|
||||
|
||||
preferred_mode = list_first_entry(&connector->probed_modes,
|
||||
|
|
@ -3475,7 +3496,6 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_connector *connecto
|
|||
const struct drm_edid *drm_edid,
|
||||
const struct detailed_timing *timing)
|
||||
{
|
||||
const struct drm_display_info *info = &connector->display_info;
|
||||
struct drm_device *dev = connector->dev;
|
||||
struct drm_display_mode *mode;
|
||||
const struct detailed_pixel_timing *pt = &timing->data.pixel_data;
|
||||
|
|
@ -3509,7 +3529,7 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_connector *connecto
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (info->quirks & EDID_QUIRK_FORCE_REDUCED_BLANKING) {
|
||||
if (drm_edid_has_internal_quirk(connector, EDID_QUIRK_FORCE_REDUCED_BLANKING)) {
|
||||
mode = drm_cvt_mode(dev, hactive, vactive, 60, true, false, false);
|
||||
if (!mode)
|
||||
return NULL;
|
||||
|
|
@ -3521,7 +3541,7 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_connector *connecto
|
|||
if (!mode)
|
||||
return NULL;
|
||||
|
||||
if (info->quirks & EDID_QUIRK_135_CLOCK_TOO_HIGH)
|
||||
if (drm_edid_has_internal_quirk(connector, EDID_QUIRK_135_CLOCK_TOO_HIGH))
|
||||
mode->clock = 1088 * 10;
|
||||
else
|
||||
mode->clock = le16_to_cpu(timing->pixel_clock) * 10;
|
||||
|
|
@ -3552,7 +3572,7 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_connector *connecto
|
|||
|
||||
drm_mode_do_interlace_quirk(mode, pt);
|
||||
|
||||
if (info->quirks & EDID_QUIRK_DETAILED_SYNC_PP) {
|
||||
if (drm_edid_has_internal_quirk(connector, EDID_QUIRK_DETAILED_SYNC_PP)) {
|
||||
mode->flags |= DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC;
|
||||
} else {
|
||||
mode->flags |= (pt->misc & DRM_EDID_PT_HSYNC_POSITIVE) ?
|
||||
|
|
@ -3565,12 +3585,12 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_connector *connecto
|
|||
mode->width_mm = pt->width_mm_lo | (pt->width_height_mm_hi & 0xf0) << 4;
|
||||
mode->height_mm = pt->height_mm_lo | (pt->width_height_mm_hi & 0xf) << 8;
|
||||
|
||||
if (info->quirks & EDID_QUIRK_DETAILED_IN_CM) {
|
||||
if (drm_edid_has_internal_quirk(connector, EDID_QUIRK_DETAILED_IN_CM)) {
|
||||
mode->width_mm *= 10;
|
||||
mode->height_mm *= 10;
|
||||
}
|
||||
|
||||
if (info->quirks & EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE) {
|
||||
if (drm_edid_has_internal_quirk(connector, EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE)) {
|
||||
mode->width_mm = drm_edid->edid->width_cm * 10;
|
||||
mode->height_mm = drm_edid->edid->height_cm * 10;
|
||||
}
|
||||
|
|
@ -6735,26 +6755,26 @@ static void update_display_info(struct drm_connector *connector,
|
|||
drm_update_mso(connector, drm_edid);
|
||||
|
||||
out:
|
||||
if (info->quirks & EDID_QUIRK_NON_DESKTOP) {
|
||||
if (drm_edid_has_internal_quirk(connector, EDID_QUIRK_NON_DESKTOP)) {
|
||||
drm_dbg_kms(connector->dev, "[CONNECTOR:%d:%s] Non-desktop display%s\n",
|
||||
connector->base.id, connector->name,
|
||||
info->non_desktop ? " (redundant quirk)" : "");
|
||||
info->non_desktop = true;
|
||||
}
|
||||
|
||||
if (info->quirks & EDID_QUIRK_CAP_DSC_15BPP)
|
||||
if (drm_edid_has_internal_quirk(connector, EDID_QUIRK_CAP_DSC_15BPP))
|
||||
info->max_dsc_bpp = 15;
|
||||
|
||||
if (info->quirks & EDID_QUIRK_FORCE_6BPC)
|
||||
if (drm_edid_has_internal_quirk(connector, EDID_QUIRK_FORCE_6BPC))
|
||||
info->bpc = 6;
|
||||
|
||||
if (info->quirks & EDID_QUIRK_FORCE_8BPC)
|
||||
if (drm_edid_has_internal_quirk(connector, EDID_QUIRK_FORCE_8BPC))
|
||||
info->bpc = 8;
|
||||
|
||||
if (info->quirks & EDID_QUIRK_FORCE_10BPC)
|
||||
if (drm_edid_has_internal_quirk(connector, EDID_QUIRK_FORCE_10BPC))
|
||||
info->bpc = 10;
|
||||
|
||||
if (info->quirks & EDID_QUIRK_FORCE_12BPC)
|
||||
if (drm_edid_has_internal_quirk(connector, EDID_QUIRK_FORCE_12BPC))
|
||||
info->bpc = 12;
|
||||
|
||||
/* Depends on info->cea_rev set by drm_parse_cea_ext() above */
|
||||
|
|
@ -6919,7 +6939,6 @@ static int add_displayid_detailed_modes(struct drm_connector *connector,
|
|||
static int _drm_edid_connector_add_modes(struct drm_connector *connector,
|
||||
const struct drm_edid *drm_edid)
|
||||
{
|
||||
const struct drm_display_info *info = &connector->display_info;
|
||||
int num_modes = 0;
|
||||
|
||||
if (!drm_edid)
|
||||
|
|
@ -6949,7 +6968,8 @@ static int _drm_edid_connector_add_modes(struct drm_connector *connector,
|
|||
if (drm_edid->edid->features & DRM_EDID_FEATURE_CONTINUOUS_FREQ)
|
||||
num_modes += add_inferred_modes(connector, drm_edid);
|
||||
|
||||
if (info->quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75))
|
||||
if (drm_edid_has_internal_quirk(connector, EDID_QUIRK_PREFER_LARGE_60) ||
|
||||
drm_edid_has_internal_quirk(connector, EDID_QUIRK_PREFER_LARGE_75))
|
||||
edid_fixup_preferred(connector);
|
||||
|
||||
return num_modes;
|
||||
|
|
|
|||
|
|
@ -40,12 +40,11 @@ i915-y += \
|
|||
intel_pcode.o \
|
||||
intel_region_ttm.o \
|
||||
intel_runtime_pm.o \
|
||||
intel_sbi.o \
|
||||
intel_step.o \
|
||||
intel_uncore.o \
|
||||
intel_uncore_trace.o \
|
||||
intel_wakeref.o \
|
||||
vlv_sideband.o \
|
||||
vlv_iosf_sb.o \
|
||||
vlv_suspend.o
|
||||
|
||||
# core peripheral code
|
||||
|
|
@ -288,6 +287,7 @@ i915-y += \
|
|||
display/intel_pmdemand.o \
|
||||
display/intel_psr.o \
|
||||
display/intel_quirks.o \
|
||||
display/intel_sbi.o \
|
||||
display/intel_sprite.o \
|
||||
display/intel_sprite_uapi.o \
|
||||
display/intel_tc.o \
|
||||
|
|
@ -296,7 +296,8 @@ i915-y += \
|
|||
display/intel_wm.o \
|
||||
display/skl_scaler.o \
|
||||
display/skl_universal_plane.o \
|
||||
display/skl_watermark.o
|
||||
display/skl_watermark.o \
|
||||
display/vlv_sideband.o
|
||||
i915-$(CONFIG_ACPI) += \
|
||||
display/intel_acpi.o \
|
||||
display/intel_opregion.o
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include "intel_crtc.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_power.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dp.h"
|
||||
#include "intel_dp_aux.h"
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#include "intel_crtc.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_power.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dp_aux.h"
|
||||
#include "intel_dpio_phy.h"
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include "i915_reg.h"
|
||||
#include "intel_color_regs.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_rpm.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_pcode.h"
|
||||
|
|
|
|||
|
|
@ -5,10 +5,10 @@
|
|||
|
||||
#include <drm/drm_device.h>
|
||||
|
||||
#include "i915_reg.h"
|
||||
#include "i9xx_display_sr.h"
|
||||
#include "i9xx_wm_regs.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_gmbus.h"
|
||||
#include "intel_pci_config.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
/*
|
||||
* Copyright © 2020 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
|
|
@ -17,6 +18,7 @@
|
|||
#include "intel_atomic_plane.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_irq.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_fb.h"
|
||||
#include "intel_fbc.h"
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include "intel_bo.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_trace.h"
|
||||
#include "intel_fb.h"
|
||||
#include "intel_mchbar_regs.h"
|
||||
|
|
@ -107,43 +108,41 @@ static const struct cxsr_latency *pnv_get_cxsr_latency(struct intel_display *dis
|
|||
|
||||
static void chv_set_memory_dvfs(struct intel_display *display, bool enable)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
u32 val;
|
||||
|
||||
vlv_punit_get(dev_priv);
|
||||
vlv_punit_get(display->drm);
|
||||
|
||||
val = vlv_punit_read(dev_priv, PUNIT_REG_DDR_SETUP2);
|
||||
val = vlv_punit_read(display->drm, PUNIT_REG_DDR_SETUP2);
|
||||
if (enable)
|
||||
val &= ~FORCE_DDR_HIGH_FREQ;
|
||||
else
|
||||
val |= FORCE_DDR_HIGH_FREQ;
|
||||
val &= ~FORCE_DDR_LOW_FREQ;
|
||||
val |= FORCE_DDR_FREQ_REQ_ACK;
|
||||
vlv_punit_write(dev_priv, PUNIT_REG_DDR_SETUP2, val);
|
||||
vlv_punit_write(display->drm, PUNIT_REG_DDR_SETUP2, val);
|
||||
|
||||
if (wait_for((vlv_punit_read(dev_priv, PUNIT_REG_DDR_SETUP2) &
|
||||
if (wait_for((vlv_punit_read(display->drm, PUNIT_REG_DDR_SETUP2) &
|
||||
FORCE_DDR_FREQ_REQ_ACK) == 0, 3))
|
||||
drm_err(display->drm,
|
||||
"timed out waiting for Punit DDR DVFS request\n");
|
||||
|
||||
vlv_punit_put(dev_priv);
|
||||
vlv_punit_put(display->drm);
|
||||
}
|
||||
|
||||
static void chv_set_memory_pm5(struct intel_display *display, bool enable)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
u32 val;
|
||||
|
||||
vlv_punit_get(dev_priv);
|
||||
vlv_punit_get(display->drm);
|
||||
|
||||
val = vlv_punit_read(dev_priv, PUNIT_REG_DSPSSPM);
|
||||
val = vlv_punit_read(display->drm, PUNIT_REG_DSPSSPM);
|
||||
if (enable)
|
||||
val |= DSP_MAXFIFO_PM5_ENABLE;
|
||||
else
|
||||
val &= ~DSP_MAXFIFO_PM5_ENABLE;
|
||||
vlv_punit_write(dev_priv, PUNIT_REG_DSPSSPM, val);
|
||||
vlv_punit_write(display->drm, PUNIT_REG_DSPSSPM, val);
|
||||
|
||||
vlv_punit_put(dev_priv);
|
||||
vlv_punit_put(display->drm);
|
||||
}
|
||||
|
||||
#define FW_WM(value, plane) \
|
||||
|
|
@ -3900,7 +3899,6 @@ static void g4x_wm_sanitize(struct intel_display *display)
|
|||
|
||||
static void vlv_wm_get_hw_state(struct intel_display *display)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
struct vlv_wm_values *wm = &display->wm.vlv;
|
||||
struct intel_crtc *crtc;
|
||||
u32 val;
|
||||
|
|
@ -3911,9 +3909,9 @@ static void vlv_wm_get_hw_state(struct intel_display *display)
|
|||
wm->level = VLV_WM_LEVEL_PM2;
|
||||
|
||||
if (display->platform.cherryview) {
|
||||
vlv_punit_get(dev_priv);
|
||||
vlv_punit_get(display->drm);
|
||||
|
||||
val = vlv_punit_read(dev_priv, PUNIT_REG_DSPSSPM);
|
||||
val = vlv_punit_read(display->drm, PUNIT_REG_DSPSSPM);
|
||||
if (val & DSP_MAXFIFO_PM5_ENABLE)
|
||||
wm->level = VLV_WM_LEVEL_PM5;
|
||||
|
||||
|
|
@ -3926,23 +3924,23 @@ static void vlv_wm_get_hw_state(struct intel_display *display)
|
|||
* HIGH/LOW bits so that we don't actually change
|
||||
* the current state.
|
||||
*/
|
||||
val = vlv_punit_read(dev_priv, PUNIT_REG_DDR_SETUP2);
|
||||
val = vlv_punit_read(display->drm, PUNIT_REG_DDR_SETUP2);
|
||||
val |= FORCE_DDR_FREQ_REQ_ACK;
|
||||
vlv_punit_write(dev_priv, PUNIT_REG_DDR_SETUP2, val);
|
||||
vlv_punit_write(display->drm, PUNIT_REG_DDR_SETUP2, val);
|
||||
|
||||
if (wait_for((vlv_punit_read(dev_priv, PUNIT_REG_DDR_SETUP2) &
|
||||
if (wait_for((vlv_punit_read(display->drm, PUNIT_REG_DDR_SETUP2) &
|
||||
FORCE_DDR_FREQ_REQ_ACK) == 0, 3)) {
|
||||
drm_dbg_kms(display->drm,
|
||||
"Punit not acking DDR DVFS request, "
|
||||
"assuming DDR DVFS is disabled\n");
|
||||
display->wm.num_levels = VLV_WM_LEVEL_PM5 + 1;
|
||||
} else {
|
||||
val = vlv_punit_read(dev_priv, PUNIT_REG_DDR_SETUP2);
|
||||
val = vlv_punit_read(display->drm, PUNIT_REG_DDR_SETUP2);
|
||||
if ((val & FORCE_DDR_HIGH_FREQ) == 0)
|
||||
wm->level = VLV_WM_LEVEL_DDR_DVFS;
|
||||
}
|
||||
|
||||
vlv_punit_put(dev_priv);
|
||||
vlv_punit_put(display->drm);
|
||||
}
|
||||
|
||||
for_each_intel_crtc(display->drm, crtc) {
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
#include "intel_crtc.h"
|
||||
#include "intel_ddi.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_dsi.h"
|
||||
#include "intel_dsi_vbt.h"
|
||||
#include "intel_panel.h"
|
||||
|
|
@ -192,12 +193,12 @@ static int dsi_send_pkt_hdr(struct intel_dsi_host *host,
|
|||
else
|
||||
tmp &= ~PAYLOAD_PRESENT;
|
||||
|
||||
tmp &= ~VBLANK_FENCE;
|
||||
tmp &= ~(VBLANK_FENCE | LP_DATA_TRANSFER | PIPELINE_FLUSH);
|
||||
|
||||
if (enable_lpdt)
|
||||
tmp |= LP_DATA_TRANSFER;
|
||||
else
|
||||
tmp &= ~LP_DATA_TRANSFER;
|
||||
tmp |= PIPELINE_FLUSH;
|
||||
|
||||
tmp &= ~(PARAM_WC_MASK | VC_MASK | DT_MASK);
|
||||
tmp |= ((packet->header[0] & VC_MASK) << VC_SHIFT);
|
||||
|
|
@ -658,7 +659,7 @@ static void gen11_dsi_map_pll(struct intel_encoder *encoder,
|
|||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
|
||||
struct intel_shared_dpll *pll = crtc_state->shared_dpll;
|
||||
struct intel_dpll *pll = crtc_state->intel_dpll;
|
||||
enum phy phy;
|
||||
u32 val;
|
||||
|
||||
|
|
|
|||
|
|
@ -272,6 +272,7 @@
|
|||
#define PAYLOAD_PRESENT (1 << 31)
|
||||
#define LP_DATA_TRANSFER (1 << 30)
|
||||
#define VBLANK_FENCE (1 << 29)
|
||||
#define PIPELINE_FLUSH (1 << 28)
|
||||
#define PARAM_WC_MASK (0xffff << 8)
|
||||
#define PARAM_WC_LOWER_SHIFT 8
|
||||
#define PARAM_WC_UPPER_SHIFT 16
|
||||
|
|
|
|||
|
|
@ -26,6 +26,13 @@ bool intel_alpm_aux_less_wake_supported(struct intel_dp *intel_dp)
|
|||
return intel_dp->alpm_dpcd & DP_ALPM_AUX_LESS_CAP;
|
||||
}
|
||||
|
||||
bool intel_alpm_is_alpm_aux_less(struct intel_dp *intel_dp,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
return intel_psr_needs_alpm_aux_less(intel_dp, crtc_state) ||
|
||||
(crtc_state->has_lobf && intel_alpm_aux_less_wake_supported(intel_dp));
|
||||
}
|
||||
|
||||
void intel_alpm_init(struct intel_dp *intel_dp)
|
||||
{
|
||||
u8 dpcd;
|
||||
|
|
@ -329,7 +336,6 @@ static void lnl_alpm_configure(struct intel_dp *intel_dp,
|
|||
{
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
|
||||
enum port port = dp_to_dig_port(intel_dp)->base.port;
|
||||
u32 alpm_ctl;
|
||||
|
||||
if (DISPLAY_VER(display) < 20 || (!intel_psr_needs_alpm(intel_dp, crtc_state) &&
|
||||
|
|
@ -341,30 +347,26 @@ static void lnl_alpm_configure(struct intel_dp *intel_dp,
|
|||
* Panel Replay on eDP is always using ALPM aux less. I.e. no need to
|
||||
* check panel support at this point.
|
||||
*/
|
||||
if ((crtc_state->has_panel_replay && intel_dp_is_edp(intel_dp)) ||
|
||||
(crtc_state->has_lobf && intel_alpm_aux_less_wake_supported(intel_dp))) {
|
||||
if (intel_alpm_is_alpm_aux_less(intel_dp, crtc_state)) {
|
||||
alpm_ctl = ALPM_CTL_ALPM_ENABLE |
|
||||
ALPM_CTL_ALPM_AUX_LESS_ENABLE |
|
||||
ALPM_CTL_AUX_LESS_SLEEP_HOLD_TIME_50_SYMBOLS |
|
||||
ALPM_CTL_AUX_LESS_WAKE_TIME(intel_dp->alpm_parameters.aux_less_wake_lines);
|
||||
|
||||
intel_de_write(display,
|
||||
PORT_ALPM_CTL(port),
|
||||
PORT_ALPM_CTL_ALPM_AUX_LESS_ENABLE |
|
||||
PORT_ALPM_CTL_MAX_PHY_SWING_SETUP(15) |
|
||||
PORT_ALPM_CTL_MAX_PHY_SWING_HOLD(0) |
|
||||
PORT_ALPM_CTL_SILENCE_PERIOD(
|
||||
intel_dp->alpm_parameters.silence_period_sym_clocks));
|
||||
if (intel_dp->as_sdp_supported) {
|
||||
u32 pr_alpm_ctl = PR_ALPM_CTL_ADAPTIVE_SYNC_SDP_POSITION_T1;
|
||||
|
||||
if (intel_dp->pr_dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_CAPABILITY)] &
|
||||
DP_PANEL_REPLAY_LINK_OFF_SUPPORTED_IN_PR_AFTER_ADAPTIVE_SYNC_SDP)
|
||||
pr_alpm_ctl |= PR_ALPM_CTL_ALLOW_LINK_OFF_BETWEEN_AS_SDP_AND_SU;
|
||||
if (!(intel_dp->pr_dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_CAPABILITY)] &
|
||||
DP_PANEL_REPLAY_ASYNC_VIDEO_TIMING_NOT_SUPPORTED_IN_PR))
|
||||
pr_alpm_ctl |= PR_ALPM_CTL_AS_SDP_TRANSMISSION_IN_ACTIVE_DISABLE;
|
||||
|
||||
intel_de_write(display, PR_ALPM_CTL(display, cpu_transcoder),
|
||||
pr_alpm_ctl);
|
||||
}
|
||||
|
||||
intel_de_write(display,
|
||||
PORT_ALPM_LFPS_CTL(port),
|
||||
PORT_ALPM_LFPS_CTL_LFPS_CYCLE_COUNT(10) |
|
||||
PORT_ALPM_LFPS_CTL_LFPS_HALF_CYCLE_DURATION(
|
||||
intel_dp->alpm_parameters.lfps_half_cycle_num_of_syms) |
|
||||
PORT_ALPM_LFPS_CTL_FIRST_LFPS_HALF_CYCLE_DURATION(
|
||||
intel_dp->alpm_parameters.lfps_half_cycle_num_of_syms) |
|
||||
PORT_ALPM_LFPS_CTL_LAST_LFPS_HALF_CYCLE_DURATION(
|
||||
intel_dp->alpm_parameters.lfps_half_cycle_num_of_syms));
|
||||
} else {
|
||||
alpm_ctl = ALPM_CTL_EXTENDED_FAST_WAKE_ENABLE |
|
||||
ALPM_CTL_EXTENDED_FAST_WAKE_TIME(intel_dp->alpm_parameters.fast_wake_lines);
|
||||
|
|
@ -388,6 +390,36 @@ void intel_alpm_configure(struct intel_dp *intel_dp,
|
|||
intel_dp->alpm_parameters.transcoder = crtc_state->cpu_transcoder;
|
||||
}
|
||||
|
||||
void intel_alpm_port_configure(struct intel_dp *intel_dp,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
enum port port = dp_to_dig_port(intel_dp)->base.port;
|
||||
u32 alpm_ctl_val = 0, lfps_ctl_val = 0;
|
||||
|
||||
if (DISPLAY_VER(display) < 20)
|
||||
return;
|
||||
|
||||
if (intel_alpm_is_alpm_aux_less(intel_dp, crtc_state)) {
|
||||
alpm_ctl_val = PORT_ALPM_CTL_ALPM_AUX_LESS_ENABLE |
|
||||
PORT_ALPM_CTL_MAX_PHY_SWING_SETUP(15) |
|
||||
PORT_ALPM_CTL_MAX_PHY_SWING_HOLD(0) |
|
||||
PORT_ALPM_CTL_SILENCE_PERIOD(
|
||||
intel_dp->alpm_parameters.silence_period_sym_clocks);
|
||||
lfps_ctl_val = PORT_ALPM_LFPS_CTL_LFPS_CYCLE_COUNT(10) |
|
||||
PORT_ALPM_LFPS_CTL_LFPS_HALF_CYCLE_DURATION(
|
||||
intel_dp->alpm_parameters.lfps_half_cycle_num_of_syms) |
|
||||
PORT_ALPM_LFPS_CTL_FIRST_LFPS_HALF_CYCLE_DURATION(
|
||||
intel_dp->alpm_parameters.lfps_half_cycle_num_of_syms) |
|
||||
PORT_ALPM_LFPS_CTL_LAST_LFPS_HALF_CYCLE_DURATION(
|
||||
intel_dp->alpm_parameters.lfps_half_cycle_num_of_syms);
|
||||
}
|
||||
|
||||
intel_de_write(display, PORT_ALPM_CTL(port), alpm_ctl_val);
|
||||
|
||||
intel_de_write(display, PORT_ALPM_LFPS_CTL(port), lfps_ctl_val);
|
||||
}
|
||||
|
||||
void intel_alpm_pre_plane_update(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -27,11 +27,15 @@ void intel_alpm_enable_sink(struct intel_dp *intel_dp,
|
|||
const struct intel_crtc_state *crtc_state);
|
||||
void intel_alpm_pre_plane_update(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc);
|
||||
void intel_alpm_port_configure(struct intel_dp *intel_dp,
|
||||
const struct intel_crtc_state *crtc_state);
|
||||
void intel_alpm_post_plane_update(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc);
|
||||
void intel_alpm_lobf_debugfs_add(struct intel_connector *connector);
|
||||
bool intel_alpm_aux_wake_supported(struct intel_dp *intel_dp);
|
||||
bool intel_alpm_aux_less_wake_supported(struct intel_dp *intel_dp);
|
||||
bool intel_alpm_is_alpm_aux_less(struct intel_dp *intel_dp,
|
||||
const struct intel_crtc_state *crtc_state);
|
||||
void intel_alpm_disable(struct intel_dp *intel_dp);
|
||||
bool intel_alpm_get_error(struct intel_dp *intel_dp);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -274,7 +274,7 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
|
|||
crtc_state->do_async_flip = false;
|
||||
crtc_state->fb_bits = 0;
|
||||
crtc_state->update_planes = 0;
|
||||
crtc_state->dsb_color_vblank = NULL;
|
||||
crtc_state->dsb_color = NULL;
|
||||
crtc_state->dsb_commit = NULL;
|
||||
crtc_state->use_dsb = false;
|
||||
|
||||
|
|
@ -310,7 +310,7 @@ intel_crtc_destroy_state(struct drm_crtc *crtc,
|
|||
{
|
||||
struct intel_crtc_state *crtc_state = to_intel_crtc_state(state);
|
||||
|
||||
drm_WARN_ON(crtc->dev, crtc_state->dsb_color_vblank);
|
||||
drm_WARN_ON(crtc->dev, crtc_state->dsb_color);
|
||||
drm_WARN_ON(crtc->dev, crtc_state->dsb_commit);
|
||||
|
||||
__drm_atomic_helper_crtc_destroy_state(&crtc_state->uapi);
|
||||
|
|
|
|||
|
|
@ -42,7 +42,6 @@
|
|||
#include <drm/drm_gem_atomic_helper.h>
|
||||
|
||||
#include "gem/i915_gem_object.h"
|
||||
#include "i915_config.h"
|
||||
#include "i915_scheduler_types.h"
|
||||
#include "i915_vma.h"
|
||||
#include "i9xx_plane_regs.h"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/pwm.h>
|
||||
#include <linux/string_helpers.h>
|
||||
|
||||
#include <acpi/video.h>
|
||||
|
||||
#include <drm/drm_file.h>
|
||||
|
|
@ -19,6 +18,7 @@
|
|||
#include "intel_backlight_regs.h"
|
||||
#include "intel_connector.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_rpm.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dp_aux_backlight.h"
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
#include "i915_drv.h"
|
||||
#include "intel_display.h"
|
||||
#include "intel_display_core.h"
|
||||
#include "intel_display_rpm.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_gmbus.h"
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
#include <drm/drm_atomic_state_helper.h>
|
||||
|
||||
#include "soc/intel_dram.h"
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include "i915_utils.h"
|
||||
|
|
@ -12,10 +14,11 @@
|
|||
#include "intel_bw.h"
|
||||
#include "intel_cdclk.h"
|
||||
#include "intel_display_core.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "skl_watermark.h"
|
||||
#include "intel_mchbar_regs.h"
|
||||
#include "intel_pcode.h"
|
||||
#include "skl_watermark.h"
|
||||
|
||||
/* Parameters for Qclk Geyserville (QGV) */
|
||||
struct intel_qgv_point {
|
||||
|
|
@ -218,11 +221,10 @@ intel_read_qgv_point_info(struct intel_display *display,
|
|||
}
|
||||
|
||||
static int icl_get_qgv_points(struct intel_display *display,
|
||||
const struct dram_info *dram_info,
|
||||
struct intel_qgv_info *qi,
|
||||
bool is_y_tile)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
const struct dram_info *dram_info = &i915->dram_info;
|
||||
int i, ret;
|
||||
|
||||
qi->num_points = dram_info->num_qgv_points;
|
||||
|
|
@ -418,19 +420,20 @@ static const struct intel_sa_info xe3lpd_sa_info = {
|
|||
.derating = 10,
|
||||
};
|
||||
|
||||
static int icl_get_bw_info(struct intel_display *display, const struct intel_sa_info *sa)
|
||||
static int icl_get_bw_info(struct intel_display *display,
|
||||
const struct dram_info *dram_info,
|
||||
const struct intel_sa_info *sa)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
struct intel_qgv_info qi = {};
|
||||
bool is_y_tile = true; /* assume y tile may be used */
|
||||
int num_channels = max_t(u8, 1, i915->dram_info.num_channels);
|
||||
int num_channels = max_t(u8, 1, dram_info->num_channels);
|
||||
int ipqdepth, ipqdepthpch = 16;
|
||||
int dclk_max;
|
||||
int maxdebw;
|
||||
int num_groups = ARRAY_SIZE(display->bw.max);
|
||||
int i, ret;
|
||||
|
||||
ret = icl_get_qgv_points(display, &qi, is_y_tile);
|
||||
ret = icl_get_qgv_points(display, dram_info, &qi, is_y_tile);
|
||||
if (ret) {
|
||||
drm_dbg_kms(display->drm,
|
||||
"Failed to get memory subsystem information, ignoring bandwidth limits");
|
||||
|
|
@ -488,11 +491,11 @@ static int icl_get_bw_info(struct intel_display *display, const struct intel_sa_
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int tgl_get_bw_info(struct intel_display *display, const struct intel_sa_info *sa)
|
||||
static int tgl_get_bw_info(struct intel_display *display,
|
||||
const struct dram_info *dram_info,
|
||||
const struct intel_sa_info *sa)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
struct intel_qgv_info qi = {};
|
||||
const struct dram_info *dram_info = &i915->dram_info;
|
||||
bool is_y_tile = true; /* assume y tile may be used */
|
||||
int num_channels = max_t(u8, 1, dram_info->num_channels);
|
||||
int ipqdepth, ipqdepthpch = 16;
|
||||
|
|
@ -502,7 +505,7 @@ static int tgl_get_bw_info(struct intel_display *display, const struct intel_sa_
|
|||
int num_groups = ARRAY_SIZE(display->bw.max);
|
||||
int i, ret;
|
||||
|
||||
ret = icl_get_qgv_points(display, &qi, is_y_tile);
|
||||
ret = icl_get_qgv_points(display, dram_info, &qi, is_y_tile);
|
||||
if (ret) {
|
||||
drm_dbg_kms(display->drm,
|
||||
"Failed to get memory subsystem information, ignoring bandwidth limits");
|
||||
|
|
@ -632,15 +635,15 @@ static void dg2_get_bw_info(struct intel_display *display)
|
|||
}
|
||||
|
||||
static int xe2_hpd_get_bw_info(struct intel_display *display,
|
||||
const struct dram_info *dram_info,
|
||||
const struct intel_sa_info *sa)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
struct intel_qgv_info qi = {};
|
||||
int num_channels = i915->dram_info.num_channels;
|
||||
int num_channels = dram_info->num_channels;
|
||||
int peakbw, maxdebw;
|
||||
int ret, i;
|
||||
|
||||
ret = icl_get_qgv_points(display, &qi, true);
|
||||
ret = icl_get_qgv_points(display, dram_info, &qi, true);
|
||||
if (ret) {
|
||||
drm_dbg_kms(display->drm,
|
||||
"Failed to get memory subsystem information, ignoring bandwidth limits");
|
||||
|
|
@ -763,32 +766,32 @@ static unsigned int icl_qgv_bw(struct intel_display *display,
|
|||
|
||||
void intel_bw_init_hw(struct intel_display *display)
|
||||
{
|
||||
const struct dram_info *dram_info = &to_i915(display->drm)->dram_info;
|
||||
const struct dram_info *dram_info = intel_dram_info(display->drm);
|
||||
|
||||
if (!HAS_DISPLAY(display))
|
||||
return;
|
||||
|
||||
if (DISPLAY_VER(display) >= 30)
|
||||
tgl_get_bw_info(display, &xe3lpd_sa_info);
|
||||
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, &xe2_hpd_ecc_sa_info);
|
||||
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, &xe2_hpd_sa_info);
|
||||
xe2_hpd_get_bw_info(display, dram_info, &xe2_hpd_sa_info);
|
||||
else if (DISPLAY_VER(display) >= 14)
|
||||
tgl_get_bw_info(display, &mtl_sa_info);
|
||||
tgl_get_bw_info(display, dram_info, &mtl_sa_info);
|
||||
else if (display->platform.dg2)
|
||||
dg2_get_bw_info(display);
|
||||
else if (display->platform.alderlake_p)
|
||||
tgl_get_bw_info(display, &adlp_sa_info);
|
||||
tgl_get_bw_info(display, dram_info, &adlp_sa_info);
|
||||
else if (display->platform.alderlake_s)
|
||||
tgl_get_bw_info(display, &adls_sa_info);
|
||||
tgl_get_bw_info(display, dram_info, &adls_sa_info);
|
||||
else if (display->platform.rocketlake)
|
||||
tgl_get_bw_info(display, &rkl_sa_info);
|
||||
tgl_get_bw_info(display, dram_info, &rkl_sa_info);
|
||||
else if (DISPLAY_VER(display) == 12)
|
||||
tgl_get_bw_info(display, &tgl_sa_info);
|
||||
tgl_get_bw_info(display, dram_info, &tgl_sa_info);
|
||||
else if (DISPLAY_VER(display) == 11)
|
||||
icl_get_bw_info(display, &icl_sa_info);
|
||||
icl_get_bw_info(display, dram_info, &icl_sa_info);
|
||||
}
|
||||
|
||||
static unsigned int intel_bw_crtc_num_active_planes(const struct intel_crtc_state *crtc_state)
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
#include "intel_cdclk.h"
|
||||
#include "intel_crtc.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_mchbar_regs.h"
|
||||
#include "intel_pci_config.h"
|
||||
|
|
@ -567,20 +568,18 @@ static u8 vlv_calc_voltage_level(struct intel_display *display, int cdclk)
|
|||
static void vlv_get_cdclk(struct intel_display *display,
|
||||
struct intel_cdclk_config *cdclk_config)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
u32 val;
|
||||
|
||||
vlv_iosf_sb_get(dev_priv,
|
||||
BIT(VLV_IOSF_SB_CCK) | BIT(VLV_IOSF_SB_PUNIT));
|
||||
vlv_iosf_sb_get(display->drm, BIT(VLV_IOSF_SB_CCK) | BIT(VLV_IOSF_SB_PUNIT));
|
||||
|
||||
cdclk_config->vco = vlv_get_hpll_vco(dev_priv);
|
||||
cdclk_config->cdclk = vlv_get_cck_clock(dev_priv, "cdclk",
|
||||
cdclk_config->vco = vlv_get_hpll_vco(display->drm);
|
||||
cdclk_config->cdclk = vlv_get_cck_clock(display->drm, "cdclk",
|
||||
CCK_DISPLAY_CLOCK_CONTROL,
|
||||
cdclk_config->vco);
|
||||
|
||||
val = vlv_punit_read(dev_priv, PUNIT_REG_DSPSSPM);
|
||||
val = vlv_punit_read(display->drm, PUNIT_REG_DSPSSPM);
|
||||
|
||||
vlv_iosf_sb_put(dev_priv,
|
||||
vlv_iosf_sb_put(display->drm,
|
||||
BIT(VLV_IOSF_SB_CCK) | BIT(VLV_IOSF_SB_PUNIT));
|
||||
|
||||
if (display->platform.valleyview)
|
||||
|
|
@ -658,16 +657,16 @@ static void vlv_set_cdclk(struct intel_display *display,
|
|||
*/
|
||||
wakeref = intel_display_power_get(display, POWER_DOMAIN_DISPLAY_CORE);
|
||||
|
||||
vlv_iosf_sb_get(dev_priv,
|
||||
vlv_iosf_sb_get(display->drm,
|
||||
BIT(VLV_IOSF_SB_CCK) |
|
||||
BIT(VLV_IOSF_SB_BUNIT) |
|
||||
BIT(VLV_IOSF_SB_PUNIT));
|
||||
|
||||
val = vlv_punit_read(dev_priv, PUNIT_REG_DSPSSPM);
|
||||
val = vlv_punit_read(display->drm, PUNIT_REG_DSPSSPM);
|
||||
val &= ~DSPFREQGUAR_MASK;
|
||||
val |= (cmd << DSPFREQGUAR_SHIFT);
|
||||
vlv_punit_write(dev_priv, PUNIT_REG_DSPSSPM, val);
|
||||
if (wait_for((vlv_punit_read(dev_priv, PUNIT_REG_DSPSSPM) &
|
||||
vlv_punit_write(display->drm, PUNIT_REG_DSPSSPM, val);
|
||||
if (wait_for((vlv_punit_read(display->drm, PUNIT_REG_DSPSSPM) &
|
||||
DSPFREQSTAT_MASK) == (cmd << DSPFREQSTAT_SHIFT),
|
||||
50)) {
|
||||
drm_err(display->drm,
|
||||
|
|
@ -681,12 +680,12 @@ static void vlv_set_cdclk(struct intel_display *display,
|
|||
cdclk) - 1;
|
||||
|
||||
/* adjust cdclk divider */
|
||||
val = vlv_cck_read(dev_priv, CCK_DISPLAY_CLOCK_CONTROL);
|
||||
val = vlv_cck_read(display->drm, CCK_DISPLAY_CLOCK_CONTROL);
|
||||
val &= ~CCK_FREQUENCY_VALUES;
|
||||
val |= divider;
|
||||
vlv_cck_write(dev_priv, CCK_DISPLAY_CLOCK_CONTROL, val);
|
||||
vlv_cck_write(display->drm, CCK_DISPLAY_CLOCK_CONTROL, val);
|
||||
|
||||
if (wait_for((vlv_cck_read(dev_priv, CCK_DISPLAY_CLOCK_CONTROL) &
|
||||
if (wait_for((vlv_cck_read(display->drm, CCK_DISPLAY_CLOCK_CONTROL) &
|
||||
CCK_FREQUENCY_STATUS) == (divider << CCK_FREQUENCY_STATUS_SHIFT),
|
||||
50))
|
||||
drm_err(display->drm,
|
||||
|
|
@ -694,7 +693,7 @@ static void vlv_set_cdclk(struct intel_display *display,
|
|||
}
|
||||
|
||||
/* adjust self-refresh exit latency value */
|
||||
val = vlv_bunit_read(dev_priv, BUNIT_REG_BISOC);
|
||||
val = vlv_bunit_read(display->drm, BUNIT_REG_BISOC);
|
||||
val &= ~0x7f;
|
||||
|
||||
/*
|
||||
|
|
@ -705,9 +704,9 @@ static void vlv_set_cdclk(struct intel_display *display,
|
|||
val |= 4500 / 250; /* 4.5 usec */
|
||||
else
|
||||
val |= 3000 / 250; /* 3.0 usec */
|
||||
vlv_bunit_write(dev_priv, BUNIT_REG_BISOC, val);
|
||||
vlv_bunit_write(display->drm, BUNIT_REG_BISOC, val);
|
||||
|
||||
vlv_iosf_sb_put(dev_priv,
|
||||
vlv_iosf_sb_put(display->drm,
|
||||
BIT(VLV_IOSF_SB_CCK) |
|
||||
BIT(VLV_IOSF_SB_BUNIT) |
|
||||
BIT(VLV_IOSF_SB_PUNIT));
|
||||
|
|
@ -723,7 +722,6 @@ static void chv_set_cdclk(struct intel_display *display,
|
|||
const struct intel_cdclk_config *cdclk_config,
|
||||
enum pipe pipe)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
int cdclk = cdclk_config->cdclk;
|
||||
u32 val, cmd = cdclk_config->voltage_level;
|
||||
intel_wakeref_t wakeref;
|
||||
|
|
@ -747,19 +745,19 @@ static void chv_set_cdclk(struct intel_display *display,
|
|||
*/
|
||||
wakeref = intel_display_power_get(display, POWER_DOMAIN_DISPLAY_CORE);
|
||||
|
||||
vlv_punit_get(dev_priv);
|
||||
val = vlv_punit_read(dev_priv, PUNIT_REG_DSPSSPM);
|
||||
vlv_punit_get(display->drm);
|
||||
val = vlv_punit_read(display->drm, PUNIT_REG_DSPSSPM);
|
||||
val &= ~DSPFREQGUAR_MASK_CHV;
|
||||
val |= (cmd << DSPFREQGUAR_SHIFT_CHV);
|
||||
vlv_punit_write(dev_priv, PUNIT_REG_DSPSSPM, val);
|
||||
if (wait_for((vlv_punit_read(dev_priv, PUNIT_REG_DSPSSPM) &
|
||||
vlv_punit_write(display->drm, PUNIT_REG_DSPSSPM, val);
|
||||
if (wait_for((vlv_punit_read(display->drm, PUNIT_REG_DSPSSPM) &
|
||||
DSPFREQSTAT_MASK_CHV) == (cmd << DSPFREQSTAT_SHIFT_CHV),
|
||||
50)) {
|
||||
drm_err(display->drm,
|
||||
"timed out waiting for CDclk change\n");
|
||||
}
|
||||
|
||||
vlv_punit_put(dev_priv);
|
||||
vlv_punit_put(display->drm);
|
||||
|
||||
intel_update_cdclk(display);
|
||||
|
||||
|
|
@ -3528,10 +3526,8 @@ static int pch_rawclk(struct intel_display *display)
|
|||
|
||||
static int vlv_hrawclk(struct intel_display *display)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
|
||||
/* RAWCLK_FREQ_VLV register updated from power well code */
|
||||
return vlv_get_cck_clock_hpll(dev_priv, "hrawclk",
|
||||
return vlv_get_cck_clock_hpll(display->drm, "hrawclk",
|
||||
CCK_DISPLAY_REF_CLOCK_CONTROL);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,13 +9,13 @@
|
|||
#include <drm/drm_device.h>
|
||||
#include <drm/drm_print.h>
|
||||
|
||||
#include "i915_reg.h"
|
||||
#include "intel_crtc.h"
|
||||
#include "intel_cmtg.h"
|
||||
#include "intel_cmtg_regs.h"
|
||||
#include "intel_crtc.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_device.h"
|
||||
#include "intel_display_power.h"
|
||||
#include "intel_display_regs.h"
|
||||
|
||||
/**
|
||||
* DOC: Common Primary Timing Generator (CMTG)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
#ifndef __INTEL_CMTG_REGS_H__
|
||||
#define __INTEL_CMTG_REGS_H__
|
||||
|
||||
#include "i915_reg_defs.h"
|
||||
#include "intel_display_reg_defs.h"
|
||||
|
||||
#define CMTG_CLK_SEL _MMIO(0x46160)
|
||||
#define CMTG_CLK_SEL_A_MASK REG_GENMASK(31, 29)
|
||||
|
|
|
|||
|
|
@ -1339,8 +1339,8 @@ static void ilk_lut_write(const struct intel_crtc_state *crtc_state,
|
|||
{
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
|
||||
if (crtc_state->dsb_color_vblank)
|
||||
intel_dsb_reg_write(crtc_state->dsb_color_vblank, reg, val);
|
||||
if (crtc_state->dsb_color)
|
||||
intel_dsb_reg_write(crtc_state->dsb_color, reg, val);
|
||||
else
|
||||
intel_de_write_fw(display, reg, val);
|
||||
}
|
||||
|
|
@ -1350,8 +1350,8 @@ static void ilk_lut_write_indexed(const struct intel_crtc_state *crtc_state,
|
|||
{
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
|
||||
if (crtc_state->dsb_color_vblank)
|
||||
intel_dsb_reg_write_indexed(crtc_state->dsb_color_vblank, reg, val);
|
||||
if (crtc_state->dsb_color)
|
||||
intel_dsb_reg_write_indexed(crtc_state->dsb_color, reg, val);
|
||||
else
|
||||
intel_de_write_fw(display, reg, val);
|
||||
}
|
||||
|
|
@ -1389,7 +1389,7 @@ static void ilk_load_lut_8(const struct intel_crtc_state *crtc_state,
|
|||
for (i = 0; i < 256; i++) {
|
||||
ilk_lut_write(crtc_state, LGC_PALETTE(pipe, i),
|
||||
i9xx_lut_8(&lut[i]));
|
||||
if (crtc_state->dsb_color_vblank)
|
||||
if (crtc_state->dsb_color)
|
||||
ilk_lut_write(crtc_state, LGC_PALETTE(pipe, i),
|
||||
i9xx_lut_8(&lut[i]));
|
||||
}
|
||||
|
|
@ -1917,7 +1917,7 @@ void intel_color_load_luts(const struct intel_crtc_state *crtc_state)
|
|||
{
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
|
||||
if (crtc_state->dsb_color_vblank)
|
||||
if (crtc_state->dsb_color)
|
||||
return;
|
||||
|
||||
display->funcs.color->load_luts(crtc_state);
|
||||
|
|
@ -1965,6 +1965,25 @@ void intel_color_modeset(const struct intel_crtc_state *crtc_state)
|
|||
}
|
||||
}
|
||||
|
||||
bool intel_color_uses_dsb(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
return crtc_state->dsb_color;
|
||||
}
|
||||
|
||||
bool intel_color_uses_chained_dsb(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
|
||||
return crtc_state->dsb_color && !HAS_DOUBLE_BUFFERED_LUT(display);
|
||||
}
|
||||
|
||||
bool intel_color_uses_gosub_dsb(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
|
||||
return crtc_state->dsb_color && HAS_DOUBLE_BUFFERED_LUT(display);
|
||||
}
|
||||
|
||||
void intel_color_prepare_commit(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
|
|
@ -1982,47 +2001,53 @@ void intel_color_prepare_commit(struct intel_atomic_state *state,
|
|||
if (!crtc_state->pre_csc_lut && !crtc_state->post_csc_lut)
|
||||
return;
|
||||
|
||||
crtc_state->dsb_color_vblank = intel_dsb_prepare(state, crtc, INTEL_DSB_1, 1024);
|
||||
if (!crtc_state->dsb_color_vblank)
|
||||
if (HAS_DOUBLE_BUFFERED_LUT(display))
|
||||
crtc_state->dsb_color = intel_dsb_prepare(state, crtc, INTEL_DSB_0, 1024);
|
||||
else
|
||||
crtc_state->dsb_color = intel_dsb_prepare(state, crtc, INTEL_DSB_1, 1024);
|
||||
|
||||
if (!intel_color_uses_dsb(crtc_state))
|
||||
return;
|
||||
|
||||
display->funcs.color->load_luts(crtc_state);
|
||||
|
||||
if (crtc_state->use_dsb) {
|
||||
intel_vrr_send_push(crtc_state->dsb_color_vblank, crtc_state);
|
||||
intel_dsb_wait_vblank_delay(state, crtc_state->dsb_color_vblank);
|
||||
intel_vrr_check_push_sent(crtc_state->dsb_color_vblank, crtc_state);
|
||||
intel_dsb_interrupt(crtc_state->dsb_color_vblank);
|
||||
if (crtc_state->use_dsb && intel_color_uses_chained_dsb(crtc_state)) {
|
||||
intel_vrr_send_push(crtc_state->dsb_color, crtc_state);
|
||||
intel_dsb_wait_vblank_delay(state, crtc_state->dsb_color);
|
||||
intel_vrr_check_push_sent(crtc_state->dsb_color, crtc_state);
|
||||
intel_dsb_interrupt(crtc_state->dsb_color);
|
||||
}
|
||||
|
||||
intel_dsb_finish(crtc_state->dsb_color_vblank);
|
||||
if (intel_color_uses_gosub_dsb(crtc_state))
|
||||
intel_dsb_gosub_finish(crtc_state->dsb_color);
|
||||
else
|
||||
intel_dsb_finish(crtc_state->dsb_color);
|
||||
}
|
||||
|
||||
void intel_color_cleanup_commit(struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
if (crtc_state->dsb_color_vblank) {
|
||||
intel_dsb_cleanup(crtc_state->dsb_color_vblank);
|
||||
crtc_state->dsb_color_vblank = NULL;
|
||||
if (crtc_state->dsb_color) {
|
||||
intel_dsb_cleanup(crtc_state->dsb_color);
|
||||
crtc_state->dsb_color = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void intel_color_wait_commit(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
if (crtc_state->dsb_color_vblank)
|
||||
intel_dsb_wait(crtc_state->dsb_color_vblank);
|
||||
}
|
||||
|
||||
bool intel_color_uses_dsb(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
return crtc_state->dsb_color_vblank;
|
||||
if (crtc_state->dsb_color)
|
||||
intel_dsb_wait(crtc_state->dsb_color);
|
||||
}
|
||||
|
||||
static bool intel_can_preload_luts(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(state);
|
||||
const struct intel_crtc_state *old_crtc_state =
|
||||
intel_atomic_get_old_crtc_state(state, crtc);
|
||||
|
||||
if (HAS_DOUBLE_BUFFERED_LUT(display))
|
||||
return false;
|
||||
|
||||
return !old_crtc_state->post_csc_lut &&
|
||||
!old_crtc_state->pre_csc_lut;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ void intel_color_prepare_commit(struct intel_atomic_state *state,
|
|||
struct intel_crtc *crtc);
|
||||
void intel_color_cleanup_commit(struct intel_crtc_state *crtc_state);
|
||||
bool intel_color_uses_dsb(const struct intel_crtc_state *crtc_state);
|
||||
bool intel_color_uses_chained_dsb(const struct intel_crtc_state *crtc_state);
|
||||
bool intel_color_uses_gosub_dsb(const struct intel_crtc_state *crtc_state);
|
||||
void intel_color_wait_commit(const struct intel_crtc_state *crtc_state);
|
||||
void intel_color_commit_noarm(struct intel_dsb *dsb,
|
||||
const struct intel_crtc_state *crtc_state);
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@
|
|||
|
||||
#include <drm/drm_print.h>
|
||||
|
||||
#include "i915_reg.h"
|
||||
#include "i915_utils.h"
|
||||
#include "intel_combo_phy.h"
|
||||
#include "intel_combo_phy_regs.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_types.h"
|
||||
|
||||
#define for_each_combo_phy(__display, __phy) \
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
#ifndef __INTEL_COMBO_PHY_REGS__
|
||||
#define __INTEL_COMBO_PHY_REGS__
|
||||
|
||||
#include "i915_reg_defs.h"
|
||||
#include "intel_display_reg_defs.h"
|
||||
|
||||
#define _ICL_COMBOPHY_A 0x162000
|
||||
#define _ICL_COMBOPHY_B 0x6C000
|
||||
|
|
|
|||
|
|
@ -208,8 +208,7 @@ enum pipe intel_connector_get_pipe(struct intel_connector *connector)
|
|||
{
|
||||
struct intel_display *display = to_intel_display(connector);
|
||||
|
||||
drm_WARN_ON(display->drm,
|
||||
!drm_modeset_is_locked(&display->drm->mode_config.connection_mutex));
|
||||
drm_modeset_lock_assert_held(&display->drm->mode_config.connection_mutex);
|
||||
|
||||
if (!connector->base.state->crtc)
|
||||
return INVALID_PIPE;
|
||||
|
|
|
|||
|
|
@ -34,8 +34,6 @@
|
|||
#include <drm/drm_print.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
|
||||
#include "i915_irq.h"
|
||||
#include "i915_reg.h"
|
||||
#include "intel_connector.h"
|
||||
#include "intel_crt.h"
|
||||
#include "intel_crt_regs.h"
|
||||
|
|
@ -44,6 +42,7 @@
|
|||
#include "intel_ddi_buf_trans.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_driver.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_fdi.h"
|
||||
#include "intel_fdi_regs.h"
|
||||
|
|
|
|||
|
|
@ -417,10 +417,13 @@ int intel_crtc_get_pipe_from_crtc_id_ioctl(struct drm_device *dev, void *data,
|
|||
|
||||
static bool intel_crtc_needs_vblank_work(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
|
||||
return crtc_state->hw.active &&
|
||||
!crtc_state->preload_luts &&
|
||||
!intel_crtc_needs_modeset(crtc_state) &&
|
||||
intel_crtc_needs_color_update(crtc_state) &&
|
||||
(intel_crtc_needs_color_update(crtc_state) &&
|
||||
!HAS_DOUBLE_BUFFERED_LUT(display)) &&
|
||||
!intel_color_uses_dsb(crtc_state) &&
|
||||
!crtc_state->use_dsb;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@
|
|||
#include <drm/drm_print.h>
|
||||
#include <drm/drm_vblank.h>
|
||||
|
||||
#include "i915_reg.h"
|
||||
#include "i915_utils.h"
|
||||
#include "intel_atomic.h"
|
||||
#include "intel_atomic_plane.h"
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@
|
|||
|
||||
#include <drm/drm_print.h>
|
||||
|
||||
#include "i915_reg.h"
|
||||
#include "i915_utils.h"
|
||||
#include "intel_alpm.h"
|
||||
#include "intel_cx0_phy.h"
|
||||
#include "intel_cx0_phy_regs.h"
|
||||
#include "intel_ddi.h"
|
||||
|
|
@ -3224,6 +3224,37 @@ void intel_mtl_pll_enable(struct intel_encoder *encoder,
|
|||
intel_cx0pll_enable(encoder, crtc_state);
|
||||
}
|
||||
|
||||
/*
|
||||
* According to HAS we need to enable MAC Transmitting LFPS in the "PHY Common
|
||||
* Control 0" PIPE register in case of AUX Less ALPM is going to be used. This
|
||||
* function is doing that and is called by link retrain sequence.
|
||||
*/
|
||||
void intel_lnl_mac_transmit_lfps(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
u8 owned_lane_mask = intel_cx0_get_owned_lane_mask(encoder);
|
||||
bool enable = intel_alpm_is_alpm_aux_less(enc_to_intel_dp(encoder),
|
||||
crtc_state);
|
||||
int i;
|
||||
|
||||
if (DISPLAY_VER(display) < 20)
|
||||
return;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
int tx = i % 2 + 1;
|
||||
u8 lane_mask = i < 2 ? INTEL_CX0_LANE0 : INTEL_CX0_LANE1;
|
||||
|
||||
if (!(owned_lane_mask & lane_mask))
|
||||
continue;
|
||||
|
||||
intel_cx0_rmw(encoder, lane_mask, PHY_CMN1_CONTROL(tx, 0),
|
||||
CONTROL0_MAC_TRANSMIT_LFPS,
|
||||
enable ? CONTROL0_MAC_TRANSMIT_LFPS : 0,
|
||||
MB_WRITE_COMMITTED);
|
||||
}
|
||||
}
|
||||
|
||||
static u8 cx0_power_control_disable_val(struct intel_encoder *encoder)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
|
|
|
|||
|
|
@ -43,5 +43,7 @@ void intel_cx0_phy_set_signal_levels(struct intel_encoder *encoder,
|
|||
const struct intel_crtc_state *crtc_state);
|
||||
int intel_mtl_tbt_calc_port_clock(struct intel_encoder *encoder);
|
||||
void intel_cx0_pll_power_save_wa(struct intel_display *display);
|
||||
void intel_lnl_mac_transmit_lfps(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state);
|
||||
|
||||
#endif /* __INTEL_CX0_PHY_H__ */
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@
|
|||
#ifndef __INTEL_CX0_PHY_REGS_H__
|
||||
#define __INTEL_CX0_PHY_REGS_H__
|
||||
|
||||
#include "i915_reg_defs.h"
|
||||
#include "intel_display_limits.h"
|
||||
#include "intel_display_reg_defs.h"
|
||||
|
||||
/* DDI Buffer Control */
|
||||
#define _DDI_CLK_VALFREQ_A 0x64030
|
||||
|
|
@ -285,6 +285,9 @@
|
|||
#define PHY_CX0_TX_CONTROL(tx, control) (0x400 + ((tx) - 1) * 0x200 + (control))
|
||||
#define CONTROL2_DISABLE_SINGLE_TX REG_BIT(6)
|
||||
|
||||
#define PHY_CMN1_CONTROL(tx, control) (0x800 + ((tx) - 1) * 0x200 + (control))
|
||||
#define CONTROL0_MAC_TRANSMIT_LFPS REG_BIT(1)
|
||||
|
||||
/* C20 Registers */
|
||||
#define PHY_C20_WR_ADDRESS_L 0xC02
|
||||
#define PHY_C20_WR_ADDRESS_H 0xC03
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@
|
|||
#include "intel_ddi_buf_trans.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_power.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dkl_phy.h"
|
||||
#include "intel_dkl_phy_regs.h"
|
||||
|
|
@ -236,7 +237,7 @@ static void intel_wait_ddi_buf_active(struct intel_encoder *encoder)
|
|||
port_name(port));
|
||||
}
|
||||
|
||||
static u32 hsw_pll_to_ddi_pll_sel(const struct intel_shared_dpll *pll)
|
||||
static u32 hsw_pll_to_ddi_pll_sel(const struct intel_dpll *pll)
|
||||
{
|
||||
switch (pll->info->id) {
|
||||
case DPLL_ID_WRPLL1:
|
||||
|
|
@ -260,7 +261,7 @@ static u32 hsw_pll_to_ddi_pll_sel(const struct intel_shared_dpll *pll)
|
|||
static u32 icl_pll_to_ddi_clk_sel(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
const struct intel_shared_dpll *pll = crtc_state->shared_dpll;
|
||||
const struct intel_dpll *pll = crtc_state->intel_dpll;
|
||||
int clock = crtc_state->port_clock;
|
||||
const enum intel_dpll_id id = pll->info->id;
|
||||
|
||||
|
|
@ -1561,7 +1562,7 @@ static bool _icl_ddi_is_clock_enabled(struct intel_display *display, i915_reg_t
|
|||
return !(intel_de_read(display, reg) & clk_off);
|
||||
}
|
||||
|
||||
static struct intel_shared_dpll *
|
||||
static struct intel_dpll *
|
||||
_icl_ddi_get_pll(struct intel_display *display, i915_reg_t reg,
|
||||
u32 clk_sel_mask, u32 clk_sel_shift)
|
||||
{
|
||||
|
|
@ -1569,14 +1570,14 @@ _icl_ddi_get_pll(struct intel_display *display, i915_reg_t reg,
|
|||
|
||||
id = (intel_de_read(display, reg) & clk_sel_mask) >> clk_sel_shift;
|
||||
|
||||
return intel_get_shared_dpll_by_id(display, id);
|
||||
return intel_get_dpll_by_id(display, id);
|
||||
}
|
||||
|
||||
static void adls_ddi_enable_clock(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
const struct intel_shared_dpll *pll = crtc_state->shared_dpll;
|
||||
const struct intel_dpll *pll = crtc_state->intel_dpll;
|
||||
enum phy phy = intel_encoder_to_phy(encoder);
|
||||
|
||||
if (drm_WARN_ON(display->drm, !pll))
|
||||
|
|
@ -1606,7 +1607,7 @@ static bool adls_ddi_is_clock_enabled(struct intel_encoder *encoder)
|
|||
ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy));
|
||||
}
|
||||
|
||||
static struct intel_shared_dpll *adls_ddi_get_pll(struct intel_encoder *encoder)
|
||||
static struct intel_dpll *adls_ddi_get_pll(struct intel_encoder *encoder)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
enum phy phy = intel_encoder_to_phy(encoder);
|
||||
|
|
@ -1620,7 +1621,7 @@ static void rkl_ddi_enable_clock(struct intel_encoder *encoder,
|
|||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
const struct intel_shared_dpll *pll = crtc_state->shared_dpll;
|
||||
const struct intel_dpll *pll = crtc_state->intel_dpll;
|
||||
enum phy phy = intel_encoder_to_phy(encoder);
|
||||
|
||||
if (drm_WARN_ON(display->drm, !pll))
|
||||
|
|
@ -1650,7 +1651,7 @@ static bool rkl_ddi_is_clock_enabled(struct intel_encoder *encoder)
|
|||
RKL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy));
|
||||
}
|
||||
|
||||
static struct intel_shared_dpll *rkl_ddi_get_pll(struct intel_encoder *encoder)
|
||||
static struct intel_dpll *rkl_ddi_get_pll(struct intel_encoder *encoder)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
enum phy phy = intel_encoder_to_phy(encoder);
|
||||
|
|
@ -1664,7 +1665,7 @@ static void dg1_ddi_enable_clock(struct intel_encoder *encoder,
|
|||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
const struct intel_shared_dpll *pll = crtc_state->shared_dpll;
|
||||
const struct intel_dpll *pll = crtc_state->intel_dpll;
|
||||
enum phy phy = intel_encoder_to_phy(encoder);
|
||||
|
||||
if (drm_WARN_ON(display->drm, !pll))
|
||||
|
|
@ -1703,7 +1704,7 @@ static bool dg1_ddi_is_clock_enabled(struct intel_encoder *encoder)
|
|||
DG1_DPCLKA_CFGCR0_DDI_CLK_OFF(phy));
|
||||
}
|
||||
|
||||
static struct intel_shared_dpll *dg1_ddi_get_pll(struct intel_encoder *encoder)
|
||||
static struct intel_dpll *dg1_ddi_get_pll(struct intel_encoder *encoder)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
enum phy phy = intel_encoder_to_phy(encoder);
|
||||
|
|
@ -1723,14 +1724,14 @@ static struct intel_shared_dpll *dg1_ddi_get_pll(struct intel_encoder *encoder)
|
|||
if (phy >= PHY_C)
|
||||
id += DPLL_ID_DG1_DPLL2;
|
||||
|
||||
return intel_get_shared_dpll_by_id(display, id);
|
||||
return intel_get_dpll_by_id(display, id);
|
||||
}
|
||||
|
||||
static void icl_ddi_combo_enable_clock(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
const struct intel_shared_dpll *pll = crtc_state->shared_dpll;
|
||||
const struct intel_dpll *pll = crtc_state->intel_dpll;
|
||||
enum phy phy = intel_encoder_to_phy(encoder);
|
||||
|
||||
if (drm_WARN_ON(display->drm, !pll))
|
||||
|
|
@ -1760,7 +1761,7 @@ static bool icl_ddi_combo_is_clock_enabled(struct intel_encoder *encoder)
|
|||
ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy));
|
||||
}
|
||||
|
||||
struct intel_shared_dpll *icl_ddi_combo_get_pll(struct intel_encoder *encoder)
|
||||
struct intel_dpll *icl_ddi_combo_get_pll(struct intel_encoder *encoder)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
enum phy phy = intel_encoder_to_phy(encoder);
|
||||
|
|
@ -1774,7 +1775,7 @@ static void jsl_ddi_tc_enable_clock(struct intel_encoder *encoder,
|
|||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
const struct intel_shared_dpll *pll = crtc_state->shared_dpll;
|
||||
const struct intel_dpll *pll = crtc_state->intel_dpll;
|
||||
enum port port = encoder->port;
|
||||
|
||||
if (drm_WARN_ON(display->drm, !pll))
|
||||
|
|
@ -1817,7 +1818,7 @@ static void icl_ddi_tc_enable_clock(struct intel_encoder *encoder,
|
|||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
const struct intel_shared_dpll *pll = crtc_state->shared_dpll;
|
||||
const struct intel_dpll *pll = crtc_state->intel_dpll;
|
||||
enum tc_port tc_port = intel_encoder_to_tc(encoder);
|
||||
enum port port = encoder->port;
|
||||
|
||||
|
|
@ -1868,7 +1869,7 @@ static bool icl_ddi_tc_is_clock_enabled(struct intel_encoder *encoder)
|
|||
return !(tmp & ICL_DPCLKA_CFGCR0_TC_CLK_OFF(tc_port));
|
||||
}
|
||||
|
||||
static struct intel_shared_dpll *icl_ddi_tc_get_pll(struct intel_encoder *encoder)
|
||||
static struct intel_dpll *icl_ddi_tc_get_pll(struct intel_encoder *encoder)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
enum tc_port tc_port = intel_encoder_to_tc(encoder);
|
||||
|
|
@ -1895,10 +1896,10 @@ static struct intel_shared_dpll *icl_ddi_tc_get_pll(struct intel_encoder *encode
|
|||
return NULL;
|
||||
}
|
||||
|
||||
return intel_get_shared_dpll_by_id(display, id);
|
||||
return intel_get_dpll_by_id(display, id);
|
||||
}
|
||||
|
||||
static struct intel_shared_dpll *bxt_ddi_get_pll(struct intel_encoder *encoder)
|
||||
static struct intel_dpll *bxt_ddi_get_pll(struct intel_encoder *encoder)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder->base.dev);
|
||||
enum intel_dpll_id id;
|
||||
|
|
@ -1918,14 +1919,14 @@ static struct intel_shared_dpll *bxt_ddi_get_pll(struct intel_encoder *encoder)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
return intel_get_shared_dpll_by_id(display, id);
|
||||
return intel_get_dpll_by_id(display, id);
|
||||
}
|
||||
|
||||
static void skl_ddi_enable_clock(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
const struct intel_shared_dpll *pll = crtc_state->shared_dpll;
|
||||
const struct intel_dpll *pll = crtc_state->intel_dpll;
|
||||
enum port port = encoder->port;
|
||||
|
||||
if (drm_WARN_ON(display->drm, !pll))
|
||||
|
|
@ -1967,7 +1968,7 @@ static bool skl_ddi_is_clock_enabled(struct intel_encoder *encoder)
|
|||
return !(intel_de_read(display, DPLL_CTRL2) & DPLL_CTRL2_DDI_CLK_OFF(port));
|
||||
}
|
||||
|
||||
static struct intel_shared_dpll *skl_ddi_get_pll(struct intel_encoder *encoder)
|
||||
static struct intel_dpll *skl_ddi_get_pll(struct intel_encoder *encoder)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
enum port port = encoder->port;
|
||||
|
|
@ -1986,14 +1987,14 @@ static struct intel_shared_dpll *skl_ddi_get_pll(struct intel_encoder *encoder)
|
|||
id = (tmp & DPLL_CTRL2_DDI_CLK_SEL_MASK(port)) >>
|
||||
DPLL_CTRL2_DDI_CLK_SEL_SHIFT(port);
|
||||
|
||||
return intel_get_shared_dpll_by_id(display, id);
|
||||
return intel_get_dpll_by_id(display, id);
|
||||
}
|
||||
|
||||
void hsw_ddi_enable_clock(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
const struct intel_shared_dpll *pll = crtc_state->shared_dpll;
|
||||
const struct intel_dpll *pll = crtc_state->intel_dpll;
|
||||
enum port port = encoder->port;
|
||||
|
||||
if (drm_WARN_ON(display->drm, !pll))
|
||||
|
|
@ -2018,7 +2019,7 @@ bool hsw_ddi_is_clock_enabled(struct intel_encoder *encoder)
|
|||
return intel_de_read(display, PORT_CLK_SEL(port)) != PORT_CLK_SEL_NONE;
|
||||
}
|
||||
|
||||
static struct intel_shared_dpll *hsw_ddi_get_pll(struct intel_encoder *encoder)
|
||||
static struct intel_dpll *hsw_ddi_get_pll(struct intel_encoder *encoder)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
enum port port = encoder->port;
|
||||
|
|
@ -2053,7 +2054,7 @@ static struct intel_shared_dpll *hsw_ddi_get_pll(struct intel_encoder *encoder)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
return intel_get_shared_dpll_by_id(display, id);
|
||||
return intel_get_dpll_by_id(display, id);
|
||||
}
|
||||
|
||||
void intel_ddi_enable_clock(struct intel_encoder *encoder,
|
||||
|
|
@ -2760,7 +2761,7 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
|
|||
* 4. Enable the port PLL.
|
||||
*
|
||||
* The PLL enabling itself was already done before this function by
|
||||
* hsw_crtc_enable()->intel_enable_shared_dpll(). We need only
|
||||
* hsw_crtc_enable()->intel_enable_dpll(). We need only
|
||||
* configure the PLL to port mapping here.
|
||||
*/
|
||||
intel_ddi_enable_clock(encoder, crtc_state);
|
||||
|
|
@ -3647,7 +3648,7 @@ void intel_ddi_update_active_dpll(struct intel_atomic_state *state,
|
|||
|
||||
for_each_intel_crtc_in_pipe_mask(display->drm, pipe_crtc,
|
||||
intel_crtc_joined_pipe_mask(crtc_state))
|
||||
intel_update_active_dpll(state, pipe_crtc, encoder);
|
||||
intel_dpll_update_active(state, pipe_crtc, encoder);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -3740,6 +3741,18 @@ static void mtl_ddi_prepare_link_retrain(struct intel_dp *intel_dp,
|
|||
|
||||
intel_ddi_buf_enable(encoder, intel_dp->DP);
|
||||
intel_dp->DP |= DDI_BUF_CTL_ENABLE;
|
||||
|
||||
/*
|
||||
* 6.k If AUX-Less ALPM is going to be enabled:
|
||||
* i. Configure PORT_ALPM_CTL and PORT_ALPM_LFPS_CTL here
|
||||
*/
|
||||
intel_alpm_port_configure(intel_dp, crtc_state);
|
||||
|
||||
/*
|
||||
* ii. Enable MAC Transmits LFPS in the "PHY Common Control 0" PIPE
|
||||
* register
|
||||
*/
|
||||
intel_lnl_mac_transmit_lfps(encoder, crtc_state);
|
||||
}
|
||||
|
||||
static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp,
|
||||
|
|
@ -4184,7 +4197,7 @@ static void intel_ddi_get_config(struct intel_encoder *encoder,
|
|||
|
||||
void intel_ddi_get_clock(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *crtc_state,
|
||||
struct intel_shared_dpll *pll)
|
||||
struct intel_dpll *pll)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
enum icl_port_dpll_id port_dpll_id = ICL_PORT_DPLL_DEFAULT;
|
||||
|
|
@ -4200,7 +4213,7 @@ void intel_ddi_get_clock(struct intel_encoder *encoder,
|
|||
|
||||
icl_set_active_port_dpll(crtc_state, port_dpll_id);
|
||||
|
||||
crtc_state->port_clock = intel_dpll_get_freq(display, crtc_state->shared_dpll,
|
||||
crtc_state->port_clock = intel_dpll_get_freq(display, crtc_state->intel_dpll,
|
||||
&crtc_state->dpll_hw_state);
|
||||
}
|
||||
|
||||
|
|
@ -4254,7 +4267,7 @@ static void icl_ddi_combo_get_config(struct intel_encoder *encoder,
|
|||
intel_ddi_get_config(encoder, crtc_state);
|
||||
}
|
||||
|
||||
static bool icl_ddi_tc_pll_is_tbt(const struct intel_shared_dpll *pll)
|
||||
static bool icl_ddi_tc_pll_is_tbt(const struct intel_dpll *pll)
|
||||
{
|
||||
return pll->info->id == DPLL_ID_ICL_TBTPLL;
|
||||
}
|
||||
|
|
@ -4264,7 +4277,7 @@ icl_ddi_tc_port_pll_type(struct intel_encoder *encoder,
|
|||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
const struct intel_shared_dpll *pll = crtc_state->shared_dpll;
|
||||
const struct intel_dpll *pll = crtc_state->intel_dpll;
|
||||
|
||||
if (drm_WARN_ON(display->drm, !pll))
|
||||
return ICL_PORT_DPLL_DEFAULT;
|
||||
|
|
@ -4287,7 +4300,7 @@ intel_ddi_port_pll_type(struct intel_encoder *encoder,
|
|||
|
||||
static void icl_ddi_tc_get_clock(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *crtc_state,
|
||||
struct intel_shared_dpll *pll)
|
||||
struct intel_dpll *pll)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
enum icl_port_dpll_id port_dpll_id;
|
||||
|
|
@ -4310,10 +4323,10 @@ static void icl_ddi_tc_get_clock(struct intel_encoder *encoder,
|
|||
|
||||
icl_set_active_port_dpll(crtc_state, port_dpll_id);
|
||||
|
||||
if (icl_ddi_tc_pll_is_tbt(crtc_state->shared_dpll))
|
||||
if (icl_ddi_tc_pll_is_tbt(crtc_state->intel_dpll))
|
||||
crtc_state->port_clock = icl_calc_tbt_pll_link(display, encoder->port);
|
||||
else
|
||||
crtc_state->port_clock = intel_dpll_get_freq(display, crtc_state->shared_dpll,
|
||||
crtc_state->port_clock = intel_dpll_get_freq(display, crtc_state->intel_dpll,
|
||||
&crtc_state->dpll_hw_state);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,9 +16,9 @@ struct intel_crtc;
|
|||
struct intel_crtc_state;
|
||||
struct intel_display;
|
||||
struct intel_dp;
|
||||
struct intel_dpll;
|
||||
struct intel_dpll_hw_state;
|
||||
struct intel_encoder;
|
||||
struct intel_shared_dpll;
|
||||
enum pipe;
|
||||
enum port;
|
||||
enum transcoder;
|
||||
|
|
@ -40,7 +40,7 @@ void intel_ddi_enable_clock(struct intel_encoder *encoder,
|
|||
void intel_ddi_disable_clock(struct intel_encoder *encoder);
|
||||
void intel_ddi_get_clock(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *crtc_state,
|
||||
struct intel_shared_dpll *pll);
|
||||
struct intel_dpll *pll);
|
||||
void hsw_ddi_enable_clock(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state);
|
||||
void hsw_ddi_disable_clock(struct intel_encoder *encoder);
|
||||
|
|
@ -50,7 +50,7 @@ intel_ddi_port_pll_type(struct intel_encoder *encoder,
|
|||
const struct intel_crtc_state *crtc_state);
|
||||
void hsw_ddi_get_config(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *crtc_state);
|
||||
struct intel_shared_dpll *icl_ddi_combo_get_pll(struct intel_encoder *encoder);
|
||||
struct intel_dpll *icl_ddi_combo_get_pll(struct intel_encoder *encoder);
|
||||
void hsw_prepare_dp_ddi_buffers(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state);
|
||||
void intel_wait_ddi_buf_idle(struct intel_display *display, enum port port);
|
||||
|
|
|
|||
|
|
@ -107,10 +107,10 @@ 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)
|
||||
u32 mask, u32 value, unsigned int timeout_ms)
|
||||
{
|
||||
return intel_wait_for_register(__to_uncore(display), reg, mask,
|
||||
value, timeout);
|
||||
value, timeout_ms);
|
||||
}
|
||||
|
||||
static inline int
|
||||
|
|
@ -125,14 +125,14 @@ __intel_de_wait_for_register_atomic_nowl(struct intel_display *display,
|
|||
|
||||
static inline int
|
||||
intel_de_wait(struct intel_display *display, i915_reg_t reg,
|
||||
u32 mask, u32 value, unsigned int timeout)
|
||||
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);
|
||||
timeout_ms);
|
||||
|
||||
intel_dmc_wl_put(display, reg);
|
||||
|
||||
|
|
@ -141,14 +141,14 @@ intel_de_wait(struct intel_display *display, i915_reg_t reg,
|
|||
|
||||
static inline int
|
||||
intel_de_wait_fw(struct intel_display *display, i915_reg_t reg,
|
||||
u32 mask, u32 value, unsigned int timeout)
|
||||
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);
|
||||
value, timeout_ms, out_value);
|
||||
|
||||
intel_dmc_wl_put(display, reg);
|
||||
|
||||
|
|
@ -176,16 +176,16 @@ 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)
|
||||
u32 mask, unsigned int timeout_ms)
|
||||
{
|
||||
return intel_de_wait(display, reg, mask, mask, timeout);
|
||||
return intel_de_wait(display, reg, mask, mask, timeout_ms);
|
||||
}
|
||||
|
||||
static inline int
|
||||
intel_de_wait_for_clear(struct intel_display *display, i915_reg_t reg,
|
||||
u32 mask, unsigned int timeout)
|
||||
u32 mask, unsigned int timeout_ms)
|
||||
{
|
||||
return intel_de_wait(display, reg, mask, 0, timeout);
|
||||
return intel_de_wait(display, reg, mask, 0, timeout_ms);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -67,13 +67,14 @@
|
|||
#include "intel_crt.h"
|
||||
#include "intel_crtc.h"
|
||||
#include "intel_crtc_state_dump.h"
|
||||
#include "intel_cursor.h"
|
||||
#include "intel_cursor_regs.h"
|
||||
#include "intel_cx0_phy.h"
|
||||
#include "intel_cursor.h"
|
||||
#include "intel_ddi.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_driver.h"
|
||||
#include "intel_display_power.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_rpm.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dmc.h"
|
||||
|
|
@ -105,7 +106,6 @@
|
|||
#include "intel_panel.h"
|
||||
#include "intel_pch_display.h"
|
||||
#include "intel_pch_refclk.h"
|
||||
#include "intel_pcode.h"
|
||||
#include "intel_pfit.h"
|
||||
#include "intel_pipe_crc.h"
|
||||
#include "intel_plane_initial.h"
|
||||
|
|
@ -140,46 +140,47 @@ static void bdw_set_pipe_misc(struct intel_dsb *dsb,
|
|||
const struct intel_crtc_state *crtc_state);
|
||||
|
||||
/* returns HPLL frequency in kHz */
|
||||
int vlv_get_hpll_vco(struct drm_i915_private *dev_priv)
|
||||
int vlv_get_hpll_vco(struct drm_device *drm)
|
||||
{
|
||||
int hpll_freq, vco_freq[] = { 800, 1600, 2000, 2400 };
|
||||
|
||||
/* Obtain SKU information */
|
||||
hpll_freq = vlv_cck_read(dev_priv, CCK_FUSE_REG) &
|
||||
hpll_freq = vlv_cck_read(drm, CCK_FUSE_REG) &
|
||||
CCK_FUSE_HPLL_FREQ_MASK;
|
||||
|
||||
return vco_freq[hpll_freq] * 1000;
|
||||
}
|
||||
|
||||
int vlv_get_cck_clock(struct drm_i915_private *dev_priv,
|
||||
int vlv_get_cck_clock(struct drm_device *drm,
|
||||
const char *name, u32 reg, int ref_freq)
|
||||
{
|
||||
u32 val;
|
||||
int divider;
|
||||
|
||||
val = vlv_cck_read(dev_priv, reg);
|
||||
val = vlv_cck_read(drm, reg);
|
||||
divider = val & CCK_FREQUENCY_VALUES;
|
||||
|
||||
drm_WARN(&dev_priv->drm, (val & CCK_FREQUENCY_STATUS) !=
|
||||
drm_WARN(drm, (val & CCK_FREQUENCY_STATUS) !=
|
||||
(divider << CCK_FREQUENCY_STATUS_SHIFT),
|
||||
"%s change in progress\n", name);
|
||||
|
||||
return DIV_ROUND_CLOSEST(ref_freq << 1, divider + 1);
|
||||
}
|
||||
|
||||
int vlv_get_cck_clock_hpll(struct drm_i915_private *dev_priv,
|
||||
int vlv_get_cck_clock_hpll(struct drm_device *drm,
|
||||
const char *name, u32 reg)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(drm);
|
||||
int hpll;
|
||||
|
||||
vlv_cck_get(dev_priv);
|
||||
vlv_cck_get(drm);
|
||||
|
||||
if (dev_priv->hpll_freq == 0)
|
||||
dev_priv->hpll_freq = vlv_get_hpll_vco(dev_priv);
|
||||
dev_priv->hpll_freq = vlv_get_hpll_vco(drm);
|
||||
|
||||
hpll = vlv_get_cck_clock(dev_priv, name, reg, dev_priv->hpll_freq);
|
||||
hpll = vlv_get_cck_clock(drm, name, reg, dev_priv->hpll_freq);
|
||||
|
||||
vlv_cck_put(dev_priv);
|
||||
vlv_cck_put(drm);
|
||||
|
||||
return hpll;
|
||||
}
|
||||
|
|
@ -191,7 +192,7 @@ void intel_update_czclk(struct intel_display *display)
|
|||
if (!display->platform.valleyview && !display->platform.cherryview)
|
||||
return;
|
||||
|
||||
dev_priv->czclk_freq = vlv_get_cck_clock_hpll(dev_priv, "czclk",
|
||||
dev_priv->czclk_freq = vlv_get_cck_clock_hpll(display->drm, "czclk",
|
||||
CCK_CZ_CLOCK_CONTROL);
|
||||
|
||||
drm_dbg_kms(display->drm, "CZ clock rate: %d kHz\n", dev_priv->czclk_freq);
|
||||
|
|
@ -1325,7 +1326,7 @@ static void intel_encoders_update_prepare(struct intel_atomic_state *state)
|
|||
if (intel_crtc_needs_modeset(new_crtc_state))
|
||||
continue;
|
||||
|
||||
new_crtc_state->shared_dpll = old_crtc_state->shared_dpll;
|
||||
new_crtc_state->intel_dpll = old_crtc_state->intel_dpll;
|
||||
new_crtc_state->dpll_hw_state = old_crtc_state->dpll_hw_state;
|
||||
}
|
||||
}
|
||||
|
|
@ -1663,8 +1664,8 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,
|
|||
|
||||
intel_encoders_pre_pll_enable(state, crtc);
|
||||
|
||||
if (new_crtc_state->shared_dpll)
|
||||
intel_enable_shared_dpll(new_crtc_state);
|
||||
if (new_crtc_state->intel_dpll)
|
||||
intel_dpll_enable(new_crtc_state);
|
||||
|
||||
intel_encoders_pre_enable(state, crtc);
|
||||
|
||||
|
|
@ -1793,7 +1794,7 @@ static void hsw_crtc_disable(struct intel_atomic_state *state,
|
|||
intel_encoders_disable(state, crtc);
|
||||
intel_encoders_post_disable(state, crtc);
|
||||
|
||||
intel_disable_shared_dpll(old_crtc_state);
|
||||
intel_dpll_disable(old_crtc_state);
|
||||
|
||||
intel_encoders_post_pll_disable(state, crtc);
|
||||
|
||||
|
|
@ -1959,7 +1960,7 @@ static void get_crtc_power_domains(struct intel_crtc_state *crtc_state,
|
|||
if (HAS_DDI(display) && crtc_state->has_audio)
|
||||
set_bit(POWER_DOMAIN_AUDIO_MMIO, mask->bits);
|
||||
|
||||
if (crtc_state->shared_dpll)
|
||||
if (crtc_state->intel_dpll)
|
||||
set_bit(POWER_DOMAIN_DISPLAY_CORE, mask->bits);
|
||||
|
||||
if (crtc_state->dsc.compression_enable)
|
||||
|
|
@ -4225,7 +4226,7 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state,
|
|||
crtc_state->update_wm_post = true;
|
||||
|
||||
if (intel_crtc_needs_modeset(crtc_state)) {
|
||||
ret = intel_dpll_crtc_get_shared_dpll(state, crtc);
|
||||
ret = intel_dpll_crtc_get_dpll(state, crtc);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -4318,6 +4319,22 @@ compute_sink_pipe_bpp(const struct drm_connector_state *conn_state,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int intel_display_min_pipe_bpp(void)
|
||||
{
|
||||
return 6 * 3;
|
||||
}
|
||||
|
||||
int intel_display_max_pipe_bpp(struct intel_display *display)
|
||||
{
|
||||
if (display->platform.g4x || display->platform.valleyview ||
|
||||
display->platform.cherryview)
|
||||
return 10*3;
|
||||
else if (DISPLAY_VER(display) >= 5)
|
||||
return 12*3;
|
||||
else
|
||||
return 8*3;
|
||||
}
|
||||
|
||||
static int
|
||||
compute_baseline_pipe_bpp(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
|
|
@ -4327,17 +4344,9 @@ compute_baseline_pipe_bpp(struct intel_atomic_state *state,
|
|||
intel_atomic_get_new_crtc_state(state, crtc);
|
||||
struct drm_connector *connector;
|
||||
struct drm_connector_state *connector_state;
|
||||
int bpp, i;
|
||||
int i;
|
||||
|
||||
if (display->platform.g4x || display->platform.valleyview ||
|
||||
display->platform.cherryview)
|
||||
bpp = 10*3;
|
||||
else if (DISPLAY_VER(display) >= 5)
|
||||
bpp = 12*3;
|
||||
else
|
||||
bpp = 8*3;
|
||||
|
||||
crtc_state->pipe_bpp = bpp;
|
||||
crtc_state->pipe_bpp = intel_display_max_pipe_bpp(display);
|
||||
|
||||
/* Clamp display bpp to connector max bpp */
|
||||
for_each_new_connector_in_state(&state->base, connector, connector_state, i) {
|
||||
|
|
@ -4501,7 +4510,7 @@ copy_joiner_crtc_state_modeset(struct intel_atomic_state *state,
|
|||
/* preserve some things from the slave's original crtc state */
|
||||
saved_state->uapi = secondary_crtc_state->uapi;
|
||||
saved_state->scaler_state = secondary_crtc_state->scaler_state;
|
||||
saved_state->shared_dpll = secondary_crtc_state->shared_dpll;
|
||||
saved_state->intel_dpll = secondary_crtc_state->intel_dpll;
|
||||
saved_state->crc_enabled = secondary_crtc_state->crc_enabled;
|
||||
|
||||
intel_crtc_free_hw_state(secondary_crtc_state);
|
||||
|
|
@ -4564,7 +4573,7 @@ intel_crtc_prepare_cleared_state(struct intel_atomic_state *state,
|
|||
saved_state->uapi = crtc_state->uapi;
|
||||
saved_state->inherited = crtc_state->inherited;
|
||||
saved_state->scaler_state = crtc_state->scaler_state;
|
||||
saved_state->shared_dpll = crtc_state->shared_dpll;
|
||||
saved_state->intel_dpll = crtc_state->intel_dpll;
|
||||
saved_state->dpll_hw_state = crtc_state->dpll_hw_state;
|
||||
memcpy(saved_state->icl_port_dplls, crtc_state->icl_port_dplls,
|
||||
sizeof(saved_state->icl_port_dplls));
|
||||
|
|
@ -5318,7 +5327,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
|
|||
PIPE_CONF_CHECK_BOOL(double_wide);
|
||||
|
||||
if (display->dpll.mgr)
|
||||
PIPE_CONF_CHECK_P(shared_dpll);
|
||||
PIPE_CONF_CHECK_P(intel_dpll);
|
||||
|
||||
/* FIXME convert everything over the dpll_mgr */
|
||||
if (display->dpll.mgr || HAS_GMCH(display))
|
||||
|
|
@ -6428,7 +6437,7 @@ int intel_atomic_check(struct drm_device *dev,
|
|||
|
||||
any_ms = true;
|
||||
|
||||
intel_release_shared_dplls(state, crtc);
|
||||
intel_dpll_release(state, crtc);
|
||||
}
|
||||
|
||||
if (any_ms && !check_digital_port_conflicts(state)) {
|
||||
|
|
@ -6630,6 +6639,7 @@ static void commit_pipe_post_planes(struct intel_atomic_state *state,
|
|||
struct intel_display *display = to_intel_display(state);
|
||||
const struct intel_crtc_state *new_crtc_state =
|
||||
intel_atomic_get_new_crtc_state(state, crtc);
|
||||
bool modeset = intel_crtc_needs_modeset(new_crtc_state);
|
||||
|
||||
drm_WARN_ON(display->drm, new_crtc_state->use_dsb);
|
||||
|
||||
|
|
@ -6638,10 +6648,15 @@ static void commit_pipe_post_planes(struct intel_atomic_state *state,
|
|||
* get a catastrophic underrun even if the two operations
|
||||
* end up happening in two different frames.
|
||||
*/
|
||||
if (DISPLAY_VER(display) >= 9 &&
|
||||
!intel_crtc_needs_modeset(new_crtc_state))
|
||||
if (DISPLAY_VER(display) >= 9 && !modeset)
|
||||
skl_detach_scalers(NULL, new_crtc_state);
|
||||
|
||||
if (!modeset &&
|
||||
intel_crtc_needs_color_update(new_crtc_state) &&
|
||||
!intel_color_uses_dsb(new_crtc_state) &&
|
||||
HAS_DOUBLE_BUFFERED_LUT(display))
|
||||
intel_color_load_luts(new_crtc_state);
|
||||
|
||||
if (intel_crtc_vrr_enabling(state, crtc))
|
||||
intel_vrr_enable(new_crtc_state);
|
||||
}
|
||||
|
|
@ -6733,13 +6748,13 @@ static void intel_update_crtc(struct intel_atomic_state *state,
|
|||
if (new_crtc_state->use_dsb) {
|
||||
intel_crtc_prepare_vblank_event(new_crtc_state, &crtc->dsb_event);
|
||||
|
||||
intel_dsb_commit(new_crtc_state->dsb_commit, false);
|
||||
intel_dsb_commit(new_crtc_state->dsb_commit);
|
||||
} else {
|
||||
/* Perform vblank evasion around commit operation */
|
||||
intel_pipe_update_start(state, crtc);
|
||||
|
||||
if (new_crtc_state->dsb_commit)
|
||||
intel_dsb_commit(new_crtc_state->dsb_commit, false);
|
||||
intel_dsb_commit(new_crtc_state->dsb_commit);
|
||||
|
||||
commit_pipe_pre_planes(state, crtc);
|
||||
|
||||
|
|
@ -7184,7 +7199,7 @@ static void intel_atomic_dsb_finish(struct intel_atomic_state *state,
|
|||
struct intel_crtc_state *new_crtc_state =
|
||||
intel_atomic_get_new_crtc_state(state, crtc);
|
||||
|
||||
if (!new_crtc_state->use_dsb && !new_crtc_state->dsb_color_vblank)
|
||||
if (!new_crtc_state->use_dsb && !new_crtc_state->dsb_color)
|
||||
return;
|
||||
|
||||
/*
|
||||
|
|
@ -7230,20 +7245,24 @@ static void intel_atomic_dsb_finish(struct intel_atomic_state *state,
|
|||
if (DISPLAY_VER(display) >= 9)
|
||||
skl_detach_scalers(new_crtc_state->dsb_commit,
|
||||
new_crtc_state);
|
||||
|
||||
if (!new_crtc_state->dsb_color_vblank) {
|
||||
intel_dsb_wait_vblanks(new_crtc_state->dsb_commit, 1);
|
||||
|
||||
intel_vrr_send_push(new_crtc_state->dsb_commit, new_crtc_state);
|
||||
intel_dsb_wait_vblank_delay(state, new_crtc_state->dsb_commit);
|
||||
intel_vrr_check_push_sent(new_crtc_state->dsb_commit, new_crtc_state);
|
||||
intel_dsb_interrupt(new_crtc_state->dsb_commit);
|
||||
}
|
||||
}
|
||||
|
||||
if (new_crtc_state->dsb_color_vblank)
|
||||
if (intel_color_uses_chained_dsb(new_crtc_state))
|
||||
intel_dsb_chain(state, new_crtc_state->dsb_commit,
|
||||
new_crtc_state->dsb_color_vblank, true);
|
||||
new_crtc_state->dsb_color, true);
|
||||
else if (intel_color_uses_gosub_dsb(new_crtc_state))
|
||||
intel_dsb_gosub(new_crtc_state->dsb_commit,
|
||||
new_crtc_state->dsb_color);
|
||||
|
||||
if (new_crtc_state->use_dsb && !intel_color_uses_chained_dsb(new_crtc_state)) {
|
||||
intel_dsb_wait_vblanks(new_crtc_state->dsb_commit, 1);
|
||||
|
||||
intel_vrr_send_push(new_crtc_state->dsb_commit, new_crtc_state);
|
||||
intel_dsb_wait_vblank_delay(state, new_crtc_state->dsb_commit);
|
||||
intel_vrr_check_push_sent(new_crtc_state->dsb_commit,
|
||||
new_crtc_state);
|
||||
intel_dsb_interrupt(new_crtc_state->dsb_commit);
|
||||
}
|
||||
|
||||
intel_dsb_finish(new_crtc_state->dsb_commit);
|
||||
}
|
||||
|
|
@ -7432,7 +7451,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
|
|||
*
|
||||
* FIXME get rid of this funny new->old swapping
|
||||
*/
|
||||
old_crtc_state->dsb_color_vblank = fetch_and_zero(&new_crtc_state->dsb_color_vblank);
|
||||
old_crtc_state->dsb_color = fetch_and_zero(&new_crtc_state->dsb_color);
|
||||
old_crtc_state->dsb_commit = fetch_and_zero(&new_crtc_state->dsb_commit);
|
||||
}
|
||||
|
||||
|
|
@ -7525,7 +7544,7 @@ static int intel_atomic_swap_state(struct intel_atomic_state *state)
|
|||
|
||||
intel_atomic_swap_global_state(state);
|
||||
|
||||
intel_shared_dpll_swap_state(state);
|
||||
intel_dpll_swap_state(state);
|
||||
|
||||
intel_atomic_track_fbs(state);
|
||||
|
||||
|
|
|
|||
|
|
@ -30,38 +30,21 @@
|
|||
#include "i915_reg_defs.h"
|
||||
#include "intel_display_limits.h"
|
||||
|
||||
enum drm_scaling_filter;
|
||||
struct dpll;
|
||||
struct drm_atomic_state;
|
||||
struct drm_connector;
|
||||
struct drm_device;
|
||||
struct drm_display_mode;
|
||||
struct drm_encoder;
|
||||
struct drm_file;
|
||||
struct drm_format_info;
|
||||
struct drm_framebuffer;
|
||||
struct drm_i915_private;
|
||||
struct drm_mode_fb_cmd2;
|
||||
struct drm_modeset_acquire_ctx;
|
||||
struct drm_plane;
|
||||
struct drm_plane_state;
|
||||
struct i915_address_space;
|
||||
struct i915_gtt_view;
|
||||
struct intel_atomic_state;
|
||||
struct intel_crtc;
|
||||
struct intel_crtc_state;
|
||||
struct intel_digital_port;
|
||||
struct intel_display;
|
||||
struct intel_dp;
|
||||
struct intel_encoder;
|
||||
struct intel_initial_plane_config;
|
||||
struct intel_link_m_n;
|
||||
struct intel_plane;
|
||||
struct intel_plane_state;
|
||||
struct intel_power_domain_mask;
|
||||
struct pci_dev;
|
||||
struct work_struct;
|
||||
|
||||
|
||||
#define pipe_name(p) ((p) + 'A')
|
||||
|
||||
|
|
@ -452,10 +435,10 @@ void intel_enable_transcoder(const struct intel_crtc_state *new_crtc_state);
|
|||
void intel_disable_transcoder(const struct intel_crtc_state *old_crtc_state);
|
||||
void i830_enable_pipe(struct intel_display *display, enum pipe pipe);
|
||||
void i830_disable_pipe(struct intel_display *display, enum pipe pipe);
|
||||
int vlv_get_hpll_vco(struct drm_i915_private *dev_priv);
|
||||
int vlv_get_cck_clock(struct drm_i915_private *dev_priv,
|
||||
int vlv_get_hpll_vco(struct drm_device *drm);
|
||||
int vlv_get_cck_clock(struct drm_device *drm,
|
||||
const char *name, u32 reg, int ref_freq);
|
||||
int vlv_get_cck_clock_hpll(struct drm_i915_private *dev_priv,
|
||||
int vlv_get_cck_clock_hpll(struct drm_device *drm,
|
||||
const char *name, u32 reg);
|
||||
bool intel_has_pending_fb_unpin(struct intel_display *display);
|
||||
void intel_encoder_destroy(struct drm_encoder *encoder);
|
||||
|
|
@ -524,6 +507,9 @@ void intel_plane_fixup_bitmasks(struct intel_crtc_state *crtc_state);
|
|||
bool intel_crtc_vrr_disabling(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc);
|
||||
|
||||
int intel_display_min_pipe_bpp(void);
|
||||
int intel_display_max_pipe_bpp(struct intel_display *display);
|
||||
|
||||
/* modesetting */
|
||||
int intel_modeset_pipes_in_mask_early(struct intel_atomic_state *state,
|
||||
const char *reason, u8 pipe_mask);
|
||||
|
|
|
|||
|
|
@ -2,10 +2,11 @@
|
|||
/* Copyright © 2024 Intel Corporation */
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "intel_display_conversion.h"
|
||||
|
||||
struct intel_display *__i915_to_display(struct drm_i915_private *i915)
|
||||
{
|
||||
return &i915->display;
|
||||
return i915->display;
|
||||
}
|
||||
|
||||
struct intel_display *__drm_to_display(struct drm_device *drm)
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ struct intel_color_funcs;
|
|||
struct intel_crtc;
|
||||
struct intel_crtc_state;
|
||||
struct intel_dmc;
|
||||
struct intel_dpll_funcs;
|
||||
struct intel_dpll_global_funcs;
|
||||
struct intel_dpll_mgr;
|
||||
struct intel_fbdev;
|
||||
struct intel_fdi_funcs;
|
||||
|
|
@ -122,11 +122,11 @@ struct intel_audio {
|
|||
* intel_{prepare,enable,disable}_shared_dpll. Must be global rather than per
|
||||
* dpll, because on some platforms plls share registers.
|
||||
*/
|
||||
struct intel_dpll {
|
||||
struct intel_dpll_global {
|
||||
struct mutex lock;
|
||||
|
||||
int num_shared_dpll;
|
||||
struct intel_shared_dpll shared_dplls[I915_NUM_PLLS];
|
||||
int num_dpll;
|
||||
struct intel_dpll dplls[I915_NUM_PLLS];
|
||||
const struct intel_dpll_mgr *mgr;
|
||||
|
||||
struct {
|
||||
|
|
@ -300,7 +300,7 @@ struct intel_display {
|
|||
const struct intel_cdclk_funcs *cdclk;
|
||||
|
||||
/* Display pll funcs */
|
||||
const struct intel_dpll_funcs *dpll;
|
||||
const struct intel_dpll_global_funcs *dpll;
|
||||
|
||||
/* irq display functions */
|
||||
const struct intel_hotplug_funcs *hotplug;
|
||||
|
|
@ -538,6 +538,11 @@ struct intel_display {
|
|||
u32 block_time_us;
|
||||
} sagv;
|
||||
|
||||
struct {
|
||||
/* LPT/WPT IOSF sideband protection */
|
||||
struct mutex lock;
|
||||
} sbi;
|
||||
|
||||
struct {
|
||||
/*
|
||||
* DG2: Mask of PHYs that were not calibrated by the firmware
|
||||
|
|
@ -570,7 +575,7 @@ struct intel_display {
|
|||
/* Grouping using named structs. Keep sorted. */
|
||||
struct drm_dp_tunnel_mgr *dp_tunnel_mgr;
|
||||
struct intel_audio audio;
|
||||
struct intel_dpll dpll;
|
||||
struct intel_dpll_global dpll;
|
||||
struct intel_fbc *fbc[I915_MAX_FBCS];
|
||||
struct intel_frontbuffer_tracking fb_tracking;
|
||||
struct intel_hotplug hotplug;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/string_choices.h>
|
||||
#include <linux/string_helpers.h>
|
||||
|
||||
#include <drm/drm_debugfs.h>
|
||||
|
|
@ -13,7 +14,6 @@
|
|||
#include <drm/drm_fourcc.h>
|
||||
|
||||
#include "hsw_ips.h"
|
||||
#include "i915_irq.h"
|
||||
#include "i915_reg.h"
|
||||
#include "i9xx_wm_regs.h"
|
||||
#include "intel_alpm.h"
|
||||
|
|
@ -25,6 +25,7 @@
|
|||
#include "intel_display_debugfs_params.h"
|
||||
#include "intel_display_power.h"
|
||||
#include "intel_display_power_well.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_rpm.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dmc.h"
|
||||
|
|
@ -39,6 +40,7 @@
|
|||
#include "intel_hdcp.h"
|
||||
#include "intel_hdmi.h"
|
||||
#include "intel_hotplug.h"
|
||||
#include "intel_link_bw.h"
|
||||
#include "intel_panel.h"
|
||||
#include "intel_pps.h"
|
||||
#include "intel_psr.h"
|
||||
|
|
@ -618,7 +620,7 @@ static int i915_shared_dplls_info(struct seq_file *m, void *unused)
|
|||
{
|
||||
struct intel_display *display = node_to_intel_display(m->private);
|
||||
struct drm_printer p = drm_seq_file_printer(m);
|
||||
struct intel_shared_dpll *pll;
|
||||
struct intel_dpll *pll;
|
||||
int i;
|
||||
|
||||
drm_modeset_lock_all(display->drm);
|
||||
|
|
@ -627,7 +629,7 @@ static int i915_shared_dplls_info(struct seq_file *m, void *unused)
|
|||
display->dpll.ref_clks.nssc,
|
||||
display->dpll.ref_clks.ssc);
|
||||
|
||||
for_each_shared_dpll(display, pll, i) {
|
||||
for_each_dpll(display, pll, i) {
|
||||
drm_printf(&p, "DPLL%i: %s, id: %i\n", pll->index,
|
||||
pll->info->name, pll->info->id);
|
||||
drm_printf(&p, " pipe_mask: 0x%x, active: 0x%x, on: %s\n",
|
||||
|
|
@ -972,7 +974,7 @@ static ssize_t i915_dsc_fec_support_write(struct file *file,
|
|||
return ret;
|
||||
|
||||
drm_dbg(display->drm, "Got %s for DSC Enable\n",
|
||||
(dsc_enable) ? "true" : "false");
|
||||
str_true_false(dsc_enable));
|
||||
intel_dp->force_dsc_en = dsc_enable;
|
||||
|
||||
*offp += len;
|
||||
|
|
@ -1183,7 +1185,7 @@ static ssize_t i915_dsc_fractional_bpp_write(struct file *file,
|
|||
return ret;
|
||||
|
||||
drm_dbg(display->drm, "Got %s for DSC Fractional BPP Enable\n",
|
||||
(dsc_fractional_bpp_enable) ? "true" : "false");
|
||||
str_true_false(dsc_fractional_bpp_enable));
|
||||
intel_dp->force_dsc_fractional_bpp_en = dsc_fractional_bpp_enable;
|
||||
|
||||
*offp += len;
|
||||
|
|
@ -1325,6 +1327,7 @@ void intel_connector_debugfs_add(struct intel_connector *connector)
|
|||
intel_psr_connector_debugfs_add(connector);
|
||||
intel_alpm_lobf_debugfs_add(connector);
|
||||
intel_dp_link_training_debugfs_add(connector);
|
||||
intel_link_bw_connector_debugfs_add(connector);
|
||||
|
||||
if (DISPLAY_VER(display) >= 11 &&
|
||||
((connector_type == DRM_MODE_CONNECTOR_DisplayPort && !connector->mst.dp) ||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include "intel_display_params.h"
|
||||
#include "intel_display_power.h"
|
||||
#include "intel_display_reg_defs.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_fbc.h"
|
||||
#include "intel_step.h"
|
||||
|
|
@ -1621,13 +1622,17 @@ static void display_platforms_or(struct intel_display_platforms *dst,
|
|||
|
||||
struct intel_display *intel_display_device_probe(struct pci_dev *pdev)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(pdev);
|
||||
struct intel_display *display;
|
||||
const struct intel_display_device_info *info;
|
||||
struct intel_display_ip_ver ip_ver = {};
|
||||
const struct platform_desc *desc;
|
||||
const struct subplatform_desc *subdesc;
|
||||
enum intel_step step;
|
||||
|
||||
display = kzalloc(sizeof(*display), GFP_KERNEL);
|
||||
if (!display)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
/* Add drm device backpointer as early as possible. */
|
||||
display->drm = pci_get_drvdata(pdev);
|
||||
|
||||
|
|
@ -1708,7 +1713,11 @@ struct intel_display *intel_display_device_probe(struct pci_dev *pdev)
|
|||
|
||||
void intel_display_device_remove(struct intel_display *display)
|
||||
{
|
||||
if (!display)
|
||||
return;
|
||||
|
||||
intel_display_params_free(&display->params);
|
||||
kfree(display);
|
||||
}
|
||||
|
||||
static void __intel_display_device_info_runtime_init(struct intel_display *display)
|
||||
|
|
|
|||
|
|
@ -157,6 +157,7 @@ struct intel_display_platforms {
|
|||
#define HAS_DMC(__display) (DISPLAY_RUNTIME_INFO(__display)->has_dmc)
|
||||
#define HAS_DMC_WAKELOCK(__display) (DISPLAY_VER(__display) >= 20)
|
||||
#define HAS_DOUBLE_BUFFERED_M_N(__display) (DISPLAY_VER(__display) >= 9 || (__display)->platform.broadwell)
|
||||
#define HAS_DOUBLE_BUFFERED_LUT(__display) (DISPLAY_VER(__display) >= 30)
|
||||
#define HAS_DOUBLE_WIDE(__display) (DISPLAY_VER(__display) < 4)
|
||||
#define HAS_DP20(__display) ((__display)->platform.dg2 || DISPLAY_VER(__display) >= 14)
|
||||
#define HAS_DPT(__display) (DISPLAY_VER(__display) >= 13)
|
||||
|
|
@ -172,6 +173,7 @@ struct intel_display_platforms {
|
|||
#define HAS_GMBUS_BURST_READ(__display) (DISPLAY_VER(__display) >= 10 || (__display)->platform.kabylake)
|
||||
#define HAS_GMBUS_IRQ(__display) (DISPLAY_VER(__display) >= 4)
|
||||
#define HAS_GMCH(__display) (DISPLAY_INFO(__display)->has_gmch)
|
||||
#define HAS_FDI(__display) (IS_DISPLAY_VER((__display), 5, 8) && !HAS_GMCH(__display))
|
||||
#define HAS_HOTPLUG(__display) (DISPLAY_INFO(__display)->has_hotplug)
|
||||
#define HAS_HW_SAGV_WM(__display) (DISPLAY_VER(__display) >= 13 && !(__display)->platform.dgfx)
|
||||
#define HAS_IPC(__display) (DISPLAY_INFO(__display)->has_ipc)
|
||||
|
|
@ -181,6 +183,7 @@ struct intel_display_platforms {
|
|||
#define HAS_MBUS_JOINING(__display) ((__display)->platform.alderlake_p || DISPLAY_VER(__display) >= 14)
|
||||
#define HAS_MSO(__display) (DISPLAY_VER(__display) >= 12)
|
||||
#define HAS_OVERLAY(__display) (DISPLAY_INFO(__display)->has_overlay)
|
||||
#define HAS_PIPEDMC(__display) (DISPLAY_VER(__display) >= 12)
|
||||
#define HAS_PSR(__display) (DISPLAY_INFO(__display)->has_psr)
|
||||
#define HAS_PSR_HW_TRACKING(__display) (DISPLAY_INFO(__display)->has_psr_hw_tracking)
|
||||
#define HAS_PSR2_SEL_FETCH(__display) (DISPLAY_VER(__display) >= 12)
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include "intel_cdclk.h"
|
||||
#include "intel_color.h"
|
||||
#include "intel_crtc.h"
|
||||
#include "intel_display_core.h"
|
||||
#include "intel_display_debugfs.h"
|
||||
#include "intel_display_driver.h"
|
||||
#include "intel_display_irq.h"
|
||||
|
|
@ -243,10 +244,16 @@ int intel_display_driver_probe_noirq(struct intel_display *display)
|
|||
|
||||
intel_dmc_init(display);
|
||||
|
||||
display->hotplug.dp_wq = alloc_ordered_workqueue("intel-dp", 0);
|
||||
if (!display->hotplug.dp_wq) {
|
||||
ret = -ENOMEM;
|
||||
goto cleanup_vga_client_pw_domain_dmc;
|
||||
}
|
||||
|
||||
display->wq.modeset = alloc_ordered_workqueue("i915_modeset", 0);
|
||||
if (!display->wq.modeset) {
|
||||
ret = -ENOMEM;
|
||||
goto cleanup_vga_client_pw_domain_dmc;
|
||||
goto cleanup_wq_dp;
|
||||
}
|
||||
|
||||
display->wq.flip = alloc_workqueue("i915_flip", WQ_HIGHPRI |
|
||||
|
|
@ -296,6 +303,8 @@ int intel_display_driver_probe_noirq(struct intel_display *display)
|
|||
destroy_workqueue(display->wq.flip);
|
||||
cleanup_wq_modeset:
|
||||
destroy_workqueue(display->wq.modeset);
|
||||
cleanup_wq_dp:
|
||||
destroy_workqueue(display->hotplug.dp_wq);
|
||||
cleanup_vga_client_pw_domain_dmc:
|
||||
intel_dmc_fini(display);
|
||||
intel_power_domains_driver_remove(display);
|
||||
|
|
@ -466,7 +475,7 @@ int intel_display_driver_probe_nogem(struct intel_display *display)
|
|||
}
|
||||
|
||||
intel_plane_possible_crtcs_init(display);
|
||||
intel_shared_dpll_init(display);
|
||||
intel_dpll_init(display);
|
||||
intel_fdi_pll_freq_update(display);
|
||||
|
||||
intel_update_czclk(display);
|
||||
|
|
@ -631,6 +640,7 @@ void intel_display_driver_remove_noirq(struct intel_display *display)
|
|||
|
||||
intel_gmbus_teardown(display);
|
||||
|
||||
destroy_workqueue(display->hotplug.dp_wq);
|
||||
destroy_workqueue(display->wq.flip);
|
||||
destroy_workqueue(display->wq.modeset);
|
||||
destroy_workqueue(display->wq.cleanup);
|
||||
|
|
|
|||
|
|
@ -13,10 +13,12 @@
|
|||
#include "intel_crtc.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_irq.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_rpm.h"
|
||||
#include "intel_display_rps.h"
|
||||
#include "intel_display_trace.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dmc.h"
|
||||
#include "intel_dmc_wl.h"
|
||||
#include "intel_dp_aux.h"
|
||||
#include "intel_dsb.h"
|
||||
|
|
@ -1016,7 +1018,15 @@ static u32 gen8_de_port_aux_mask(struct intel_display *display)
|
|||
|
||||
static u32 gen8_de_pipe_fault_mask(struct intel_display *display)
|
||||
{
|
||||
if (DISPLAY_VER(display) >= 14)
|
||||
if (DISPLAY_VER(display) >= 20)
|
||||
return MTL_PLANE_ATS_FAULT |
|
||||
GEN9_PIPE_CURSOR_FAULT |
|
||||
GEN11_PIPE_PLANE5_FAULT |
|
||||
GEN9_PIPE_PLANE4_FAULT |
|
||||
GEN9_PIPE_PLANE3_FAULT |
|
||||
GEN9_PIPE_PLANE2_FAULT |
|
||||
GEN9_PIPE_PLANE1_FAULT;
|
||||
else if (DISPLAY_VER(display) >= 14)
|
||||
return MTL_PIPEDMC_ATS_FAULT |
|
||||
MTL_PLANE_ATS_FAULT |
|
||||
GEN12_PIPEDMC_FAULT |
|
||||
|
|
@ -1418,7 +1428,8 @@ void gen8_de_irq_handler(struct intel_display *display, u32 master_ctl)
|
|||
iir = intel_de_read(display, GEN8_DE_PIPE_IIR(pipe));
|
||||
if (!iir) {
|
||||
drm_err_ratelimited(display->drm,
|
||||
"The master control interrupt lied (DE PIPE)!\n");
|
||||
"The master control interrupt lied (DE PIPE %c)!\n",
|
||||
pipe_name(pipe));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -1441,6 +1452,9 @@ void gen8_de_irq_handler(struct intel_display *display, u32 master_ctl)
|
|||
intel_dsb_irq_handler(display, pipe, INTEL_DSB_2);
|
||||
}
|
||||
|
||||
if (HAS_PIPEDMC(display) && iir & GEN12_PIPEDMC_INTERRUPT)
|
||||
intel_pipedmc_irq_handler(display, pipe);
|
||||
|
||||
if (iir & GEN8_PIPE_CDCLK_CRC_DONE)
|
||||
hsw_pipe_crc_irq_handler(display, pipe);
|
||||
|
||||
|
|
@ -2258,6 +2272,10 @@ void gen8_de_irq_postinstall(struct intel_display *display)
|
|||
GEN12_DSB_INT(INTEL_DSB_1) |
|
||||
GEN12_DSB_INT(INTEL_DSB_2);
|
||||
|
||||
/* TODO figure PIPEDMC interrupts for pre-LNL */
|
||||
if (DISPLAY_VER(display) >= 20)
|
||||
de_pipe_masked |= GEN12_PIPEDMC_INTERRUPT;
|
||||
|
||||
de_pipe_enables = de_pipe_masked |
|
||||
GEN8_PIPE_VBLANK | GEN8_PIPE_FIFO_UNDERRUN |
|
||||
gen8_de_pipe_flip_done_mask(display);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
#include <linux/string_helpers.h>
|
||||
|
||||
#include "soc/intel_dram.h"
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_irq.h"
|
||||
#include "i915_reg.h"
|
||||
|
|
@ -16,6 +18,7 @@
|
|||
#include "intel_display_power.h"
|
||||
#include "intel_display_power_map.h"
|
||||
#include "intel_display_power_well.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_rpm.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dmc.h"
|
||||
|
|
@ -1604,9 +1607,7 @@ static const struct buddy_page_mask wa_1409767108_buddy_page_masks[] = {
|
|||
|
||||
static void tgl_bw_buddy_init(struct intel_display *display)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
enum intel_dram_type type = dev_priv->dram_info.type;
|
||||
u8 num_channels = dev_priv->dram_info.num_channels;
|
||||
const struct dram_info *dram_info = intel_dram_info(display->drm);
|
||||
const struct buddy_page_mask *table;
|
||||
unsigned long abox_mask = DISPLAY_INFO(display)->abox_mask;
|
||||
int config, i;
|
||||
|
|
@ -1623,8 +1624,8 @@ static void tgl_bw_buddy_init(struct intel_display *display)
|
|||
table = tgl_buddy_page_masks;
|
||||
|
||||
for (config = 0; table[config].page_mask != 0; config++)
|
||||
if (table[config].num_channels == num_channels &&
|
||||
table[config].type == type)
|
||||
if (table[config].num_channels == dram_info->num_channels &&
|
||||
table[config].type == dram_info->type)
|
||||
break;
|
||||
|
||||
if (table[config].page_mask == 0) {
|
||||
|
|
@ -1883,12 +1884,11 @@ static void vlv_cmnlane_wa(struct intel_display *display)
|
|||
|
||||
static bool vlv_punit_is_power_gated(struct intel_display *display, u32 reg0)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
bool ret;
|
||||
|
||||
vlv_punit_get(dev_priv);
|
||||
ret = (vlv_punit_read(dev_priv, reg0) & SSPM0_SSC_MASK) == SSPM0_SSC_PWR_GATE;
|
||||
vlv_punit_put(dev_priv);
|
||||
vlv_punit_get(display->drm);
|
||||
ret = (vlv_punit_read(display->drm, reg0) & SSPM0_SSC_MASK) == SSPM0_SSC_PWR_GATE;
|
||||
vlv_punit_put(display->drm);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,12 +5,12 @@
|
|||
|
||||
#include <drm/drm_print.h>
|
||||
|
||||
#include "i915_reg.h"
|
||||
#include "intel_display_core.h"
|
||||
#include "intel_display_power_map.h"
|
||||
#include "intel_display_power_well.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "vlv_sideband_reg.h"
|
||||
#include "vlv_iosf_sb_reg.h"
|
||||
|
||||
#define __LIST_INLINE_ELEMS(__elem_type, ...) \
|
||||
((__elem_type[]) { __VA_ARGS__ })
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include "intel_de.h"
|
||||
#include "intel_display_irq.h"
|
||||
#include "intel_display_power_well.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_rpm.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dkl_phy.h"
|
||||
|
|
@ -30,8 +31,8 @@
|
|||
#include "intel_vga.h"
|
||||
#include "skl_watermark.h"
|
||||
#include "vlv_dpio_phy_regs.h"
|
||||
#include "vlv_iosf_sb_reg.h"
|
||||
#include "vlv_sideband.h"
|
||||
#include "vlv_sideband_reg.h"
|
||||
|
||||
struct i915_power_well_regs {
|
||||
i915_reg_t bios;
|
||||
|
|
@ -809,7 +810,6 @@ static void tgl_disable_dc3co(struct intel_display *display)
|
|||
|
||||
static void assert_can_enable_dc5(struct intel_display *display)
|
||||
{
|
||||
struct drm_i915_private __maybe_unused *dev_priv = to_i915(display->drm);
|
||||
enum i915_power_well_id high_pg;
|
||||
|
||||
/* Power wells at this level and above must be disabled for DC5 entry */
|
||||
|
|
@ -1102,7 +1102,6 @@ static void i830_pipes_power_well_sync_hw(struct intel_display *display,
|
|||
static void vlv_set_power_well(struct intel_display *display,
|
||||
struct i915_power_well *power_well, bool enable)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
int pw_idx = i915_power_well_instance(power_well)->vlv.idx;
|
||||
u32 mask;
|
||||
u32 state;
|
||||
|
|
@ -1112,29 +1111,29 @@ static void vlv_set_power_well(struct intel_display *display,
|
|||
state = enable ? PUNIT_PWRGT_PWR_ON(pw_idx) :
|
||||
PUNIT_PWRGT_PWR_GATE(pw_idx);
|
||||
|
||||
vlv_punit_get(dev_priv);
|
||||
vlv_punit_get(display->drm);
|
||||
|
||||
#define COND \
|
||||
((vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_STATUS) & mask) == state)
|
||||
((vlv_punit_read(display->drm, PUNIT_REG_PWRGT_STATUS) & mask) == state)
|
||||
|
||||
if (COND)
|
||||
goto out;
|
||||
|
||||
ctrl = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_CTRL);
|
||||
ctrl = vlv_punit_read(display->drm, PUNIT_REG_PWRGT_CTRL);
|
||||
ctrl &= ~mask;
|
||||
ctrl |= state;
|
||||
vlv_punit_write(dev_priv, PUNIT_REG_PWRGT_CTRL, ctrl);
|
||||
vlv_punit_write(display->drm, PUNIT_REG_PWRGT_CTRL, ctrl);
|
||||
|
||||
if (wait_for(COND, 100))
|
||||
drm_err(display->drm,
|
||||
"timeout setting power well state %08x (%08x)\n",
|
||||
state,
|
||||
vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_CTRL));
|
||||
vlv_punit_read(display->drm, PUNIT_REG_PWRGT_CTRL));
|
||||
|
||||
#undef COND
|
||||
|
||||
out:
|
||||
vlv_punit_put(dev_priv);
|
||||
vlv_punit_put(display->drm);
|
||||
}
|
||||
|
||||
static void vlv_power_well_enable(struct intel_display *display,
|
||||
|
|
@ -1152,7 +1151,6 @@ static void vlv_power_well_disable(struct intel_display *display,
|
|||
static bool vlv_power_well_enabled(struct intel_display *display,
|
||||
struct i915_power_well *power_well)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
int pw_idx = i915_power_well_instance(power_well)->vlv.idx;
|
||||
bool enabled = false;
|
||||
u32 mask;
|
||||
|
|
@ -1162,9 +1160,9 @@ static bool vlv_power_well_enabled(struct intel_display *display,
|
|||
mask = PUNIT_PWRGT_MASK(pw_idx);
|
||||
ctrl = PUNIT_PWRGT_PWR_ON(pw_idx);
|
||||
|
||||
vlv_punit_get(dev_priv);
|
||||
vlv_punit_get(display->drm);
|
||||
|
||||
state = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_STATUS) & mask;
|
||||
state = vlv_punit_read(display->drm, PUNIT_REG_PWRGT_STATUS) & mask;
|
||||
/*
|
||||
* We only ever set the power-on and power-gate states, anything
|
||||
* else is unexpected.
|
||||
|
|
@ -1178,10 +1176,10 @@ static bool vlv_power_well_enabled(struct intel_display *display,
|
|||
* A transient state at this point would mean some unexpected party
|
||||
* is poking at the power controls too.
|
||||
*/
|
||||
ctrl = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_CTRL) & mask;
|
||||
ctrl = vlv_punit_read(display->drm, PUNIT_REG_PWRGT_CTRL) & mask;
|
||||
drm_WARN_ON(display->drm, ctrl != state);
|
||||
|
||||
vlv_punit_put(dev_priv);
|
||||
vlv_punit_put(display->drm);
|
||||
|
||||
return enabled;
|
||||
}
|
||||
|
|
@ -1437,7 +1435,6 @@ static void assert_chv_phy_status(struct intel_display *display)
|
|||
static void chv_dpio_cmn_power_well_enable(struct intel_display *display,
|
||||
struct i915_power_well *power_well)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
enum i915_power_well_id id = i915_power_well_instance(power_well)->id;
|
||||
enum dpio_phy phy;
|
||||
u32 tmp;
|
||||
|
|
@ -1461,30 +1458,30 @@ static void chv_dpio_cmn_power_well_enable(struct intel_display *display,
|
|||
drm_err(display->drm, "Display PHY %d is not power up\n",
|
||||
phy);
|
||||
|
||||
vlv_dpio_get(dev_priv);
|
||||
vlv_dpio_get(display->drm);
|
||||
|
||||
/* Enable dynamic power down */
|
||||
tmp = vlv_dpio_read(dev_priv, phy, CHV_CMN_DW28);
|
||||
tmp = vlv_dpio_read(display->drm, phy, CHV_CMN_DW28);
|
||||
tmp |= DPIO_DYNPWRDOWNEN_CH0 | DPIO_CL1POWERDOWNEN |
|
||||
DPIO_SUS_CLK_CONFIG_GATE_CLKREQ;
|
||||
vlv_dpio_write(dev_priv, phy, CHV_CMN_DW28, tmp);
|
||||
vlv_dpio_write(display->drm, phy, CHV_CMN_DW28, tmp);
|
||||
|
||||
if (id == VLV_DISP_PW_DPIO_CMN_BC) {
|
||||
tmp = vlv_dpio_read(dev_priv, phy, CHV_CMN_DW6_CH1);
|
||||
tmp = vlv_dpio_read(display->drm, phy, CHV_CMN_DW6_CH1);
|
||||
tmp |= DPIO_DYNPWRDOWNEN_CH1;
|
||||
vlv_dpio_write(dev_priv, phy, CHV_CMN_DW6_CH1, tmp);
|
||||
vlv_dpio_write(display->drm, phy, CHV_CMN_DW6_CH1, tmp);
|
||||
} else {
|
||||
/*
|
||||
* Force the non-existing CL2 off. BXT does this
|
||||
* too, so maybe it saves some power even though
|
||||
* CL2 doesn't exist?
|
||||
*/
|
||||
tmp = vlv_dpio_read(dev_priv, phy, CHV_CMN_DW30);
|
||||
tmp = vlv_dpio_read(display->drm, phy, CHV_CMN_DW30);
|
||||
tmp |= DPIO_CL2_LDOFUSE_PWRENB;
|
||||
vlv_dpio_write(dev_priv, phy, CHV_CMN_DW30, tmp);
|
||||
vlv_dpio_write(display->drm, phy, CHV_CMN_DW30, tmp);
|
||||
}
|
||||
|
||||
vlv_dpio_put(dev_priv);
|
||||
vlv_dpio_put(display->drm);
|
||||
|
||||
display->power.chv_phy_control |= PHY_COM_LANE_RESET_DEASSERT(phy);
|
||||
intel_de_write(display, DISPLAY_PHY_CONTROL,
|
||||
|
|
@ -1535,7 +1532,6 @@ static void chv_dpio_cmn_power_well_disable(struct intel_display *display,
|
|||
static void assert_chv_phy_powergate(struct intel_display *display, enum dpio_phy phy,
|
||||
enum dpio_channel ch, bool override, unsigned int mask)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
u32 reg, val, expected, actual;
|
||||
|
||||
/*
|
||||
|
|
@ -1553,9 +1549,9 @@ static void assert_chv_phy_powergate(struct intel_display *display, enum dpio_ph
|
|||
else
|
||||
reg = CHV_CMN_DW6_CH1;
|
||||
|
||||
vlv_dpio_get(dev_priv);
|
||||
val = vlv_dpio_read(dev_priv, phy, reg);
|
||||
vlv_dpio_put(dev_priv);
|
||||
vlv_dpio_get(display->drm);
|
||||
val = vlv_dpio_read(display->drm, phy, reg);
|
||||
vlv_dpio_put(display->drm);
|
||||
|
||||
/*
|
||||
* This assumes !override is only used when the port is disabled.
|
||||
|
|
@ -1665,14 +1661,13 @@ void chv_phy_powergate_lanes(struct intel_encoder *encoder,
|
|||
static bool chv_pipe_power_well_enabled(struct intel_display *display,
|
||||
struct i915_power_well *power_well)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
enum pipe pipe = PIPE_A;
|
||||
bool enabled;
|
||||
u32 state, ctrl;
|
||||
|
||||
vlv_punit_get(dev_priv);
|
||||
vlv_punit_get(display->drm);
|
||||
|
||||
state = vlv_punit_read(dev_priv, PUNIT_REG_DSPSSPM) & DP_SSS_MASK(pipe);
|
||||
state = vlv_punit_read(display->drm, PUNIT_REG_DSPSSPM) & DP_SSS_MASK(pipe);
|
||||
/*
|
||||
* We only ever set the power-on and power-gate states, anything
|
||||
* else is unexpected.
|
||||
|
|
@ -1685,10 +1680,10 @@ static bool chv_pipe_power_well_enabled(struct intel_display *display,
|
|||
* A transient state at this point would mean some unexpected party
|
||||
* is poking at the power controls too.
|
||||
*/
|
||||
ctrl = vlv_punit_read(dev_priv, PUNIT_REG_DSPSSPM) & DP_SSC_MASK(pipe);
|
||||
ctrl = vlv_punit_read(display->drm, PUNIT_REG_DSPSSPM) & DP_SSC_MASK(pipe);
|
||||
drm_WARN_ON(display->drm, ctrl << 16 != state);
|
||||
|
||||
vlv_punit_put(dev_priv);
|
||||
vlv_punit_put(display->drm);
|
||||
|
||||
return enabled;
|
||||
}
|
||||
|
|
@ -1697,36 +1692,35 @@ static void chv_set_pipe_power_well(struct intel_display *display,
|
|||
struct i915_power_well *power_well,
|
||||
bool enable)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
enum pipe pipe = PIPE_A;
|
||||
u32 state;
|
||||
u32 ctrl;
|
||||
|
||||
state = enable ? DP_SSS_PWR_ON(pipe) : DP_SSS_PWR_GATE(pipe);
|
||||
|
||||
vlv_punit_get(dev_priv);
|
||||
vlv_punit_get(display->drm);
|
||||
|
||||
#define COND \
|
||||
((vlv_punit_read(dev_priv, PUNIT_REG_DSPSSPM) & DP_SSS_MASK(pipe)) == state)
|
||||
((vlv_punit_read(display->drm, PUNIT_REG_DSPSSPM) & DP_SSS_MASK(pipe)) == state)
|
||||
|
||||
if (COND)
|
||||
goto out;
|
||||
|
||||
ctrl = vlv_punit_read(dev_priv, PUNIT_REG_DSPSSPM);
|
||||
ctrl = vlv_punit_read(display->drm, PUNIT_REG_DSPSSPM);
|
||||
ctrl &= ~DP_SSC_MASK(pipe);
|
||||
ctrl |= enable ? DP_SSC_PWR_ON(pipe) : DP_SSC_PWR_GATE(pipe);
|
||||
vlv_punit_write(dev_priv, PUNIT_REG_DSPSSPM, ctrl);
|
||||
vlv_punit_write(display->drm, PUNIT_REG_DSPSSPM, ctrl);
|
||||
|
||||
if (wait_for(COND, 100))
|
||||
drm_err(display->drm,
|
||||
"timeout setting power well state %08x (%08x)\n",
|
||||
state,
|
||||
vlv_punit_read(dev_priv, PUNIT_REG_DSPSSPM));
|
||||
vlv_punit_read(display->drm, PUNIT_REG_DSPSSPM));
|
||||
|
||||
#undef COND
|
||||
|
||||
out:
|
||||
vlv_punit_put(dev_priv);
|
||||
vlv_punit_put(display->drm);
|
||||
}
|
||||
|
||||
static void chv_pipe_power_well_sync_hw(struct intel_display *display,
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -8,6 +8,7 @@
|
|||
#include "i915_drv.h"
|
||||
#include "intel_clock_gating.h"
|
||||
#include "intel_cx0_phy.h"
|
||||
#include "intel_display_core.h"
|
||||
#include "intel_display_driver.h"
|
||||
#include "intel_display_reset.h"
|
||||
#include "intel_display_types.h"
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
/* Copyright © 2025 Intel Corporation */
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "intel_display_core.h"
|
||||
#include "intel_display_rpm.h"
|
||||
#include "intel_runtime_pm.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include "gt/intel_rps.h"
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include "intel_display_core.h"
|
||||
#include "intel_display_irq.h"
|
||||
#include "intel_display_rps.h"
|
||||
#include "intel_display_types.h"
|
||||
|
|
@ -45,12 +46,13 @@ static int do_rps_boost(struct wait_queue_entry *_wait,
|
|||
void intel_display_rps_boost_after_vblank(struct drm_crtc *crtc,
|
||||
struct dma_fence *fence)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(crtc->dev);
|
||||
struct wait_rps_boost *wait;
|
||||
|
||||
if (!dma_fence_is_i915(fence))
|
||||
return;
|
||||
|
||||
if (DISPLAY_VER(to_i915(crtc->dev)) < 6)
|
||||
if (DISPLAY_VER(display) < 6)
|
||||
return;
|
||||
|
||||
if (drm_crtc_vblank_get(crtc))
|
||||
|
|
|
|||
|
|
@ -554,6 +554,10 @@ struct intel_connector {
|
|||
struct intel_dp *dp;
|
||||
} mst;
|
||||
|
||||
struct {
|
||||
int force_bpp_x16;
|
||||
} link;
|
||||
|
||||
/* Work struct to schedule a uevent on link train failure */
|
||||
struct work_struct modeset_retry_work;
|
||||
|
||||
|
|
@ -595,7 +599,7 @@ struct intel_atomic_state {
|
|||
|
||||
bool dpll_set, modeset;
|
||||
|
||||
struct intel_shared_dpll_state shared_dpll[I915_NUM_PLLS];
|
||||
struct intel_dpll_state dpll_state[I915_NUM_PLLS];
|
||||
|
||||
struct intel_dp_tunnel_inherited_state *inherited_dp_tunnels;
|
||||
|
||||
|
|
@ -1079,8 +1083,8 @@ struct intel_crtc_state {
|
|||
* haswell. */
|
||||
struct dpll dpll;
|
||||
|
||||
/* Selected dpll when shared or NULL. */
|
||||
struct intel_shared_dpll *shared_dpll;
|
||||
/* Selected dpll or NULL. */
|
||||
struct intel_dpll *intel_dpll;
|
||||
|
||||
/* Actual register state of the dpll, for shared dpll cross-checking. */
|
||||
struct intel_dpll_hw_state dpll_hw_state;
|
||||
|
|
@ -1090,7 +1094,7 @@ struct intel_crtc_state {
|
|||
* setting shared_dpll and dpll_hw_state to one of these reserved ones.
|
||||
*/
|
||||
struct icl_port_dpll {
|
||||
struct intel_shared_dpll *pll;
|
||||
struct intel_dpll *pll;
|
||||
struct intel_dpll_hw_state hw_state;
|
||||
} icl_port_dplls[ICL_PORT_DPLL_COUNT];
|
||||
|
||||
|
|
@ -1297,7 +1301,7 @@ struct intel_crtc_state {
|
|||
enum transcoder mst_master_transcoder;
|
||||
|
||||
/* For DSB based pipe updates */
|
||||
struct intel_dsb *dsb_color_vblank, *dsb_commit;
|
||||
struct intel_dsb *dsb_color, *dsb_commit;
|
||||
bool use_dsb;
|
||||
|
||||
u32 psr2_man_track_ctl;
|
||||
|
|
@ -1669,7 +1673,9 @@ struct intel_dp {
|
|||
bool use_max_params;
|
||||
u8 dpcd[DP_RECEIVER_CAP_SIZE];
|
||||
u8 psr_dpcd[EDP_PSR_RECEIVER_CAP_SIZE];
|
||||
u8 pr_dpcd;
|
||||
u8 pr_dpcd[DP_PANEL_REPLAY_CAP_SIZE];
|
||||
#define INTEL_PR_DPCD_INDEX(pr_dpcd_register) ((pr_dpcd_register) - DP_PANEL_REPLAY_CAP_SUPPORT)
|
||||
|
||||
u8 downstream_ports[DP_MAX_DOWNSTREAM_PORTS];
|
||||
u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE];
|
||||
u8 lttpr_common_caps[DP_LTTPR_COMMON_CAP_SIZE];
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include "i915_reg.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_core.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_wa.h"
|
||||
|
||||
static void gen11_display_wa_apply(struct intel_display *display)
|
||||
|
|
|
|||
|
|
@ -25,7 +25,9 @@ dkl_phy_set_hip_idx(struct intel_display *display, struct intel_dkl_phy_reg reg)
|
|||
{
|
||||
enum tc_port tc_port = DKL_REG_TC_PORT(reg);
|
||||
|
||||
drm_WARN_ON(display->drm, tc_port < TC_PORT_1 || tc_port >= I915_MAX_TC_PORTS);
|
||||
if (drm_WARN_ON(display->drm,
|
||||
tc_port < TC_PORT_1 || tc_port >= I915_MAX_TC_PORTS))
|
||||
return;
|
||||
|
||||
intel_de_write(display,
|
||||
HIP_INDEX_REG(tc_port),
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
#include <linux/types.h>
|
||||
|
||||
#include "intel_display_reg_defs.h"
|
||||
|
||||
struct intel_dkl_phy_reg {
|
||||
u32 reg:24;
|
||||
u32 bank_idx:4;
|
||||
|
|
|
|||
|
|
@ -27,9 +27,12 @@
|
|||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include "intel_crtc.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_rpm.h"
|
||||
#include "intel_display_power_well.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_rpm.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dmc.h"
|
||||
#include "intel_dmc_regs.h"
|
||||
#include "intel_step.h"
|
||||
|
|
@ -425,7 +428,7 @@ static void disable_event_handler(struct intel_display *display,
|
|||
REG_FIELD_PREP(DMC_EVT_CTL_TYPE_MASK,
|
||||
DMC_EVT_CTL_TYPE_EDGE_0_1) |
|
||||
REG_FIELD_PREP(DMC_EVT_CTL_EVENT_ID_MASK,
|
||||
DMC_EVT_CTL_EVENT_ID_FALSE));
|
||||
DMC_EVENT_FALSE));
|
||||
intel_de_write(display, htp_reg, 0);
|
||||
}
|
||||
|
||||
|
|
@ -490,6 +493,17 @@ static void pipedmc_clock_gating_wa(struct intel_display *display, bool enable)
|
|||
adlp_pipedmc_clock_gating_wa(display, enable);
|
||||
}
|
||||
|
||||
static u32 pipedmc_interrupt_mask(struct intel_display *display)
|
||||
{
|
||||
/*
|
||||
* FIXME PIPEDMC_ERROR not enabled for now due to LNL pipe B
|
||||
* triggering it during the first DC state transition. Figure
|
||||
* out what is going on...
|
||||
*/
|
||||
return PIPEDMC_GTT_FAULT |
|
||||
PIPEDMC_ATS_FAULT;
|
||||
}
|
||||
|
||||
void intel_dmc_enable_pipe(struct intel_display *display, enum pipe pipe)
|
||||
{
|
||||
enum intel_dmc_id dmc_id = PIPE_TO_DMC_ID(pipe);
|
||||
|
|
@ -497,6 +511,11 @@ void intel_dmc_enable_pipe(struct intel_display *display, enum pipe pipe)
|
|||
if (!is_valid_dmc_id(dmc_id) || !has_dmc_id_fw(display, dmc_id))
|
||||
return;
|
||||
|
||||
if (DISPLAY_VER(display) >= 20) {
|
||||
intel_de_write(display, PIPEDMC_INTERRUPT(pipe), pipedmc_interrupt_mask(display));
|
||||
intel_de_write(display, PIPEDMC_INTERRUPT_MASK(pipe), ~pipedmc_interrupt_mask(display));
|
||||
}
|
||||
|
||||
if (DISPLAY_VER(display) >= 14)
|
||||
intel_de_rmw(display, MTL_PIPEDMC_CONTROL, 0, PIPEDMC_ENABLE_MTL(pipe));
|
||||
else
|
||||
|
|
@ -514,6 +533,73 @@ void intel_dmc_disable_pipe(struct intel_display *display, enum pipe pipe)
|
|||
intel_de_rmw(display, MTL_PIPEDMC_CONTROL, PIPEDMC_ENABLE_MTL(pipe), 0);
|
||||
else
|
||||
intel_de_rmw(display, PIPEDMC_CONTROL(pipe), PIPEDMC_ENABLE, 0);
|
||||
|
||||
if (DISPLAY_VER(display) >= 20) {
|
||||
intel_de_write(display, PIPEDMC_INTERRUPT_MASK(pipe), ~0);
|
||||
intel_de_write(display, PIPEDMC_INTERRUPT(pipe), pipedmc_interrupt_mask(display));
|
||||
}
|
||||
}
|
||||
|
||||
static u32 dmc_evt_ctl_disable(void)
|
||||
{
|
||||
return REG_FIELD_PREP(DMC_EVT_CTL_TYPE_MASK,
|
||||
DMC_EVT_CTL_TYPE_EDGE_0_1) |
|
||||
REG_FIELD_PREP(DMC_EVT_CTL_EVENT_ID_MASK,
|
||||
DMC_EVENT_FALSE);
|
||||
}
|
||||
|
||||
static bool is_dmc_evt_ctl_reg(struct intel_display *display,
|
||||
enum intel_dmc_id dmc_id, i915_reg_t reg)
|
||||
{
|
||||
u32 offset = i915_mmio_reg_offset(reg);
|
||||
u32 start = i915_mmio_reg_offset(DMC_EVT_CTL(display, dmc_id, 0));
|
||||
u32 end = i915_mmio_reg_offset(DMC_EVT_CTL(display, dmc_id, DMC_EVENT_HANDLER_COUNT_GEN12));
|
||||
|
||||
return offset >= start && offset < end;
|
||||
}
|
||||
|
||||
static bool is_dmc_evt_htp_reg(struct intel_display *display,
|
||||
enum intel_dmc_id dmc_id, i915_reg_t reg)
|
||||
{
|
||||
u32 offset = i915_mmio_reg_offset(reg);
|
||||
u32 start = i915_mmio_reg_offset(DMC_EVT_HTP(display, dmc_id, 0));
|
||||
u32 end = i915_mmio_reg_offset(DMC_EVT_HTP(display, dmc_id, DMC_EVENT_HANDLER_COUNT_GEN12));
|
||||
|
||||
return offset >= start && offset < end;
|
||||
}
|
||||
|
||||
static bool is_event_handler(struct intel_display *display,
|
||||
enum intel_dmc_id dmc_id,
|
||||
unsigned int event_id,
|
||||
i915_reg_t reg, u32 data)
|
||||
{
|
||||
return is_dmc_evt_ctl_reg(display, dmc_id, reg) &&
|
||||
REG_FIELD_GET(DMC_EVT_CTL_EVENT_ID_MASK, data) == event_id;
|
||||
}
|
||||
|
||||
static void dmc_configure_event(struct intel_display *display,
|
||||
enum intel_dmc_id dmc_id,
|
||||
unsigned int event_id,
|
||||
bool enable)
|
||||
{
|
||||
struct intel_dmc *dmc = display_to_dmc(display);
|
||||
int num_handlers = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < dmc->dmc_info[dmc_id].mmio_count; i++) {
|
||||
i915_reg_t reg = dmc->dmc_info[dmc_id].mmioaddr[i];
|
||||
u32 data = dmc->dmc_info[dmc_id].mmiodata[i];
|
||||
|
||||
if (!is_event_handler(display, dmc_id, event_id, reg, data))
|
||||
continue;
|
||||
|
||||
intel_de_write(display, reg, enable ? data : dmc_evt_ctl_disable());
|
||||
num_handlers++;
|
||||
}
|
||||
|
||||
drm_WARN_ONCE(display->drm, num_handlers != 1,
|
||||
"DMC %d has %d handlers for event 0x%x\n",
|
||||
dmc_id, num_handlers, event_id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -546,42 +632,9 @@ void intel_dmc_block_pkgc(struct intel_display *display, enum pipe pipe,
|
|||
void intel_dmc_start_pkgc_exit_at_start_of_undelayed_vblank(struct intel_display *display,
|
||||
enum pipe pipe, bool enable)
|
||||
{
|
||||
u32 val;
|
||||
enum intel_dmc_id dmc_id = PIPE_TO_DMC_ID(pipe);
|
||||
|
||||
if (enable)
|
||||
val = DMC_EVT_CTL_ENABLE | DMC_EVT_CTL_RECURRING |
|
||||
REG_FIELD_PREP(DMC_EVT_CTL_TYPE_MASK,
|
||||
DMC_EVT_CTL_TYPE_EDGE_0_1) |
|
||||
REG_FIELD_PREP(DMC_EVT_CTL_EVENT_ID_MASK,
|
||||
DMC_EVT_CTL_EVENT_ID_VBLANK_A);
|
||||
else
|
||||
val = REG_FIELD_PREP(DMC_EVT_CTL_EVENT_ID_MASK,
|
||||
DMC_EVT_CTL_EVENT_ID_FALSE) |
|
||||
REG_FIELD_PREP(DMC_EVT_CTL_TYPE_MASK,
|
||||
DMC_EVT_CTL_TYPE_EDGE_0_1);
|
||||
|
||||
intel_de_write(display, MTL_PIPEDMC_EVT_CTL_4(pipe),
|
||||
val);
|
||||
}
|
||||
|
||||
static bool is_dmc_evt_ctl_reg(struct intel_display *display,
|
||||
enum intel_dmc_id dmc_id, i915_reg_t reg)
|
||||
{
|
||||
u32 offset = i915_mmio_reg_offset(reg);
|
||||
u32 start = i915_mmio_reg_offset(DMC_EVT_CTL(display, dmc_id, 0));
|
||||
u32 end = i915_mmio_reg_offset(DMC_EVT_CTL(display, dmc_id, DMC_EVENT_HANDLER_COUNT_GEN12));
|
||||
|
||||
return offset >= start && offset < end;
|
||||
}
|
||||
|
||||
static bool is_dmc_evt_htp_reg(struct intel_display *display,
|
||||
enum intel_dmc_id dmc_id, i915_reg_t reg)
|
||||
{
|
||||
u32 offset = i915_mmio_reg_offset(reg);
|
||||
u32 start = i915_mmio_reg_offset(DMC_EVT_HTP(display, dmc_id, 0));
|
||||
u32 end = i915_mmio_reg_offset(DMC_EVT_HTP(display, dmc_id, DMC_EVENT_HANDLER_COUNT_GEN12));
|
||||
|
||||
return offset >= start && offset < end;
|
||||
dmc_configure_event(display, dmc_id, PIPEDMC_EVENT_VBLANK, enable);
|
||||
}
|
||||
|
||||
static bool disable_dmc_evt(struct intel_display *display,
|
||||
|
|
@ -597,12 +650,12 @@ static bool disable_dmc_evt(struct intel_display *display,
|
|||
|
||||
/* also disable the flip queue event on the main DMC on TGL */
|
||||
if (display->platform.tigerlake &&
|
||||
REG_FIELD_GET(DMC_EVT_CTL_EVENT_ID_MASK, data) == DMC_EVT_CTL_EVENT_ID_CLK_MSEC)
|
||||
is_event_handler(display, dmc_id, MAINDMC_EVENT_CLK_MSEC, reg, data))
|
||||
return true;
|
||||
|
||||
/* also disable the HRR event on the main DMC on TGL/ADLS */
|
||||
if ((display->platform.tigerlake || display->platform.alderlake_s) &&
|
||||
REG_FIELD_GET(DMC_EVT_CTL_EVENT_ID_MASK, data) == DMC_EVT_CTL_EVENT_ID_VBLANK_A)
|
||||
is_event_handler(display, dmc_id, MAINDMC_EVENT_VBLANK_A, reg, data))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
@ -615,10 +668,7 @@ static u32 dmc_mmiodata(struct intel_display *display,
|
|||
if (disable_dmc_evt(display, dmc_id,
|
||||
dmc->dmc_info[dmc_id].mmioaddr[i],
|
||||
dmc->dmc_info[dmc_id].mmiodata[i]))
|
||||
return REG_FIELD_PREP(DMC_EVT_CTL_TYPE_MASK,
|
||||
DMC_EVT_CTL_TYPE_EDGE_0_1) |
|
||||
REG_FIELD_PREP(DMC_EVT_CTL_EVENT_ID_MASK,
|
||||
DMC_EVT_CTL_EVENT_ID_FALSE);
|
||||
return dmc_evt_ctl_disable();
|
||||
else
|
||||
return dmc->dmc_info[dmc_id].mmiodata[i];
|
||||
}
|
||||
|
|
@ -1403,3 +1453,29 @@ void intel_dmc_debugfs_register(struct intel_display *display)
|
|||
debugfs_create_file("i915_dmc_info", 0444, minor->debugfs_root,
|
||||
display, &intel_dmc_debugfs_status_fops);
|
||||
}
|
||||
|
||||
void intel_pipedmc_irq_handler(struct intel_display *display, enum pipe pipe)
|
||||
{
|
||||
struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe);
|
||||
u32 tmp;
|
||||
|
||||
if (DISPLAY_VER(display) >= 20) {
|
||||
tmp = intel_de_read(display, PIPEDMC_INTERRUPT(pipe));
|
||||
intel_de_write(display, PIPEDMC_INTERRUPT(pipe), tmp);
|
||||
|
||||
if (tmp & PIPEDMC_ATS_FAULT)
|
||||
drm_err_ratelimited(display->drm, "[CRTC:%d:%s] PIPEDMC ATS fault\n",
|
||||
crtc->base.base.id, crtc->base.name);
|
||||
if (tmp & PIPEDMC_GTT_FAULT)
|
||||
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",
|
||||
crtc->base.base.id, crtc->base.name);
|
||||
}
|
||||
|
||||
tmp = intel_de_read(display, PIPEDMC_STATUS(pipe)) & PIPEDMC_INT_VECTOR_MASK;
|
||||
if (tmp)
|
||||
drm_err(display->drm, "[CRTC:%d:%s]] PIPEDMC interrupt vector 0x%x\n",
|
||||
crtc->base.base.id, crtc->base.name, tmp);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,4 +34,6 @@ void intel_dmc_update_dc6_allowed_count(struct intel_display *display, bool star
|
|||
|
||||
void assert_dmc_loaded(struct intel_display *display);
|
||||
|
||||
void intel_pipedmc_irq_handler(struct intel_display *display, enum pipe pipe);
|
||||
|
||||
#endif /* __INTEL_DMC_H__ */
|
||||
|
|
|
|||
|
|
@ -6,7 +6,273 @@
|
|||
#ifndef __INTEL_DMC_REGS_H__
|
||||
#define __INTEL_DMC_REGS_H__
|
||||
|
||||
#include "i915_reg_defs.h"
|
||||
#include "intel_display_reg_defs.h"
|
||||
|
||||
enum dmc_event_id {
|
||||
DMC_EVENT_TRUE = 0x0,
|
||||
DMC_EVENT_FALSE = 0x1,
|
||||
};
|
||||
|
||||
enum maindmc_event_id {
|
||||
MAINDMC_EVENT_CMP_ZERO = 0x8,
|
||||
MAINDMC_EVENT_CMP_ODD = 0x9,
|
||||
MAINDMC_EVENT_CMP_NEG = 0xa,
|
||||
MAINDMC_EVENT_CMP_CARRY = 0xb,
|
||||
|
||||
MAINDMC_EVENT_TMR0_DONE = 0x14,
|
||||
MAINDMC_EVENT_TMR1_DONE = 0x15,
|
||||
MAINDMC_EVENT_TMR2_DONE = 0x16,
|
||||
MAINDMC_EVENT_COUNT0_DONE = 0x17,
|
||||
MAINDMC_EVENT_COUNT1_DONE = 0x18,
|
||||
MAINDMC_EVENT_PERF_CNTR_DARBF = 0x19,
|
||||
|
||||
MAINDMC_EVENT_SCANLINE_INRANGE_FQ_A_TRIGGER = 0x22,
|
||||
MAINDMC_EVENT_SCANLINE_INRANGE_FQ_B_TRIGGER = 0x23,
|
||||
MAINDMC_EVENT_SCANLINE_INRANGE_FQ_C_TRIGGER = 0x24,
|
||||
MAINDMC_EVENT_SCANLINE_INRANGE_FQ_D_TRIGGER = 0x25,
|
||||
MAINDMC_EVENT_1KHZ_FQ_A_TRIGGER = 0x26,
|
||||
MAINDMC_EVENT_1KHZ_FQ_B_TRIGGER = 0x27,
|
||||
MAINDMC_EVENT_1KHZ_FQ_C_TRIGGER = 0x28,
|
||||
MAINDMC_EVENT_1KHZ_FQ_D_TRIGGER = 0x29,
|
||||
MAINDMC_EVENT_SCANLINE_COMP_A = 0x2a,
|
||||
MAINDMC_EVENT_SCANLINE_COMP_B = 0x2b,
|
||||
MAINDMC_EVENT_SCANLINE_COMP_C = 0x2c,
|
||||
MAINDMC_EVENT_SCANLINE_COMP_D = 0x2d,
|
||||
MAINDMC_EVENT_VBLANK_DELAYED_A = 0x2e,
|
||||
MAINDMC_EVENT_VBLANK_DELAYED_B = 0x2f,
|
||||
MAINDMC_EVENT_VBLANK_DELAYED_C = 0x30,
|
||||
MAINDMC_EVENT_VBLANK_DELAYED_D = 0x31,
|
||||
MAINDMC_EVENT_VBLANK_A = 0x32,
|
||||
MAINDMC_EVENT_VBLANK_B = 0x33,
|
||||
MAINDMC_EVENT_VBLANK_C = 0x34,
|
||||
MAINDMC_EVENT_VBLANK_D = 0x35,
|
||||
MAINDMC_EVENT_HBLANK_A = 0x36,
|
||||
MAINDMC_EVENT_HBLANK_B = 0x37,
|
||||
MAINDMC_EVENT_HBLANK_C = 0x38,
|
||||
MAINDMC_EVENT_HBLANK_D = 0x39,
|
||||
MAINDMC_EVENT_VSYNC_A = 0x3a,
|
||||
MAINDMC_EVENT_VSYNC_B = 0x3b,
|
||||
MAINDMC_EVENT_VSYNC_C = 0x3c,
|
||||
MAINDMC_EVENT_VSYNC_D = 0x3d,
|
||||
MAINDMC_EVENT_SCANLINE_A = 0x3e,
|
||||
MAINDMC_EVENT_SCANLINE_B = 0x3f,
|
||||
MAINDMC_EVENT_SCANLINE_C = 0x40,
|
||||
MAINDMC_EVENT_SCANLINE_D = 0x41,
|
||||
|
||||
MAINDMC_EVENT_PLANE1_FLIP_A = 0x42,
|
||||
MAINDMC_EVENT_PLANE2_FLIP_A = 0x43,
|
||||
MAINDMC_EVENT_PLANE3_FLIP_A = 0x44,
|
||||
MAINDMC_EVENT_PLANE4_FLIP_A = 0x45,
|
||||
MAINDMC_EVENT_PLANE5_FLIP_A = 0x46,
|
||||
MAINDMC_EVENT_PLANE6_FLIP_A = 0x47,
|
||||
MAINDMC_EVENT_PLANE7_FLIP_A = 0x48,
|
||||
MAINDMC_EVENT_PLANE1_FLIP_B = 0x49,
|
||||
MAINDMC_EVENT_PLANE2_FLIP_B = 0x4a,
|
||||
MAINDMC_EVENT_PLANE3_FLIP_B = 0x4b,
|
||||
MAINDMC_EVENT_PLANE4_FLIP_B = 0x4c,
|
||||
MAINDMC_EVENT_PLANE5_FLIP_B = 0x4d,
|
||||
MAINDMC_EVENT_PLANE6_FLIP_B = 0x4e,
|
||||
MAINDMC_EVENT_PLANE7_FLIP_B = 0x4f,
|
||||
MAINDMC_EVENT_PLANE1_FLIP_C = 0x50,
|
||||
MAINDMC_EVENT_PLANE2_FLIP_C = 0x51,
|
||||
MAINDMC_EVENT_PLANE3_FLIP_C = 0x52,
|
||||
MAINDMC_EVENT_PLANE4_FLIP_C = 0x53,
|
||||
MAINDMC_EVENT_PLANE5_FLIP_C = 0x54,
|
||||
MAINDMC_EVENT_PLANE6_FLIP_C = 0x55,
|
||||
MAINDMC_EVENT_PLANE7_FLIP_C = 0x56,
|
||||
MAINDMC_EVENT_PLANE1_FLIP_D = 0x57,
|
||||
MAINDMC_EVENT_PLANE2_FLIP_D = 0x58,
|
||||
MAINDMC_EVENT_PLANE3_FLIP_D = 0x59,
|
||||
MAINDMC_EVENT_PLANE4_FLIP_D = 0x5a,
|
||||
MAINDMC_EVENT_PLANE5_FLIP_D = 0x5b,
|
||||
MAINDMC_EVENT_PLANE6_FLIP_D = 0x5c,
|
||||
MAINDMC_EVENT_PLANE7_FLIP_D = 0x5d,
|
||||
MAINDMC_EVENT_PLANE1_FLIP_DONE_A = 0x5e,
|
||||
MAINDMC_EVENT_PLANE2_FLIP_DONE_A = 0x5f,
|
||||
MAINDMC_EVENT_PLANE3_FLIP_DONE_A = 0x60,
|
||||
MAINDMC_EVENT_PLANE4_FLIP_DONE_A = 0x61,
|
||||
MAINDMC_EVENT_PLANE5_FLIP_DONE_A = 0x62,
|
||||
MAINDMC_EVENT_PLANE6_FLIP_DONE_A = 0x63,
|
||||
MAINDMC_EVENT_PLANE7_FLIP_DONE_A = 0x64,
|
||||
MAINDMC_EVENT_PLANE1_FLIP_DONE_B = 0x65,
|
||||
MAINDMC_EVENT_PLANE2_FLIP_DONE_B = 0x66,
|
||||
MAINDMC_EVENT_PLANE3_FLIP_DONE_B = 0x67,
|
||||
MAINDMC_EVENT_PLANE4_FLIP_DONE_B = 0x68,
|
||||
MAINDMC_EVENT_PLANE5_FLIP_DONE_B = 0x69,
|
||||
MAINDMC_EVENT_PLANE6_FLIP_DONE_B = 0x6a,
|
||||
MAINDMC_EVENT_PLANE7_FLIP_DONE_B = 0x6b,
|
||||
MAINDMC_EVENT_PLANE1_FLIP_DONE_C = 0x6c,
|
||||
MAINDMC_EVENT_PLANE2_FLIP_DONE_C = 0x6d,
|
||||
MAINDMC_EVENT_PLANE3_FLIP_DONE_C = 0x6e,
|
||||
MAINDMC_EVENT_PLANE4_FLIP_DONE_C = 0x6f,
|
||||
MAINDMC_EVENT_PLANE5_FLIP_DONE_C = 0x70,
|
||||
MAINDMC_EVENT_PLANE6_FLIP_DONE_C = 0x71,
|
||||
MAINDMC_EVENT_PLANE7_FLIP_DONE_C = 0x72,
|
||||
MAINDMC_EVENT_PLANE1_FLIP_DONE_D = 0x73,
|
||||
MAINDMC_EVENT_PLANE2_FLIP_DONE_D = 0x74,
|
||||
MAINDMC_EVENT_PLANE3_FLIP_DONE_D = 0x75,
|
||||
MAINDMC_EVENT_PLANE4_FLIP_DONE_D = 0x76,
|
||||
MAINDMC_EVENT_PLANE5_FLIP_DONE_D = 0x77,
|
||||
MAINDMC_EVENT_PLANE6_FLIP_DONE_D = 0x78,
|
||||
MAINDMC_EVENT_PLANE7_FLIP_DONE_D = 0x79,
|
||||
|
||||
MAINDMC_EVENT_WIDI_GTT_FAULT_SL1 = 0x7d,
|
||||
MAINDMC_EVENT_WIDI_GTT_FAULT_SL2 = 0x7e,
|
||||
MAINDMC_EVENT_WIDI_CAP_ACTIVE_SL1 = 0x7f,
|
||||
MAINDMC_EVENT_WIDI_CAP_ACTIVE_SL2 = 0x80,
|
||||
|
||||
MAINDMC_EVENT_RENUKE_A = 0x85,
|
||||
MAINDMC_EVENT_RENUKE_B = 0x86,
|
||||
MAINDMC_EVENT_RENUKE_C = 0x87,
|
||||
MAINDMC_EVENT_RENUKE_D = 0x88,
|
||||
MAINDMC_EVENT_DPFC_FIFO_FULL_A = 0x89,
|
||||
MAINDMC_EVENT_DPFC_FIFO_FULL_B = 0x8a,
|
||||
MAINDMC_EVENT_DPFC_FIFO_FULL_C = 0x8b,
|
||||
MAINDMC_EVENT_DPFC_FIFO_FULL_D = 0x8c,
|
||||
MAINDMC_EVENT_DPFC_PIXEL_CNT_MISMATCH_A = 0x8d,
|
||||
MAINDMC_EVENT_DPFC_PIXEL_CNT_MISMATCH_B = 0x8e,
|
||||
MAINDMC_EVENT_DPFC_PIXEL_CNT_MISMATCH_C = 0x8f,
|
||||
MAINDMC_EVENT_DPFC_PIXEL_CNT_MISMATCH_D = 0x90,
|
||||
MAINDMC_EVENT_DPFC_COMPTAG_UNDERRUN_A = 0x91,
|
||||
MAINDMC_EVENT_DPFC_COMPTAG_UNDERRUN_B = 0x92,
|
||||
MAINDMC_EVENT_DPFC_COMPTAG_UNDERRUN_C = 0x93,
|
||||
MAINDMC_EVENT_DPFC_COMPTAG_UNDERRUN_D = 0x94,
|
||||
MAINDMC_EVENT_DPFC_FIFO_NOT_EMPTY_A = 0x95,
|
||||
MAINDMC_EVENT_DPFC_FIFO_NOT_EMPTY_B = 0x96,
|
||||
MAINDMC_EVENT_DPFC_FIFO_NOT_EMPTY_C = 0x97,
|
||||
MAINDMC_EVENT_DPFC_FIFO_NOT_EMPTY_D = 0x98,
|
||||
MAINDMC_EVENT_DPFC_COMPTAG_MISMATCH_A = 0x99,
|
||||
MAINDMC_EVENT_DPFC_COMPTAG_MISMATCH_B = 0x9a,
|
||||
MAINDMC_EVENT_DPFC_COMPTAG_MISMATCH_C = 0x9b,
|
||||
MAINDMC_EVENT_DPFC_COMPTAG_MISMATCH_D = 0x9c,
|
||||
MAINDMC_EVENT_DISP_PCH_INT = 0x9d,
|
||||
MAINDMC_EVENT_GTT_ERR = 0x9e,
|
||||
MAINDMC_EVENT_VTD_ERR = 0x9f,
|
||||
MAINDMC_EVENT_FULL_FQ_WAKE_TRIGGER_A = 0xa0,
|
||||
MAINDMC_EVENT_FULL_FQ_WAKE_TRIGGER_B = 0xa1,
|
||||
MAINDMC_EVENT_FULL_FQ_WAKE_TRIGGER_C = 0xa2,
|
||||
MAINDMC_EVENT_FULL_FQ_WAKE_TRIGGER_D = 0xa3,
|
||||
MAINDMC_EVENT_PIPEDMC_CHICKEN_FW_EVENT_A = 0xa4,
|
||||
MAINDMC_EVENT_PIPEDMC_CHICKEN_FW_EVENT_B = 0xa5,
|
||||
MAINDMC_EVENT_PIPEDMC_CHICKEN_FW_EVENT_C = 0xa6,
|
||||
MAINDMC_EVENT_PIPEDMC_CHICKEN_FW_EVENT_D = 0xa7,
|
||||
|
||||
MAINDMC_EVENT_DC_CLOCK_OFF_START_EDP = 0xb2,
|
||||
MAINDMC_EVENT_DC_CLOCK_OFF_START_DSI = 0xb3,
|
||||
MAINDMC_EVENT_DCPR_DMC_CSR_START = 0xb4,
|
||||
MAINDMC_EVENT_IN_PSR = 0xb5,
|
||||
|
||||
MAINDMC_EVENT_IN_MEMUP = 0xb7,
|
||||
MAINDMC_EVENT_IN_VGA = 0xb8,
|
||||
|
||||
MAINDMC_EVENT_IN_KVM_SESSION = 0xba,
|
||||
MAINDMC_EVENT_DEWAKE = 0xbb,
|
||||
|
||||
MAINDMC_EVENT_TRAP_HIT = 0xbd,
|
||||
MAINDMC_EVENT_CLK_USEC = 0xbe,
|
||||
MAINDMC_EVENT_CLK_MSEC = 0xbf,
|
||||
|
||||
MAINDMC_EVENT_CHICKEN1 = 0xc8,
|
||||
MAINDMC_EVENT_CHICKEN2 = 0xc9,
|
||||
MAINDMC_EVENT_CHICKEN3 = 0xca,
|
||||
MAINDMC_EVENT_DDT_UBP = 0xcb,
|
||||
|
||||
MAINDMC_EVENT_HP_LATENCY = 0xcd,
|
||||
MAINDMC_EVENT_LP_LATENCY = 0xce,
|
||||
MAINDMC_EVENT_WIDI_LP_REQ_SL1 = 0xcf,
|
||||
MAINDMC_EVENT_WIDI_LP_REQ_SL2 = 0xd0,
|
||||
|
||||
MAINDMC_EVENT_DG_DMC_EVT_0 = 0xd3,
|
||||
MAINDMC_EVENT_DG_DMC_EVT_1 = 0xd4,
|
||||
MAINDMC_EVENT_DG_DMC_EVT_2 = 0xd5,
|
||||
MAINDMC_EVENT_DG_DMC_EVT_3 = 0xd6,
|
||||
MAINDMC_EVENT_DG_DMC_EVT_4 = 0xd7,
|
||||
MAINDMC_EVENT_DACFE_CLK_STOP = 0xd8,
|
||||
MAINDMC_EVENT_DACFE_AZILIA_SDI_WAKE = 0xd9,
|
||||
MAINDMC_EVENT_AUDIO_DOUBLE_FUNC_GRP_RST = 0xda,
|
||||
MAINDMC_EVENT_AUDIO_CMD_VALID = 0xdb,
|
||||
MAINDMC_EVENT_AUDIO_FRM_SYNC_BCLK = 0xdc,
|
||||
MAINDMC_EVENT_AUDIO_FRM_SYNC_CDCLK = 0xdd,
|
||||
MAINDMC_EVENT_AUDIO_PRESENCE_DETECT_A = 0xde,
|
||||
MAINDMC_EVENT_AUDIO_PRESENCE_DETECT_B = 0xdf,
|
||||
MAINDMC_EVENT_AUDIO_PRESENCE_DETECT_C = 0xe0,
|
||||
MAINDMC_EVENT_AUDIO_PRESENCE_DETECT_E = 0xe1,
|
||||
MAINDMC_EVENT_CMTG_SCANLINE_IN_GB_DC6v = 0xe2,
|
||||
MAINDMC_EVENT_DCPR_CMTG_SCANLINE_OUTSIDE_GB = 0xe3,
|
||||
MAINDMC_EVENT_DC6v_BACKWARD_COMPAT = 0xe4,
|
||||
MAINDMC_EVENT_DPMA_PM_ABORT = 0xe5,
|
||||
|
||||
MAINDMC_EVENT_STACK_OVF = 0xfc,
|
||||
MAINDMC_EVENT_NO_CLAIM = 0xfd,
|
||||
MAINDMC_EVENT_UNK_CMD = 0xfe,
|
||||
MAINDMC_EVENT_HTP_MOD = 0xff,
|
||||
};
|
||||
|
||||
enum pipedmc_event_id {
|
||||
PIPEDMC_EVENT_TMR0_DONE = 0x14,
|
||||
PIPEDMC_EVENT_TMR1_DONE = 0x15,
|
||||
PIPEDMC_EVENT_TMR2_DONE = 0x16,
|
||||
PIPEDMC_EVENT_COUNT0_DONE = 0x17,
|
||||
PIPEDMC_EVENT_COUNT1_DONE = 0x18,
|
||||
PIPEDMC_EVENT_PGA_PGB_RESTORE_DONE = 0x19,
|
||||
PIPEDMC_EVENT_PG1_PG2_RESTORE_DONE = 0x1a,
|
||||
PIPEDMC_EVENT_PGA_PGB_SAVE_DONE = 0x1b,
|
||||
PIPEDMC_EVENT_PG1_PG2_SAVE_DONE = 0x1c,
|
||||
|
||||
PIPEDMC_EVENT_FULL_FQ_WAKE_TRIGGER = 0x2b,
|
||||
PIPEDMC_EVENT_1KHZ_FQ_TRIGGER = 0x2c,
|
||||
PIPEDMC_EVENT_SCANLINE_INRANGE_FQ_TRIGGER = 0x2d,
|
||||
PIPEDMC_EVENT_SCANLINE_INRANGE = 0x2e,
|
||||
PIPEDMC_EVENT_SCANLINE_OUTRANGE = 0x2f,
|
||||
PIPEDMC_EVENT_SCANLINE_EQUAL = 0x30,
|
||||
PIPEDMC_EVENT_DELAYED_VBLANK = 0x31,
|
||||
PIPEDMC_EVENT_VBLANK = 0x32,
|
||||
PIPEDMC_EVENT_HBLANK = 0x33,
|
||||
PIPEDMC_EVENT_VSYNC = 0x34,
|
||||
PIPEDMC_EVENT_SCANLINE_FROM_DMUX = 0x35,
|
||||
PIPEDMC_EVENT_PLANE1_FLIP = 0x36,
|
||||
PIPEDMC_EVENT_PLANE2_FLIP = 0x37,
|
||||
PIPEDMC_EVENT_PLANE3_FLIP = 0x38,
|
||||
PIPEDMC_EVENT_PLANE4_FLIP = 0x39,
|
||||
PIPEDMC_EVENT_PLANE5_FLIP = 0x3a,
|
||||
PIPEDMC_EVENT_PLANE6_FLIP = 0x3b,
|
||||
PIPEDMC_EVENT_PLANE7_FLIP = 0x3c,
|
||||
PIPEDMC_EVENT_ADAPTIVE_DCB_TRIGGER = 0x3d,
|
||||
|
||||
PIPEDMC_EVENT_PLANE1_FLIP_DONE = 0x56,
|
||||
PIPEDMC_EVENT_PLANE2_FLIP_DONE = 0x57,
|
||||
PIPEDMC_EVENT_PLANE3_FLIP_DONE = 0x58,
|
||||
PIPEDMC_EVENT_PLANE4_FLIP_DONE = 0x59,
|
||||
PIPEDMC_EVENT_PLANE5_FLIP_DONE = 0x5a,
|
||||
PIPEDMC_EVENT_PLANE6_FLIP_DONE = 0x5b,
|
||||
PIPEDMC_EVENT_PLANE7_FLIP_DONE = 0x5c,
|
||||
|
||||
PIPEDMC_EVENT_GTT_ERR = 0x9b,
|
||||
|
||||
PIPEDMC_EVENT_IN_PSR = 0xb5,
|
||||
PIPEDMC_EVENT_DSI_DMC_IDLE = 0xb6,
|
||||
PIPEDMC_EVENT_PSR2_DMC_IDLE = 0xb7,
|
||||
PIPEDMC_EVENT_IN_VGA = 0xb8,
|
||||
|
||||
PIPEDMC_EVENT_TRAP_HIT = 0xbd,
|
||||
PIPEDMC_EVENT_CLK_USEC = 0xbe,
|
||||
PIPEDMC_EVENT_CLK_MSEC = 0xbf,
|
||||
|
||||
PIPEDMC_EVENT_CHICKEN1 = 0xc8,
|
||||
PIPEDMC_EVENT_CHICKEN2 = 0xc9,
|
||||
PIPEDMC_EVENT_CHICKEN3 = 0xca,
|
||||
PIPEDMC_EVENT_DDT_UBP = 0xcb,
|
||||
|
||||
PIPEDMC_EVENT_LP_LATENCY = 0xce,
|
||||
|
||||
PIPEDMC_EVENT_LACE_PART_A_HIST_TRIGGER = 0xdf,
|
||||
PIPEDMC_EVENT_LACE_PART_B_HIST_TRIGGER = 0xe0,
|
||||
|
||||
PIPEDMC_EVENT_STACK_OVF = 0xfc,
|
||||
PIPEDMC_EVENT_NO_CLAIM = 0xfd,
|
||||
PIPEDMC_EVENT_UNK_CMD = 0xfe,
|
||||
PIPEDMC_EVENT_HTP_MOD = 0xff,
|
||||
};
|
||||
|
||||
#define DMC_PROGRAM(addr, i) _MMIO((addr) + (i) * 4)
|
||||
#define DMC_SSP_BASE_ADDR_GEN9 0x00002FC0
|
||||
|
|
@ -21,11 +287,27 @@
|
|||
#define MTL_PIPEDMC_CONTROL _MMIO(0x45250)
|
||||
#define PIPEDMC_ENABLE_MTL(pipe) REG_BIT(((pipe) - PIPE_A) * 4)
|
||||
|
||||
#define _MTL_PIPEDMC_EVT_CTL_4_A 0x5f044
|
||||
#define _MTL_PIPEDMC_EVT_CTL_4_B 0x5f444
|
||||
#define MTL_PIPEDMC_EVT_CTL_4(pipe) _MMIO_PIPE(pipe, \
|
||||
_MTL_PIPEDMC_EVT_CTL_4_A, \
|
||||
_MTL_PIPEDMC_EVT_CTL_4_B)
|
||||
#define _PIPEDMC_STATUS_A 0x5f06c
|
||||
#define _PIPEDMC_STATUS_B 0x5f46c
|
||||
#define PIPEDMC_STATUS(pipe) _MMIO_PIPE((pipe), _PIPEDMC_STATUS_A, _PIPEDMC_STATUS_B)
|
||||
#define PIPEDMC_SSP REG_GENMASK(31, 16)
|
||||
#define PIPEDMC_INT_VECTOR_MASK REG_GENMASK(15, 8)
|
||||
/* PIPEDMC_INT_VECTOR values defined by firmware */
|
||||
#define PIPEDMC_INT_VECTOR_SCANLINE_COMP_ERROR REG_FIELD_PREP(PIPEDMC_INT_VECTOR_MASK, 0x1)
|
||||
#define PIPEDMC_INT_VECTOR_DC6V_FLIPQ_OVERLAP_ERROR REG_FIELD_PREP(PIPEDMC_INT_VECTOR_MASK, 0x2)
|
||||
#define PIPEDMC_INT_VECTOR_FLIPQ_PROG_DONE REG_FIELD_PREP(PIPEDMC_INT_VECTOR_MASK, 0xff) /* Wa_16018781658:lnl[a0] */
|
||||
#define PIPEDMC_EVT_PENDING REG_GENMASK(7, 0)
|
||||
|
||||
#define _PIPEDMC_INTERRUPT_A 0x5f190 /* lnl+ */
|
||||
#define _PIPEDMC_INTERRUPT_B 0x5f590 /* lnl+ */
|
||||
#define PIPEDMC_INTERRUPT(pipe) _MMIO_PIPE((pipe), _PIPEDMC_INTERRUPT_A, _PIPEDMC_INTERRUPT_B)
|
||||
#define _PIPEDMC_INTERRUPT_MASK_A 0x5f194 /* lnl+ */
|
||||
#define _PIPEDMC_INTERRUPT_MASK_B 0x5f594 /* lnl+ */
|
||||
#define PIPEDMC_INTERRUPT_MASK(pipe) _MMIO_PIPE((pipe), _PIPEDMC_INTERRUPT_MASK_A, _PIPEDMC_INTERRUPT_MASK_B)
|
||||
#define PIPEDMC_FLIPQ_PROG_DONE REG_BIT(3)
|
||||
#define PIPEDMC_ERROR REG_BIT(2)
|
||||
#define PIPEDMC_GTT_FAULT REG_BIT(1)
|
||||
#define PIPEDMC_ATS_FAULT REG_BIT(0)
|
||||
|
||||
#define PIPEDMC_BLOCK_PKGC_SW_A 0x5f1d0
|
||||
#define PIPEDMC_BLOCK_PKGC_SW_B 0x5F5d0
|
||||
|
|
@ -71,12 +353,7 @@
|
|||
#define DMC_EVT_CTL_TYPE_LEVEL_1 1
|
||||
#define DMC_EVT_CTL_TYPE_EDGE_1_0 2
|
||||
#define DMC_EVT_CTL_TYPE_EDGE_0_1 3
|
||||
|
||||
#define DMC_EVT_CTL_EVENT_ID_MASK REG_GENMASK(15, 8)
|
||||
#define DMC_EVT_CTL_EVENT_ID_FALSE 0x01
|
||||
#define DMC_EVT_CTL_EVENT_ID_VBLANK_A 0x32 /* main DMC */
|
||||
/* An event handler scheduled to run at a 1 kHz frequency. */
|
||||
#define DMC_EVT_CTL_EVENT_ID_CLK_MSEC 0xbf
|
||||
|
||||
#define DMC_HTP_ADDR_SKL 0x00500034
|
||||
#define DMC_SSP_BASE _MMIO(0x8F074)
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@
|
|||
#include <drm/drm_print.h>
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_dmc_regs.h"
|
||||
#include "intel_dmc_wl.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@
|
|||
|
||||
#include <linux/export.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/log2.h>
|
||||
#include <linux/math.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/seq_buf.h>
|
||||
#include <linux/slab.h>
|
||||
|
|
@ -34,7 +36,6 @@
|
|||
#include <linux/string_helpers.h>
|
||||
#include <linux/timekeeping.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
#include <drm/display/drm_dp_helper.h>
|
||||
|
|
@ -49,8 +50,6 @@
|
|||
#include <drm/drm_probe_helper.h>
|
||||
|
||||
#include "g4x_dp.h"
|
||||
#include "i915_irq.h"
|
||||
#include "i915_reg.h"
|
||||
#include "i915_utils.h"
|
||||
#include "intel_alpm.h"
|
||||
#include "intel_atomic.h"
|
||||
|
|
@ -64,6 +63,7 @@
|
|||
#include "intel_ddi.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_driver.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_rpm.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dp.h"
|
||||
|
|
@ -847,7 +847,7 @@ small_joiner_ram_size_bits(struct intel_display *display)
|
|||
return 6144 * 8;
|
||||
}
|
||||
|
||||
u32 intel_dp_dsc_nearest_valid_bpp(struct intel_display *display, u32 bpp, u32 pipe_bpp)
|
||||
static u32 intel_dp_dsc_nearest_valid_bpp(struct intel_display *display, u32 bpp, u32 pipe_bpp)
|
||||
{
|
||||
u32 bits_per_pixel = bpp;
|
||||
int i;
|
||||
|
|
@ -939,6 +939,7 @@ static u32 ultrajoiner_ram_max_bpp(u32 mode_hdisplay)
|
|||
return ultrajoiner_ram_bits() / mode_hdisplay;
|
||||
}
|
||||
|
||||
/* TODO: return a bpp_x16 value */
|
||||
static
|
||||
u32 get_max_compressed_bpp_with_joiner(struct intel_display *display,
|
||||
u32 mode_clock, u32 mode_hdisplay,
|
||||
|
|
@ -955,6 +956,7 @@ u32 get_max_compressed_bpp_with_joiner(struct intel_display *display,
|
|||
return max_bpp;
|
||||
}
|
||||
|
||||
/* TODO: return a bpp_x16 value */
|
||||
u16 intel_dp_dsc_get_max_compressed_bpp(struct intel_display *display,
|
||||
u32 link_clock, u32 lane_count,
|
||||
u32 mode_clock, u32 mode_hdisplay,
|
||||
|
|
@ -1195,7 +1197,7 @@ intel_dp_output_format(struct intel_connector *connector,
|
|||
int intel_dp_min_bpp(enum intel_output_format output_format)
|
||||
{
|
||||
if (output_format == INTEL_OUTPUT_FORMAT_RGB)
|
||||
return 6 * 3;
|
||||
return intel_display_min_pipe_bpp();
|
||||
else
|
||||
return 8 * 3;
|
||||
}
|
||||
|
|
@ -2067,7 +2069,7 @@ int intel_dp_dsc_sink_max_compressed_bpp(const struct intel_connector *connector
|
|||
pipe_config, bpc) >> 4;
|
||||
}
|
||||
|
||||
static int dsc_src_min_compressed_bpp(void)
|
||||
int intel_dp_dsc_min_src_compressed_bpp(void)
|
||||
{
|
||||
/* Min Compressed bpp supported by source is 8 */
|
||||
return 8;
|
||||
|
|
@ -2099,7 +2101,7 @@ static int dsc_src_max_compressed_bpp(struct intel_dp *intel_dp)
|
|||
/*
|
||||
* Note: for pre-13 display you still need to check the validity of each step.
|
||||
*/
|
||||
static int intel_dp_dsc_bpp_step_x16(const struct intel_connector *connector)
|
||||
int intel_dp_dsc_bpp_step_x16(const struct intel_connector *connector)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(connector);
|
||||
u8 incr = drm_dp_dsc_sink_bpp_incr(connector->dp.dsc_dpcd);
|
||||
|
|
@ -2107,12 +2109,19 @@ static int intel_dp_dsc_bpp_step_x16(const struct intel_connector *connector)
|
|||
if (DISPLAY_VER(display) < 14 || !incr)
|
||||
return fxp_q4_from_int(1);
|
||||
|
||||
if (connector->mst.dp &&
|
||||
!connector->link.force_bpp_x16 && !connector->mst.dp->force_dsc_fractional_bpp_en)
|
||||
return fxp_q4_from_int(1);
|
||||
|
||||
/* fxp q4 */
|
||||
return fxp_q4_from_int(1) / incr;
|
||||
}
|
||||
|
||||
/* Note: This is not universally usable! */
|
||||
static bool intel_dp_dsc_valid_bpp(struct intel_dp *intel_dp, int bpp_x16)
|
||||
/*
|
||||
* Note: for bpp_x16 to be valid it must be also within the source/sink's
|
||||
* min..max bpp capability range.
|
||||
*/
|
||||
bool intel_dp_dsc_valid_compressed_bpp(struct intel_dp *intel_dp, int bpp_x16)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
int i;
|
||||
|
|
@ -2150,24 +2159,16 @@ static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp,
|
|||
const struct intel_connector *connector = to_intel_connector(conn_state->connector);
|
||||
const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
|
||||
int output_bpp;
|
||||
int dsc_min_bpp;
|
||||
int dsc_max_bpp;
|
||||
int min_bpp_x16, max_bpp_x16, bpp_step_x16;
|
||||
int dsc_joiner_max_bpp;
|
||||
int num_joined_pipes = intel_crtc_num_joined_pipes(pipe_config);
|
||||
int bpp_x16;
|
||||
int ret;
|
||||
|
||||
dsc_min_bpp = fxp_q4_to_int_roundup(limits->link.min_bpp_x16);
|
||||
|
||||
dsc_joiner_max_bpp = get_max_compressed_bpp_with_joiner(display, adjusted_mode->clock,
|
||||
adjusted_mode->hdisplay,
|
||||
num_joined_pipes);
|
||||
dsc_max_bpp = min(dsc_joiner_max_bpp, fxp_q4_to_int(limits->link.max_bpp_x16));
|
||||
|
||||
/* FIXME: remove the round trip via integers */
|
||||
min_bpp_x16 = fxp_q4_from_int(dsc_min_bpp);
|
||||
max_bpp_x16 = fxp_q4_from_int(dsc_max_bpp);
|
||||
max_bpp_x16 = min(fxp_q4_from_int(dsc_joiner_max_bpp), limits->link.max_bpp_x16);
|
||||
|
||||
bpp_step_x16 = intel_dp_dsc_bpp_step_x16(connector);
|
||||
|
||||
|
|
@ -2175,8 +2176,12 @@ static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp,
|
|||
output_bpp = intel_dp_output_bpp(pipe_config->output_format, pipe_bpp);
|
||||
max_bpp_x16 = min(max_bpp_x16, fxp_q4_from_int(output_bpp) - bpp_step_x16);
|
||||
|
||||
drm_WARN_ON(display->drm, !is_power_of_2(bpp_step_x16));
|
||||
min_bpp_x16 = round_up(limits->link.min_bpp_x16, bpp_step_x16);
|
||||
max_bpp_x16 = round_down(max_bpp_x16, bpp_step_x16);
|
||||
|
||||
for (bpp_x16 = max_bpp_x16; bpp_x16 >= min_bpp_x16; bpp_x16 -= bpp_step_x16) {
|
||||
if (!intel_dp_dsc_valid_bpp(intel_dp, bpp_x16))
|
||||
if (!intel_dp_dsc_valid_compressed_bpp(intel_dp, bpp_x16))
|
||||
continue;
|
||||
|
||||
ret = dsc_compute_link_config(intel_dp,
|
||||
|
|
@ -2479,7 +2484,7 @@ intel_dp_compute_config_link_bpp_limits(struct intel_dp *intel_dp,
|
|||
int dsc_src_min_bpp, dsc_sink_min_bpp, dsc_min_bpp;
|
||||
int dsc_src_max_bpp, dsc_sink_max_bpp, dsc_max_bpp;
|
||||
|
||||
dsc_src_min_bpp = dsc_src_min_compressed_bpp();
|
||||
dsc_src_min_bpp = intel_dp_dsc_min_src_compressed_bpp();
|
||||
dsc_sink_min_bpp = intel_dp_dsc_sink_min_compressed_bpp(crtc_state);
|
||||
dsc_min_bpp = max(dsc_src_min_bpp, dsc_sink_min_bpp);
|
||||
limits->link.min_bpp_x16 = fxp_q4_from_int(dsc_min_bpp);
|
||||
|
|
@ -5785,6 +5790,28 @@ intel_dp_detect_sdp_caps(struct intel_dp *intel_dp)
|
|||
drm_dp_as_sdp_supported(&intel_dp->aux, intel_dp->dpcd);
|
||||
}
|
||||
|
||||
static bool intel_dp_needs_dpcd_probe(struct intel_dp *intel_dp, bool force_on_external)
|
||||
{
|
||||
struct intel_connector *connector = intel_dp->attached_connector;
|
||||
|
||||
if (intel_dp_is_edp(intel_dp))
|
||||
return false;
|
||||
|
||||
if (force_on_external)
|
||||
return true;
|
||||
|
||||
if (intel_dp->is_mst)
|
||||
return false;
|
||||
|
||||
return drm_edid_has_quirk(&connector->base, DRM_EDID_QUIRK_DP_DPCD_PROBE);
|
||||
}
|
||||
|
||||
void intel_dp_dpcd_set_probe(struct intel_dp *intel_dp, bool force_on_external)
|
||||
{
|
||||
drm_dp_dpcd_set_probe(&intel_dp->aux,
|
||||
intel_dp_needs_dpcd_probe(intel_dp, force_on_external));
|
||||
}
|
||||
|
||||
static int
|
||||
intel_dp_detect(struct drm_connector *_connector,
|
||||
struct drm_modeset_acquire_ctx *ctx,
|
||||
|
|
@ -5913,6 +5940,8 @@ intel_dp_detect(struct drm_connector *_connector,
|
|||
if (status != connector_status_connected && !intel_dp->is_mst)
|
||||
intel_dp_unset_edid(intel_dp);
|
||||
|
||||
intel_dp_dpcd_set_probe(intel_dp, false);
|
||||
|
||||
if (!intel_dp_is_edp(intel_dp))
|
||||
drm_dp_set_subconnector_property(&connector->base,
|
||||
status,
|
||||
|
|
@ -5943,6 +5972,8 @@ intel_dp_force(struct drm_connector *_connector)
|
|||
return;
|
||||
|
||||
intel_dp_set_edid(intel_dp);
|
||||
|
||||
intel_dp_dpcd_set_probe(intel_dp, false);
|
||||
}
|
||||
|
||||
static int intel_dp_get_modes(struct drm_connector *_connector)
|
||||
|
|
@ -6315,10 +6346,11 @@ intel_dp_hpd_pulse(struct intel_digital_port *dig_port, bool long_hpd)
|
|||
* complete the DP tunnel BW request for the latter connector/encoder
|
||||
* waiting for this encoder's DPRX read, perform a dummy read here.
|
||||
*/
|
||||
if (long_hpd)
|
||||
if (long_hpd) {
|
||||
intel_dp_dpcd_set_probe(intel_dp, true);
|
||||
|
||||
intel_dp_read_dprx_caps(intel_dp, dpcd);
|
||||
|
||||
if (long_hpd) {
|
||||
intel_dp->reset_link_params = true;
|
||||
intel_dp_invalidate_source_oui(intel_dp);
|
||||
|
||||
|
|
|
|||
|
|
@ -147,6 +147,7 @@ int intel_dp_dsc_sink_min_compressed_bpp(const struct intel_crtc_state *pipe_con
|
|||
int intel_dp_dsc_sink_max_compressed_bpp(const struct intel_connector *connector,
|
||||
const struct intel_crtc_state *pipe_config,
|
||||
int bpc);
|
||||
bool intel_dp_dsc_valid_compressed_bpp(struct intel_dp *intel_dp, int bpp_x16);
|
||||
u8 intel_dp_dsc_get_slice_count(const struct intel_connector *connector,
|
||||
int mode_clock, int mode_hdisplay,
|
||||
int num_joined_pipes);
|
||||
|
|
@ -173,8 +174,6 @@ bool intel_dp_supports_dsc(struct intel_dp *intel_dp,
|
|||
const struct intel_connector *connector,
|
||||
const struct intel_crtc_state *crtc_state);
|
||||
|
||||
u32 intel_dp_dsc_nearest_valid_bpp(struct intel_display *display, u32 bpp, u32 pipe_bpp);
|
||||
|
||||
void intel_ddi_update_pipe(struct intel_atomic_state *state,
|
||||
struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
|
|
@ -209,7 +208,11 @@ bool intel_dp_has_connector(struct intel_dp *intel_dp,
|
|||
const struct drm_connector_state *conn_state);
|
||||
int intel_dp_dsc_max_src_input_bpc(struct intel_display *display);
|
||||
int intel_dp_dsc_min_src_input_bpc(void);
|
||||
int intel_dp_dsc_min_src_compressed_bpp(void);
|
||||
int intel_dp_compute_min_hblank(struct intel_crtc_state *crtc_state,
|
||||
const struct drm_connector_state *conn_state);
|
||||
|
||||
int intel_dp_dsc_bpp_step_x16(const struct intel_connector *connector);
|
||||
void intel_dp_dpcd_set_probe(struct intel_dp *intel_dp, bool force_on_external);
|
||||
|
||||
#endif /* __INTEL_DP_H__ */
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
#include <drm/drm_print.h>
|
||||
|
||||
#include "i915_reg.h"
|
||||
#include "i915_utils.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_types.h"
|
||||
|
|
@ -835,6 +834,8 @@ void intel_dp_aux_init(struct intel_dp *intel_dp)
|
|||
|
||||
intel_dp->aux.transfer = intel_dp_aux_transfer;
|
||||
cpu_latency_qos_add_request(&intel_dp->pm_qos, PM_QOS_DEFAULT_VALUE);
|
||||
|
||||
intel_dp_dpcd_set_probe(intel_dp, true);
|
||||
}
|
||||
|
||||
static enum aux_ch default_aux_ch(struct intel_encoder *encoder)
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@
|
|||
#include <drm/display/drm_hdcp_helper.h>
|
||||
#include <drm/drm_print.h>
|
||||
|
||||
#include "i915_reg.h"
|
||||
#include "intel_ddi.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dp.h"
|
||||
#include "intel_dp_hdcp.h"
|
||||
|
|
|
|||
|
|
@ -23,6 +23,9 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <linux/log2.h>
|
||||
#include <linux/math.h>
|
||||
|
||||
#include <drm/drm_atomic.h>
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
#include <drm/drm_edid.h>
|
||||
|
|
@ -30,7 +33,6 @@
|
|||
#include <drm/drm_print.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
|
||||
#include "i915_reg.h"
|
||||
#include "i915_utils.h"
|
||||
#include "intel_atomic.h"
|
||||
#include "intel_audio.h"
|
||||
|
|
@ -39,6 +41,7 @@
|
|||
#include "intel_ddi.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_driver.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dp.h"
|
||||
#include "intel_dp_hdcp.h"
|
||||
|
|
@ -135,6 +138,7 @@ static bool intel_dp_mst_inc_active_streams(struct intel_dp *intel_dp)
|
|||
return intel_dp->mst.active_streams++ == 0;
|
||||
}
|
||||
|
||||
/* TODO: return a bpp_x16 value */
|
||||
static int intel_dp_mst_max_dpt_bpp(const struct intel_crtc_state *crtc_state,
|
||||
bool dsc)
|
||||
{
|
||||
|
|
@ -241,6 +245,15 @@ static int intel_dp_mst_dsc_get_slice_count(const struct intel_connector *connec
|
|||
num_joined_pipes);
|
||||
}
|
||||
|
||||
static void mst_stream_update_slots(const struct intel_crtc_state *crtc_state,
|
||||
struct drm_dp_mst_topology_state *topology_state)
|
||||
{
|
||||
u8 link_coding_cap = intel_dp_is_uhbr(crtc_state) ?
|
||||
DP_CAP_ANSI_128B132B : DP_CAP_ANSI_8B10B;
|
||||
|
||||
drm_dp_mst_update_slots(topology_state, link_coding_cap);
|
||||
}
|
||||
|
||||
int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp,
|
||||
struct intel_crtc_state *crtc_state,
|
||||
struct drm_connector_state *conn_state,
|
||||
|
|
@ -263,6 +276,12 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp,
|
|||
fxp_q4_to_frac(max_bpp_x16) ||
|
||||
fxp_q4_to_frac(bpp_step_x16)));
|
||||
|
||||
if (!bpp_step_x16) {
|
||||
/* Allow using zero step only to indicate single try for a given bpp. */
|
||||
drm_WARN_ON(display->drm, min_bpp_x16 != max_bpp_x16);
|
||||
bpp_step_x16 = 1;
|
||||
}
|
||||
|
||||
if (is_mst) {
|
||||
mst_state = drm_atomic_get_mst_topology_state(state, &intel_dp->mst.mgr);
|
||||
if (IS_ERR(mst_state))
|
||||
|
|
@ -270,6 +289,8 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp,
|
|||
|
||||
mst_state->pbn_div = drm_dp_get_vc_payload_bw(crtc_state->port_clock,
|
||||
crtc_state->lane_count);
|
||||
|
||||
mst_stream_update_slots(crtc_state, mst_state);
|
||||
}
|
||||
|
||||
if (dsc) {
|
||||
|
|
@ -298,12 +319,20 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp,
|
|||
}
|
||||
}
|
||||
|
||||
drm_WARN_ON(display->drm, min_bpp_x16 % bpp_step_x16 || max_bpp_x16 % bpp_step_x16);
|
||||
|
||||
for (bpp_x16 = max_bpp_x16; bpp_x16 >= min_bpp_x16; bpp_x16 -= bpp_step_x16) {
|
||||
int local_bw_overhead;
|
||||
int link_bpp_x16;
|
||||
|
||||
drm_dbg_kms(display->drm, "Trying bpp " FXP_Q4_FMT "\n", FXP_Q4_ARGS(bpp_x16));
|
||||
|
||||
if (dsc && !intel_dp_dsc_valid_compressed_bpp(intel_dp, bpp_x16)) {
|
||||
/* SST must have validated the single bpp tried here already earlier. */
|
||||
drm_WARN_ON(display->drm, !is_mst);
|
||||
continue;
|
||||
}
|
||||
|
||||
link_bpp_x16 = dsc ? bpp_x16 :
|
||||
fxp_q4_from_int(intel_dp_output_bpp(crtc_state->output_format,
|
||||
fxp_q4_to_int(bpp_x16)));
|
||||
|
|
@ -367,6 +396,10 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp,
|
|||
slots = drm_dp_atomic_find_time_slots(state, &intel_dp->mst.mgr,
|
||||
connector->mst.port,
|
||||
dfixed_trunc(pbn));
|
||||
|
||||
/* TODO: Check this already in drm_dp_atomic_find_time_slots(). */
|
||||
if (slots > mst_state->total_avail_slots)
|
||||
slots = -EINVAL;
|
||||
} else {
|
||||
/* Same as above for remote_tu */
|
||||
crtc_state->dp_m_n.tu = ALIGN(crtc_state->dp_m_n.tu,
|
||||
|
|
@ -386,10 +419,6 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp,
|
|||
|
||||
break;
|
||||
}
|
||||
|
||||
/* Allow using zero step to indicate one try */
|
||||
if (!bpp_step_x16)
|
||||
break;
|
||||
}
|
||||
|
||||
if (slots < 0) {
|
||||
|
|
@ -437,7 +466,8 @@ static int mst_stream_dsc_compute_link_config(struct intel_dp *intel_dp,
|
|||
int num_bpc;
|
||||
u8 dsc_bpc[3] = {};
|
||||
int min_bpp, max_bpp, sink_min_bpp, sink_max_bpp;
|
||||
int min_compressed_bpp, max_compressed_bpp;
|
||||
int min_compressed_bpp_x16, max_compressed_bpp_x16;
|
||||
int bpp_step_x16;
|
||||
|
||||
max_bpp = limits->pipe.max_bpp;
|
||||
min_bpp = limits->pipe.min_bpp;
|
||||
|
|
@ -462,46 +492,28 @@ static int mst_stream_dsc_compute_link_config(struct intel_dp *intel_dp,
|
|||
|
||||
crtc_state->pipe_bpp = max_bpp;
|
||||
|
||||
max_compressed_bpp = fxp_q4_to_int(limits->link.max_bpp_x16);
|
||||
min_compressed_bpp = fxp_q4_to_int_roundup(limits->link.min_bpp_x16);
|
||||
min_compressed_bpp_x16 = limits->link.min_bpp_x16;
|
||||
max_compressed_bpp_x16 = limits->link.max_bpp_x16;
|
||||
|
||||
drm_dbg_kms(display->drm, "DSC Sink supported compressed min bpp %d compressed max bpp %d\n",
|
||||
min_compressed_bpp, max_compressed_bpp);
|
||||
drm_dbg_kms(display->drm,
|
||||
"DSC Sink supported compressed min bpp " FXP_Q4_FMT " compressed max bpp " FXP_Q4_FMT "\n",
|
||||
FXP_Q4_ARGS(min_compressed_bpp_x16), FXP_Q4_ARGS(max_compressed_bpp_x16));
|
||||
|
||||
/* Align compressed bpps according to our own constraints */
|
||||
max_compressed_bpp = intel_dp_dsc_nearest_valid_bpp(display, max_compressed_bpp,
|
||||
crtc_state->pipe_bpp);
|
||||
min_compressed_bpp = intel_dp_dsc_nearest_valid_bpp(display, min_compressed_bpp,
|
||||
crtc_state->pipe_bpp);
|
||||
bpp_step_x16 = intel_dp_dsc_bpp_step_x16(connector);
|
||||
|
||||
max_compressed_bpp_x16 = min(max_compressed_bpp_x16, fxp_q4_from_int(crtc_state->pipe_bpp) - bpp_step_x16);
|
||||
|
||||
drm_WARN_ON(display->drm, !is_power_of_2(bpp_step_x16));
|
||||
min_compressed_bpp_x16 = round_up(min_compressed_bpp_x16, bpp_step_x16);
|
||||
max_compressed_bpp_x16 = round_down(max_compressed_bpp_x16, bpp_step_x16);
|
||||
|
||||
crtc_state->lane_count = limits->max_lane_count;
|
||||
crtc_state->port_clock = limits->max_rate;
|
||||
|
||||
return intel_dp_mtp_tu_compute_config(intel_dp, crtc_state, conn_state,
|
||||
fxp_q4_from_int(min_compressed_bpp),
|
||||
fxp_q4_from_int(max_compressed_bpp),
|
||||
fxp_q4_from_int(1), true);
|
||||
}
|
||||
|
||||
static int mst_stream_update_slots(struct intel_dp *intel_dp,
|
||||
struct intel_crtc_state *crtc_state,
|
||||
struct drm_connector_state *conn_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
struct drm_dp_mst_topology_mgr *mgr = &intel_dp->mst.mgr;
|
||||
struct drm_dp_mst_topology_state *topology_state;
|
||||
u8 link_coding_cap = intel_dp_is_uhbr(crtc_state) ?
|
||||
DP_CAP_ANSI_128B132B : DP_CAP_ANSI_8B10B;
|
||||
|
||||
topology_state = drm_atomic_get_mst_topology_state(conn_state->state, mgr);
|
||||
if (IS_ERR(topology_state)) {
|
||||
drm_dbg_kms(display->drm, "slot update failed\n");
|
||||
return PTR_ERR(topology_state);
|
||||
}
|
||||
|
||||
drm_dp_mst_update_slots(topology_state, link_coding_cap);
|
||||
|
||||
return 0;
|
||||
min_compressed_bpp_x16,
|
||||
max_compressed_bpp_x16,
|
||||
bpp_step_x16, true);
|
||||
}
|
||||
|
||||
static int mode_hblank_period_ns(const struct drm_display_mode *mode)
|
||||
|
|
@ -706,10 +718,6 @@ static int mst_stream_compute_config(struct intel_encoder *encoder,
|
|||
pipe_config->dp_m_n.tu);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = mst_stream_update_slots(intel_dp, pipe_config, conn_state);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@
|
|||
#include <drm/drm_print.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
|
||||
#include "i915_reg.h"
|
||||
#include "intel_ddi.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dp.h"
|
||||
#include "intel_dp_link_training.h"
|
||||
|
|
|
|||
|
|
@ -21,13 +21,15 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <drm/drm_print.h>
|
||||
|
||||
#include "bxt_dpio_phy_regs.h"
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include "i915_utils.h"
|
||||
#include "intel_ddi.h"
|
||||
#include "intel_ddi_buf_trans.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_power_well.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dp.h"
|
||||
#include "intel_dpio_phy.h"
|
||||
|
|
@ -426,7 +428,7 @@ static void _bxt_dpio_phy_init(struct intel_display *display, enum dpio_phy phy)
|
|||
* use 1ms due to occasional timeouts observed with that.
|
||||
*/
|
||||
if (intel_de_wait_fw(display, BXT_PORT_CL1CM_DW0(phy),
|
||||
PHY_RESERVED | PHY_POWER_GOOD, PHY_POWER_GOOD, 1))
|
||||
PHY_RESERVED | PHY_POWER_GOOD, PHY_POWER_GOOD, 1, NULL))
|
||||
drm_err(display->drm, "timeout during PHY%d power on\n",
|
||||
phy);
|
||||
|
||||
|
|
@ -715,53 +717,53 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder,
|
|||
u32 deemph_reg_value, u32 margin_reg_value,
|
||||
bool uniq_trans_scale)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
|
||||
enum dpio_channel ch = vlv_dig_port_to_channel(dig_port);
|
||||
enum dpio_phy phy = vlv_dig_port_to_phy(dig_port);
|
||||
u32 val;
|
||||
int i;
|
||||
|
||||
vlv_dpio_get(dev_priv);
|
||||
vlv_dpio_get(display->drm);
|
||||
|
||||
/* Clear calc init */
|
||||
val = vlv_dpio_read(dev_priv, phy, VLV_PCS01_DW10(ch));
|
||||
val = vlv_dpio_read(display->drm, phy, VLV_PCS01_DW10(ch));
|
||||
val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3);
|
||||
val &= ~(DPIO_PCS_TX1DEEMP_MASK | DPIO_PCS_TX2DEEMP_MASK);
|
||||
val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5;
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PCS01_DW10(ch), val);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PCS01_DW10(ch), val);
|
||||
|
||||
if (crtc_state->lane_count > 2) {
|
||||
val = vlv_dpio_read(dev_priv, phy, VLV_PCS23_DW10(ch));
|
||||
val = vlv_dpio_read(display->drm, phy, VLV_PCS23_DW10(ch));
|
||||
val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3);
|
||||
val &= ~(DPIO_PCS_TX1DEEMP_MASK | DPIO_PCS_TX2DEEMP_MASK);
|
||||
val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5;
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PCS23_DW10(ch), val);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PCS23_DW10(ch), val);
|
||||
}
|
||||
|
||||
val = vlv_dpio_read(dev_priv, phy, VLV_PCS01_DW9(ch));
|
||||
val = vlv_dpio_read(display->drm, phy, VLV_PCS01_DW9(ch));
|
||||
val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK);
|
||||
val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000;
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PCS01_DW9(ch), val);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PCS01_DW9(ch), val);
|
||||
|
||||
if (crtc_state->lane_count > 2) {
|
||||
val = vlv_dpio_read(dev_priv, phy, VLV_PCS23_DW9(ch));
|
||||
val = vlv_dpio_read(display->drm, phy, VLV_PCS23_DW9(ch));
|
||||
val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK);
|
||||
val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000;
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PCS23_DW9(ch), val);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PCS23_DW9(ch), val);
|
||||
}
|
||||
|
||||
/* Program swing deemph */
|
||||
for (i = 0; i < crtc_state->lane_count; i++) {
|
||||
val = vlv_dpio_read(dev_priv, phy, CHV_TX_DW4(ch, i));
|
||||
val = vlv_dpio_read(display->drm, phy, CHV_TX_DW4(ch, i));
|
||||
val &= ~DPIO_SWING_DEEMPH9P5_MASK;
|
||||
val |= DPIO_SWING_DEEMPH9P5(deemph_reg_value);
|
||||
vlv_dpio_write(dev_priv, phy, CHV_TX_DW4(ch, i), val);
|
||||
vlv_dpio_write(display->drm, phy, CHV_TX_DW4(ch, i), val);
|
||||
}
|
||||
|
||||
/* Program swing margin */
|
||||
for (i = 0; i < crtc_state->lane_count; i++) {
|
||||
val = vlv_dpio_read(dev_priv, phy, CHV_TX_DW2(ch, i));
|
||||
val = vlv_dpio_read(display->drm, phy, CHV_TX_DW2(ch, i));
|
||||
|
||||
val &= ~DPIO_SWING_MARGIN000_MASK;
|
||||
val |= DPIO_SWING_MARGIN000(margin_reg_value);
|
||||
|
|
@ -774,7 +776,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder,
|
|||
val &= ~DPIO_UNIQ_TRANS_SCALE_MASK;
|
||||
val |= DPIO_UNIQ_TRANS_SCALE(0x9a);
|
||||
|
||||
vlv_dpio_write(dev_priv, phy, CHV_TX_DW2(ch, i), val);
|
||||
vlv_dpio_write(display->drm, phy, CHV_TX_DW2(ch, i), val);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -784,70 +786,70 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder,
|
|||
* 27 for ch0 and ch1.
|
||||
*/
|
||||
for (i = 0; i < crtc_state->lane_count; i++) {
|
||||
val = vlv_dpio_read(dev_priv, phy, CHV_TX_DW3(ch, i));
|
||||
val = vlv_dpio_read(display->drm, phy, CHV_TX_DW3(ch, i));
|
||||
if (uniq_trans_scale)
|
||||
val |= DPIO_TX_UNIQ_TRANS_SCALE_EN;
|
||||
else
|
||||
val &= ~DPIO_TX_UNIQ_TRANS_SCALE_EN;
|
||||
vlv_dpio_write(dev_priv, phy, CHV_TX_DW3(ch, i), val);
|
||||
vlv_dpio_write(display->drm, phy, CHV_TX_DW3(ch, i), val);
|
||||
}
|
||||
|
||||
/* Start swing calculation */
|
||||
val = vlv_dpio_read(dev_priv, phy, VLV_PCS01_DW10(ch));
|
||||
val = vlv_dpio_read(display->drm, phy, VLV_PCS01_DW10(ch));
|
||||
val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3;
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PCS01_DW10(ch), val);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PCS01_DW10(ch), val);
|
||||
|
||||
if (crtc_state->lane_count > 2) {
|
||||
val = vlv_dpio_read(dev_priv, phy, VLV_PCS23_DW10(ch));
|
||||
val = vlv_dpio_read(display->drm, phy, VLV_PCS23_DW10(ch));
|
||||
val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3;
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PCS23_DW10(ch), val);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PCS23_DW10(ch), val);
|
||||
}
|
||||
|
||||
vlv_dpio_put(dev_priv);
|
||||
vlv_dpio_put(display->drm);
|
||||
}
|
||||
|
||||
static void __chv_data_lane_soft_reset(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
bool reset)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
|
||||
enum dpio_channel ch = vlv_dig_port_to_channel(dig_port);
|
||||
enum dpio_phy phy = vlv_dig_port_to_phy(dig_port);
|
||||
u32 val;
|
||||
|
||||
val = vlv_dpio_read(dev_priv, phy, VLV_PCS01_DW0(ch));
|
||||
val = vlv_dpio_read(display->drm, phy, VLV_PCS01_DW0(ch));
|
||||
if (reset)
|
||||
val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
|
||||
else
|
||||
val |= DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET;
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PCS01_DW0(ch), val);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PCS01_DW0(ch), val);
|
||||
|
||||
if (crtc_state->lane_count > 2) {
|
||||
val = vlv_dpio_read(dev_priv, phy, VLV_PCS23_DW0(ch));
|
||||
val = vlv_dpio_read(display->drm, phy, VLV_PCS23_DW0(ch));
|
||||
if (reset)
|
||||
val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET);
|
||||
else
|
||||
val |= DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET;
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PCS23_DW0(ch), val);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PCS23_DW0(ch), val);
|
||||
}
|
||||
|
||||
val = vlv_dpio_read(dev_priv, phy, VLV_PCS01_DW1(ch));
|
||||
val = vlv_dpio_read(display->drm, phy, VLV_PCS01_DW1(ch));
|
||||
val |= CHV_PCS_REQ_SOFTRESET_EN;
|
||||
if (reset)
|
||||
val &= ~DPIO_PCS_CLK_SOFT_RESET;
|
||||
else
|
||||
val |= DPIO_PCS_CLK_SOFT_RESET;
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PCS01_DW1(ch), val);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PCS01_DW1(ch), val);
|
||||
|
||||
if (crtc_state->lane_count > 2) {
|
||||
val = vlv_dpio_read(dev_priv, phy, VLV_PCS23_DW1(ch));
|
||||
val = vlv_dpio_read(display->drm, phy, VLV_PCS23_DW1(ch));
|
||||
val |= CHV_PCS_REQ_SOFTRESET_EN;
|
||||
if (reset)
|
||||
val &= ~DPIO_PCS_CLK_SOFT_RESET;
|
||||
else
|
||||
val |= DPIO_PCS_CLK_SOFT_RESET;
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PCS23_DW1(ch), val);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PCS23_DW1(ch), val);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -855,11 +857,11 @@ void chv_data_lane_soft_reset(struct intel_encoder *encoder,
|
|||
const struct intel_crtc_state *crtc_state,
|
||||
bool reset)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
|
||||
vlv_dpio_get(i915);
|
||||
vlv_dpio_get(display->drm);
|
||||
__chv_data_lane_soft_reset(encoder, crtc_state, reset);
|
||||
vlv_dpio_put(i915);
|
||||
vlv_dpio_put(display->drm);
|
||||
}
|
||||
|
||||
void chv_phy_pre_pll_enable(struct intel_encoder *encoder,
|
||||
|
|
@ -867,7 +869,6 @@ void chv_phy_pre_pll_enable(struct intel_encoder *encoder,
|
|||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
enum dpio_channel ch = vlv_dig_port_to_channel(dig_port);
|
||||
enum dpio_phy phy = vlv_dig_port_to_phy(dig_port);
|
||||
|
|
@ -886,47 +887,47 @@ void chv_phy_pre_pll_enable(struct intel_encoder *encoder,
|
|||
|
||||
chv_phy_powergate_lanes(encoder, true, lane_mask);
|
||||
|
||||
vlv_dpio_get(dev_priv);
|
||||
vlv_dpio_get(display->drm);
|
||||
|
||||
/* Assert data lane reset */
|
||||
__chv_data_lane_soft_reset(encoder, crtc_state, true);
|
||||
|
||||
/* program left/right clock distribution */
|
||||
if (pipe != PIPE_B) {
|
||||
val = vlv_dpio_read(dev_priv, phy, CHV_CMN_DW5_CH0);
|
||||
val = vlv_dpio_read(display->drm, phy, CHV_CMN_DW5_CH0);
|
||||
val &= ~(CHV_BUFLEFTENA1_MASK | CHV_BUFRIGHTENA1_MASK);
|
||||
if (ch == DPIO_CH0)
|
||||
val |= CHV_BUFLEFTENA1_FORCE;
|
||||
if (ch == DPIO_CH1)
|
||||
val |= CHV_BUFRIGHTENA1_FORCE;
|
||||
vlv_dpio_write(dev_priv, phy, CHV_CMN_DW5_CH0, val);
|
||||
vlv_dpio_write(display->drm, phy, CHV_CMN_DW5_CH0, val);
|
||||
} else {
|
||||
val = vlv_dpio_read(dev_priv, phy, CHV_CMN_DW1_CH1);
|
||||
val = vlv_dpio_read(display->drm, phy, CHV_CMN_DW1_CH1);
|
||||
val &= ~(CHV_BUFLEFTENA2_MASK | CHV_BUFRIGHTENA2_MASK);
|
||||
if (ch == DPIO_CH0)
|
||||
val |= CHV_BUFLEFTENA2_FORCE;
|
||||
if (ch == DPIO_CH1)
|
||||
val |= CHV_BUFRIGHTENA2_FORCE;
|
||||
vlv_dpio_write(dev_priv, phy, CHV_CMN_DW1_CH1, val);
|
||||
vlv_dpio_write(display->drm, phy, CHV_CMN_DW1_CH1, val);
|
||||
}
|
||||
|
||||
/* program clock channel usage */
|
||||
val = vlv_dpio_read(dev_priv, phy, VLV_PCS01_DW8(ch));
|
||||
val = vlv_dpio_read(display->drm, phy, VLV_PCS01_DW8(ch));
|
||||
val |= DPIO_PCS_USEDCLKCHANNEL_OVRRIDE;
|
||||
if (pipe == PIPE_B)
|
||||
val |= DPIO_PCS_USEDCLKCHANNEL;
|
||||
else
|
||||
val &= ~DPIO_PCS_USEDCLKCHANNEL;
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PCS01_DW8(ch), val);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PCS01_DW8(ch), val);
|
||||
|
||||
if (crtc_state->lane_count > 2) {
|
||||
val = vlv_dpio_read(dev_priv, phy, VLV_PCS23_DW8(ch));
|
||||
val = vlv_dpio_read(display->drm, phy, VLV_PCS23_DW8(ch));
|
||||
val |= DPIO_PCS_USEDCLKCHANNEL_OVRRIDE;
|
||||
if (pipe == PIPE_B)
|
||||
val |= DPIO_PCS_USEDCLKCHANNEL;
|
||||
else
|
||||
val &= ~DPIO_PCS_USEDCLKCHANNEL;
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PCS23_DW8(ch), val);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PCS23_DW8(ch), val);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -934,38 +935,38 @@ void chv_phy_pre_pll_enable(struct intel_encoder *encoder,
|
|||
* matches the pipe, but here we need to
|
||||
* pick the CL based on the port.
|
||||
*/
|
||||
val = vlv_dpio_read(dev_priv, phy, CHV_CMN_DW19(ch));
|
||||
val = vlv_dpio_read(display->drm, phy, CHV_CMN_DW19(ch));
|
||||
if (pipe == PIPE_B)
|
||||
val |= CHV_CMN_USEDCLKCHANNEL;
|
||||
else
|
||||
val &= ~CHV_CMN_USEDCLKCHANNEL;
|
||||
vlv_dpio_write(dev_priv, phy, CHV_CMN_DW19(ch), val);
|
||||
vlv_dpio_write(display->drm, phy, CHV_CMN_DW19(ch), val);
|
||||
|
||||
vlv_dpio_put(dev_priv);
|
||||
vlv_dpio_put(display->drm);
|
||||
}
|
||||
|
||||
void chv_phy_pre_encoder_enable(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
|
||||
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
enum dpio_channel ch = vlv_dig_port_to_channel(dig_port);
|
||||
enum dpio_phy phy = vlv_dig_port_to_phy(dig_port);
|
||||
int data, i, stagger;
|
||||
u32 val;
|
||||
|
||||
vlv_dpio_get(dev_priv);
|
||||
vlv_dpio_get(display->drm);
|
||||
|
||||
/* allow hardware to manage TX FIFO reset source */
|
||||
val = vlv_dpio_read(dev_priv, phy, VLV_PCS01_DW11(ch));
|
||||
val = vlv_dpio_read(display->drm, phy, VLV_PCS01_DW11(ch));
|
||||
val &= ~DPIO_LANEDESKEW_STRAP_OVRD;
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PCS01_DW11(ch), val);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PCS01_DW11(ch), val);
|
||||
|
||||
if (crtc_state->lane_count > 2) {
|
||||
val = vlv_dpio_read(dev_priv, phy, VLV_PCS23_DW11(ch));
|
||||
val = vlv_dpio_read(display->drm, phy, VLV_PCS23_DW11(ch));
|
||||
val &= ~DPIO_LANEDESKEW_STRAP_OVRD;
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PCS23_DW11(ch), val);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PCS23_DW11(ch), val);
|
||||
}
|
||||
|
||||
/* Program Tx lane latency optimal setting*/
|
||||
|
|
@ -975,7 +976,7 @@ void chv_phy_pre_encoder_enable(struct intel_encoder *encoder,
|
|||
data = 0;
|
||||
else
|
||||
data = (i == 1) ? 0 : DPIO_UPAR;
|
||||
vlv_dpio_write(dev_priv, phy, CHV_TX_DW14(ch, i), data);
|
||||
vlv_dpio_write(display->drm, phy, CHV_TX_DW14(ch, i), data);
|
||||
}
|
||||
|
||||
/* Data lane stagger programming */
|
||||
|
|
@ -990,17 +991,17 @@ void chv_phy_pre_encoder_enable(struct intel_encoder *encoder,
|
|||
else
|
||||
stagger = 0x2;
|
||||
|
||||
val = vlv_dpio_read(dev_priv, phy, VLV_PCS01_DW11(ch));
|
||||
val = vlv_dpio_read(display->drm, phy, VLV_PCS01_DW11(ch));
|
||||
val |= DPIO_TX2_STAGGER_MASK(0x1f);
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PCS01_DW11(ch), val);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PCS01_DW11(ch), val);
|
||||
|
||||
if (crtc_state->lane_count > 2) {
|
||||
val = vlv_dpio_read(dev_priv, phy, VLV_PCS23_DW11(ch));
|
||||
val = vlv_dpio_read(display->drm, phy, VLV_PCS23_DW11(ch));
|
||||
val |= DPIO_TX2_STAGGER_MASK(0x1f);
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PCS23_DW11(ch), val);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PCS23_DW11(ch), val);
|
||||
}
|
||||
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PCS01_DW12(ch),
|
||||
vlv_dpio_write(display->drm, phy, VLV_PCS01_DW12(ch),
|
||||
DPIO_LANESTAGGER_STRAP(stagger) |
|
||||
DPIO_LANESTAGGER_STRAP_OVRD |
|
||||
DPIO_TX1_STAGGER_MASK(0x1f) |
|
||||
|
|
@ -1008,7 +1009,7 @@ void chv_phy_pre_encoder_enable(struct intel_encoder *encoder,
|
|||
DPIO_TX2_STAGGER_MULT(0));
|
||||
|
||||
if (crtc_state->lane_count > 2) {
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PCS23_DW12(ch),
|
||||
vlv_dpio_write(display->drm, phy, VLV_PCS23_DW12(ch),
|
||||
DPIO_LANESTAGGER_STRAP(stagger) |
|
||||
DPIO_LANESTAGGER_STRAP_OVRD |
|
||||
DPIO_TX1_STAGGER_MASK(0x1f) |
|
||||
|
|
@ -1019,7 +1020,7 @@ void chv_phy_pre_encoder_enable(struct intel_encoder *encoder,
|
|||
/* Deassert data lane reset */
|
||||
__chv_data_lane_soft_reset(encoder, crtc_state, false);
|
||||
|
||||
vlv_dpio_put(dev_priv);
|
||||
vlv_dpio_put(display->drm);
|
||||
}
|
||||
|
||||
void chv_phy_release_cl2_override(struct intel_encoder *encoder)
|
||||
|
|
@ -1036,25 +1037,25 @@ void chv_phy_release_cl2_override(struct intel_encoder *encoder)
|
|||
void chv_phy_post_pll_disable(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *old_crtc_state)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
enum dpio_phy phy = vlv_dig_port_to_phy(enc_to_dig_port(encoder));
|
||||
enum pipe pipe = to_intel_crtc(old_crtc_state->uapi.crtc)->pipe;
|
||||
u32 val;
|
||||
|
||||
vlv_dpio_get(dev_priv);
|
||||
vlv_dpio_get(display->drm);
|
||||
|
||||
/* disable left/right clock distribution */
|
||||
if (pipe != PIPE_B) {
|
||||
val = vlv_dpio_read(dev_priv, phy, CHV_CMN_DW5_CH0);
|
||||
val = vlv_dpio_read(display->drm, phy, CHV_CMN_DW5_CH0);
|
||||
val &= ~(CHV_BUFLEFTENA1_MASK | CHV_BUFRIGHTENA1_MASK);
|
||||
vlv_dpio_write(dev_priv, phy, CHV_CMN_DW5_CH0, val);
|
||||
vlv_dpio_write(display->drm, phy, CHV_CMN_DW5_CH0, val);
|
||||
} else {
|
||||
val = vlv_dpio_read(dev_priv, phy, CHV_CMN_DW1_CH1);
|
||||
val = vlv_dpio_read(display->drm, phy, CHV_CMN_DW1_CH1);
|
||||
val &= ~(CHV_BUFLEFTENA2_MASK | CHV_BUFRIGHTENA2_MASK);
|
||||
vlv_dpio_write(dev_priv, phy, CHV_CMN_DW1_CH1, val);
|
||||
vlv_dpio_write(display->drm, phy, CHV_CMN_DW1_CH1, val);
|
||||
}
|
||||
|
||||
vlv_dpio_put(dev_priv);
|
||||
vlv_dpio_put(display->drm);
|
||||
|
||||
/*
|
||||
* Leave the power down bit cleared for at least one
|
||||
|
|
@ -1073,97 +1074,97 @@ void vlv_set_phy_signal_level(struct intel_encoder *encoder,
|
|||
u32 demph_reg_value, u32 preemph_reg_value,
|
||||
u32 uniqtranscale_reg_value, u32 tx3_demph)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
|
||||
enum dpio_channel ch = vlv_dig_port_to_channel(dig_port);
|
||||
enum dpio_phy phy = vlv_dig_port_to_phy(dig_port);
|
||||
|
||||
vlv_dpio_get(dev_priv);
|
||||
vlv_dpio_get(display->drm);
|
||||
|
||||
vlv_dpio_write(dev_priv, phy, VLV_TX_DW5_GRP(ch), 0x00000000);
|
||||
vlv_dpio_write(dev_priv, phy, VLV_TX_DW4_GRP(ch), demph_reg_value);
|
||||
vlv_dpio_write(dev_priv, phy, VLV_TX_DW2_GRP(ch),
|
||||
uniqtranscale_reg_value);
|
||||
vlv_dpio_write(dev_priv, phy, VLV_TX_DW3_GRP(ch), 0x0C782040);
|
||||
vlv_dpio_write(display->drm, phy, VLV_TX_DW5_GRP(ch), 0x00000000);
|
||||
vlv_dpio_write(display->drm, phy, VLV_TX_DW4_GRP(ch), demph_reg_value);
|
||||
vlv_dpio_write(display->drm, phy, VLV_TX_DW2_GRP(ch),
|
||||
uniqtranscale_reg_value);
|
||||
vlv_dpio_write(display->drm, phy, VLV_TX_DW3_GRP(ch), 0x0C782040);
|
||||
|
||||
if (tx3_demph)
|
||||
vlv_dpio_write(dev_priv, phy, VLV_TX_DW4(ch, 3), tx3_demph);
|
||||
vlv_dpio_write(display->drm, phy, VLV_TX_DW4(ch, 3), tx3_demph);
|
||||
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PCS_DW11_GRP(ch), 0x00030000);
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PCS_DW9_GRP(ch), preemph_reg_value);
|
||||
vlv_dpio_write(dev_priv, phy, VLV_TX_DW5_GRP(ch), DPIO_TX_OCALINIT_EN);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PCS_DW11_GRP(ch), 0x00030000);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PCS_DW9_GRP(ch), preemph_reg_value);
|
||||
vlv_dpio_write(display->drm, phy, VLV_TX_DW5_GRP(ch), DPIO_TX_OCALINIT_EN);
|
||||
|
||||
vlv_dpio_put(dev_priv);
|
||||
vlv_dpio_put(display->drm);
|
||||
}
|
||||
|
||||
void vlv_phy_pre_pll_enable(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
enum dpio_channel ch = vlv_dig_port_to_channel(dig_port);
|
||||
enum dpio_phy phy = vlv_dig_port_to_phy(dig_port);
|
||||
|
||||
/* Program Tx lane resets to default */
|
||||
vlv_dpio_get(dev_priv);
|
||||
vlv_dpio_get(display->drm);
|
||||
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PCS_DW0_GRP(ch),
|
||||
vlv_dpio_write(display->drm, phy, VLV_PCS_DW0_GRP(ch),
|
||||
DPIO_PCS_TX_LANE2_RESET |
|
||||
DPIO_PCS_TX_LANE1_RESET);
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PCS_DW1_GRP(ch),
|
||||
vlv_dpio_write(display->drm, phy, VLV_PCS_DW1_GRP(ch),
|
||||
DPIO_PCS_CLK_CRI_RXEB_EIOS_EN |
|
||||
DPIO_PCS_CLK_CRI_RXDIGFILTSG_EN |
|
||||
DPIO_PCS_CLK_DATAWIDTH_8_10 |
|
||||
DPIO_PCS_CLK_SOFT_RESET);
|
||||
|
||||
/* Fix up inter-pair skew failure */
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PCS_DW12_GRP(ch), 0x00750f00);
|
||||
vlv_dpio_write(dev_priv, phy, VLV_TX_DW11_GRP(ch), 0x00001500);
|
||||
vlv_dpio_write(dev_priv, phy, VLV_TX_DW14_GRP(ch), 0x40400000);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PCS_DW12_GRP(ch), 0x00750f00);
|
||||
vlv_dpio_write(display->drm, phy, VLV_TX_DW11_GRP(ch), 0x00001500);
|
||||
vlv_dpio_write(display->drm, phy, VLV_TX_DW14_GRP(ch), 0x40400000);
|
||||
|
||||
vlv_dpio_put(dev_priv);
|
||||
vlv_dpio_put(display->drm);
|
||||
}
|
||||
|
||||
void vlv_phy_pre_encoder_enable(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
|
||||
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
enum dpio_channel ch = vlv_dig_port_to_channel(dig_port);
|
||||
enum dpio_phy phy = vlv_dig_port_to_phy(dig_port);
|
||||
enum pipe pipe = crtc->pipe;
|
||||
u32 val;
|
||||
|
||||
vlv_dpio_get(dev_priv);
|
||||
vlv_dpio_get(display->drm);
|
||||
|
||||
/* Enable clock channels for this port */
|
||||
val = DPIO_PCS_USEDCLKCHANNEL_OVRRIDE;
|
||||
if (pipe == PIPE_B)
|
||||
val |= DPIO_PCS_USEDCLKCHANNEL;
|
||||
val |= 0xc4;
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PCS_DW8_GRP(ch), val);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PCS_DW8_GRP(ch), val);
|
||||
|
||||
/* Program lane clock */
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PCS_DW14_GRP(ch), 0x00760018);
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PCS_DW23_GRP(ch), 0x00400888);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PCS_DW14_GRP(ch), 0x00760018);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PCS_DW23_GRP(ch), 0x00400888);
|
||||
|
||||
vlv_dpio_put(dev_priv);
|
||||
vlv_dpio_put(display->drm);
|
||||
}
|
||||
|
||||
void vlv_phy_reset_lanes(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *old_crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
enum dpio_channel ch = vlv_dig_port_to_channel(dig_port);
|
||||
enum dpio_phy phy = vlv_dig_port_to_phy(dig_port);
|
||||
|
||||
vlv_dpio_get(dev_priv);
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PCS_DW0_GRP(ch), 0x00000000);
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PCS_DW1_GRP(ch), 0x00e00060);
|
||||
vlv_dpio_put(dev_priv);
|
||||
vlv_dpio_get(display->drm);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PCS_DW0_GRP(ch), 0x00000000);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PCS_DW1_GRP(ch), 0x00e00060);
|
||||
vlv_dpio_put(display->drm);
|
||||
}
|
||||
|
||||
void vlv_wait_port_ready(struct intel_encoder *encoder,
|
||||
|
|
|
|||
|
|
@ -6,13 +6,14 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/string_helpers.h>
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include <drm/drm_print.h>
|
||||
|
||||
#include "intel_atomic.h"
|
||||
#include "intel_crtc.h"
|
||||
#include "intel_cx0_phy.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dpio_phy.h"
|
||||
#include "intel_dpll.h"
|
||||
|
|
@ -24,11 +25,11 @@
|
|||
#include "vlv_dpio_phy_regs.h"
|
||||
#include "vlv_sideband.h"
|
||||
|
||||
struct intel_dpll_funcs {
|
||||
struct intel_dpll_global_funcs {
|
||||
int (*crtc_compute_clock)(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc);
|
||||
int (*crtc_get_shared_dpll)(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc);
|
||||
int (*crtc_get_dpll)(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc);
|
||||
};
|
||||
|
||||
struct intel_limit {
|
||||
|
|
@ -513,8 +514,8 @@ void i9xx_crtc_clock_get(struct intel_crtc_state *crtc_state)
|
|||
|
||||
void vlv_crtc_clock_get(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);
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||
enum dpio_channel ch = vlv_pipe_to_channel(crtc->pipe);
|
||||
enum dpio_phy phy = vlv_pipe_to_phy(crtc->pipe);
|
||||
const struct i9xx_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.i9xx;
|
||||
|
|
@ -526,9 +527,9 @@ void vlv_crtc_clock_get(struct intel_crtc_state *crtc_state)
|
|||
if ((hw_state->dpll & DPLL_VCO_ENABLE) == 0)
|
||||
return;
|
||||
|
||||
vlv_dpio_get(dev_priv);
|
||||
tmp = vlv_dpio_read(dev_priv, phy, VLV_PLL_DW3(ch));
|
||||
vlv_dpio_put(dev_priv);
|
||||
vlv_dpio_get(display->drm);
|
||||
tmp = vlv_dpio_read(display->drm, phy, VLV_PLL_DW3(ch));
|
||||
vlv_dpio_put(display->drm);
|
||||
|
||||
clock.m1 = REG_FIELD_GET(DPIO_M1_DIV_MASK, tmp);
|
||||
clock.m2 = REG_FIELD_GET(DPIO_M2_DIV_MASK, tmp);
|
||||
|
|
@ -541,8 +542,8 @@ void vlv_crtc_clock_get(struct intel_crtc_state *crtc_state)
|
|||
|
||||
void chv_crtc_clock_get(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);
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||
enum dpio_channel ch = vlv_pipe_to_channel(crtc->pipe);
|
||||
enum dpio_phy phy = vlv_pipe_to_phy(crtc->pipe);
|
||||
const struct i9xx_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.i9xx;
|
||||
|
|
@ -554,13 +555,13 @@ void chv_crtc_clock_get(struct intel_crtc_state *crtc_state)
|
|||
if ((hw_state->dpll & DPLL_VCO_ENABLE) == 0)
|
||||
return;
|
||||
|
||||
vlv_dpio_get(dev_priv);
|
||||
cmn_dw13 = vlv_dpio_read(dev_priv, phy, CHV_CMN_DW13(ch));
|
||||
pll_dw0 = vlv_dpio_read(dev_priv, phy, CHV_PLL_DW0(ch));
|
||||
pll_dw1 = vlv_dpio_read(dev_priv, phy, CHV_PLL_DW1(ch));
|
||||
pll_dw2 = vlv_dpio_read(dev_priv, phy, CHV_PLL_DW2(ch));
|
||||
pll_dw3 = vlv_dpio_read(dev_priv, phy, CHV_PLL_DW3(ch));
|
||||
vlv_dpio_put(dev_priv);
|
||||
vlv_dpio_get(display->drm);
|
||||
cmn_dw13 = vlv_dpio_read(display->drm, phy, CHV_CMN_DW13(ch));
|
||||
pll_dw0 = vlv_dpio_read(display->drm, phy, CHV_PLL_DW0(ch));
|
||||
pll_dw1 = vlv_dpio_read(display->drm, phy, CHV_PLL_DW1(ch));
|
||||
pll_dw2 = vlv_dpio_read(display->drm, phy, CHV_PLL_DW2(ch));
|
||||
pll_dw3 = vlv_dpio_read(display->drm, phy, CHV_PLL_DW3(ch));
|
||||
vlv_dpio_put(display->drm);
|
||||
|
||||
clock.m1 = REG_FIELD_GET(DPIO_CHV_M1_DIV_MASK, pll_dw1) == DPIO_CHV_M1_DIV_BY_2 ? 2 : 0;
|
||||
clock.m2 = REG_FIELD_GET(DPIO_CHV_M2_DIV_MASK, pll_dw0) << 22;
|
||||
|
|
@ -1161,7 +1162,7 @@ static int hsw_crtc_compute_clock(struct intel_atomic_state *state,
|
|||
intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI))
|
||||
return 0;
|
||||
|
||||
ret = intel_compute_shared_dplls(state, crtc, encoder);
|
||||
ret = intel_dpll_compute(state, crtc, encoder);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -1176,8 +1177,8 @@ static int hsw_crtc_compute_clock(struct intel_atomic_state *state,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int hsw_crtc_get_shared_dpll(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
static int hsw_crtc_get_dpll(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(state);
|
||||
struct intel_crtc_state *crtc_state =
|
||||
|
|
@ -1189,7 +1190,7 @@ static int hsw_crtc_get_shared_dpll(struct intel_atomic_state *state,
|
|||
intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI))
|
||||
return 0;
|
||||
|
||||
return intel_reserve_shared_dplls(state, crtc, encoder);
|
||||
return intel_dpll_reserve(state, crtc, encoder);
|
||||
}
|
||||
|
||||
static int dg2_crtc_compute_clock(struct intel_atomic_state *state,
|
||||
|
|
@ -1223,7 +1224,7 @@ static int mtl_crtc_compute_clock(struct intel_atomic_state *state,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* TODO: Do the readback via intel_compute_shared_dplls() */
|
||||
/* TODO: Do the readback via intel_dpll_compute() */
|
||||
crtc_state->port_clock = intel_cx0pll_calc_port_clock(encoder, &crtc_state->dpll_hw_state.cx0pll);
|
||||
|
||||
crtc_state->hw.adjusted_mode.crtc_clock = intel_crtc_dotclock(crtc_state);
|
||||
|
|
@ -1394,7 +1395,7 @@ static int ilk_crtc_compute_clock(struct intel_atomic_state *state,
|
|||
ilk_compute_dpll(crtc_state, &crtc_state->dpll,
|
||||
&crtc_state->dpll);
|
||||
|
||||
ret = intel_compute_shared_dplls(state, crtc, NULL);
|
||||
ret = intel_dpll_compute(state, crtc, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -1404,8 +1405,8 @@ static int ilk_crtc_compute_clock(struct intel_atomic_state *state,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int ilk_crtc_get_shared_dpll(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
static int ilk_crtc_get_dpll(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
struct intel_crtc_state *crtc_state =
|
||||
intel_atomic_get_new_crtc_state(state, crtc);
|
||||
|
|
@ -1414,7 +1415,7 @@ static int ilk_crtc_get_shared_dpll(struct intel_atomic_state *state,
|
|||
if (!crtc_state->has_pch_encoder)
|
||||
return 0;
|
||||
|
||||
return intel_reserve_shared_dplls(state, crtc, NULL);
|
||||
return intel_dpll_reserve(state, crtc, NULL);
|
||||
}
|
||||
|
||||
static u32 vlv_dpll(const struct intel_crtc_state *crtc_state)
|
||||
|
|
@ -1690,45 +1691,45 @@ static int i8xx_crtc_compute_clock(struct intel_atomic_state *state,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const struct intel_dpll_funcs mtl_dpll_funcs = {
|
||||
static const struct intel_dpll_global_funcs mtl_dpll_funcs = {
|
||||
.crtc_compute_clock = mtl_crtc_compute_clock,
|
||||
};
|
||||
|
||||
static const struct intel_dpll_funcs dg2_dpll_funcs = {
|
||||
static const struct intel_dpll_global_funcs dg2_dpll_funcs = {
|
||||
.crtc_compute_clock = dg2_crtc_compute_clock,
|
||||
};
|
||||
|
||||
static const struct intel_dpll_funcs hsw_dpll_funcs = {
|
||||
static const struct intel_dpll_global_funcs hsw_dpll_funcs = {
|
||||
.crtc_compute_clock = hsw_crtc_compute_clock,
|
||||
.crtc_get_shared_dpll = hsw_crtc_get_shared_dpll,
|
||||
.crtc_get_dpll = hsw_crtc_get_dpll,
|
||||
};
|
||||
|
||||
static const struct intel_dpll_funcs ilk_dpll_funcs = {
|
||||
static const struct intel_dpll_global_funcs ilk_dpll_funcs = {
|
||||
.crtc_compute_clock = ilk_crtc_compute_clock,
|
||||
.crtc_get_shared_dpll = ilk_crtc_get_shared_dpll,
|
||||
.crtc_get_dpll = ilk_crtc_get_dpll,
|
||||
};
|
||||
|
||||
static const struct intel_dpll_funcs chv_dpll_funcs = {
|
||||
static const struct intel_dpll_global_funcs chv_dpll_funcs = {
|
||||
.crtc_compute_clock = chv_crtc_compute_clock,
|
||||
};
|
||||
|
||||
static const struct intel_dpll_funcs vlv_dpll_funcs = {
|
||||
static const struct intel_dpll_global_funcs vlv_dpll_funcs = {
|
||||
.crtc_compute_clock = vlv_crtc_compute_clock,
|
||||
};
|
||||
|
||||
static const struct intel_dpll_funcs g4x_dpll_funcs = {
|
||||
static const struct intel_dpll_global_funcs g4x_dpll_funcs = {
|
||||
.crtc_compute_clock = g4x_crtc_compute_clock,
|
||||
};
|
||||
|
||||
static const struct intel_dpll_funcs pnv_dpll_funcs = {
|
||||
static const struct intel_dpll_global_funcs pnv_dpll_funcs = {
|
||||
.crtc_compute_clock = pnv_crtc_compute_clock,
|
||||
};
|
||||
|
||||
static const struct intel_dpll_funcs i9xx_dpll_funcs = {
|
||||
static const struct intel_dpll_global_funcs i9xx_dpll_funcs = {
|
||||
.crtc_compute_clock = i9xx_crtc_compute_clock,
|
||||
};
|
||||
|
||||
static const struct intel_dpll_funcs i8xx_dpll_funcs = {
|
||||
static const struct intel_dpll_global_funcs i8xx_dpll_funcs = {
|
||||
.crtc_compute_clock = i8xx_crtc_compute_clock,
|
||||
};
|
||||
|
||||
|
|
@ -1758,8 +1759,8 @@ int intel_dpll_crtc_compute_clock(struct intel_atomic_state *state,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int intel_dpll_crtc_get_shared_dpll(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
int intel_dpll_crtc_get_dpll(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(state);
|
||||
struct intel_crtc_state *crtc_state =
|
||||
|
|
@ -1767,15 +1768,15 @@ int intel_dpll_crtc_get_shared_dpll(struct intel_atomic_state *state,
|
|||
int ret;
|
||||
|
||||
drm_WARN_ON(display->drm, !intel_crtc_needs_modeset(crtc_state));
|
||||
drm_WARN_ON(display->drm, !crtc_state->hw.enable && crtc_state->shared_dpll);
|
||||
drm_WARN_ON(display->drm, !crtc_state->hw.enable && crtc_state->intel_dpll);
|
||||
|
||||
if (!crtc_state->hw.enable || crtc_state->shared_dpll)
|
||||
if (!crtc_state->hw.enable || crtc_state->intel_dpll)
|
||||
return 0;
|
||||
|
||||
if (!display->funcs.dpll->crtc_get_shared_dpll)
|
||||
if (!display->funcs.dpll->crtc_get_dpll)
|
||||
return 0;
|
||||
|
||||
ret = display->funcs.dpll->crtc_get_shared_dpll(state, crtc);
|
||||
ret = display->funcs.dpll->crtc_get_dpll(state, crtc);
|
||||
if (ret) {
|
||||
drm_dbg_kms(display->drm, "[CRTC:%d:%s] Couldn't get a shared DPLL\n",
|
||||
crtc->base.base.id, crtc->base.name);
|
||||
|
|
@ -1871,45 +1872,43 @@ void i9xx_enable_pll(const struct intel_crtc_state *crtc_state)
|
|||
static void vlv_pllb_recal_opamp(struct intel_display *display,
|
||||
enum dpio_phy phy, enum dpio_channel ch)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
u32 tmp;
|
||||
|
||||
/*
|
||||
* PLLB opamp always calibrates to max value of 0x3f, force enable it
|
||||
* and set it to a reasonable value instead.
|
||||
*/
|
||||
tmp = vlv_dpio_read(dev_priv, phy, VLV_PLL_DW17(ch));
|
||||
tmp = vlv_dpio_read(display->drm, phy, VLV_PLL_DW17(ch));
|
||||
tmp &= 0xffffff00;
|
||||
tmp |= 0x00000030;
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PLL_DW17(ch), tmp);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PLL_DW17(ch), tmp);
|
||||
|
||||
tmp = vlv_dpio_read(dev_priv, phy, VLV_REF_DW11);
|
||||
tmp = vlv_dpio_read(display->drm, phy, VLV_REF_DW11);
|
||||
tmp &= 0x00ffffff;
|
||||
tmp |= 0x8c000000;
|
||||
vlv_dpio_write(dev_priv, phy, VLV_REF_DW11, tmp);
|
||||
vlv_dpio_write(display->drm, phy, VLV_REF_DW11, tmp);
|
||||
|
||||
tmp = vlv_dpio_read(dev_priv, phy, VLV_PLL_DW17(ch));
|
||||
tmp = vlv_dpio_read(display->drm, phy, VLV_PLL_DW17(ch));
|
||||
tmp &= 0xffffff00;
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PLL_DW17(ch), tmp);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PLL_DW17(ch), tmp);
|
||||
|
||||
tmp = vlv_dpio_read(dev_priv, phy, VLV_REF_DW11);
|
||||
tmp = vlv_dpio_read(display->drm, phy, VLV_REF_DW11);
|
||||
tmp &= 0x00ffffff;
|
||||
tmp |= 0xb0000000;
|
||||
vlv_dpio_write(dev_priv, phy, VLV_REF_DW11, tmp);
|
||||
vlv_dpio_write(display->drm, phy, VLV_REF_DW11, tmp);
|
||||
}
|
||||
|
||||
static void vlv_prepare_pll(const 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);
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||
const struct dpll *clock = &crtc_state->dpll;
|
||||
enum dpio_channel ch = vlv_pipe_to_channel(crtc->pipe);
|
||||
enum dpio_phy phy = vlv_pipe_to_phy(crtc->pipe);
|
||||
enum pipe pipe = crtc->pipe;
|
||||
u32 tmp, coreclk;
|
||||
|
||||
vlv_dpio_get(dev_priv);
|
||||
vlv_dpio_get(display->drm);
|
||||
|
||||
/* See eDP HDMI DPIO driver vbios notes doc */
|
||||
|
||||
|
|
@ -1918,15 +1917,15 @@ static void vlv_prepare_pll(const struct intel_crtc_state *crtc_state)
|
|||
vlv_pllb_recal_opamp(display, phy, ch);
|
||||
|
||||
/* Set up Tx target for periodic Rcomp update */
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PCS_DW17_BCAST, 0x0100000f);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PCS_DW17_BCAST, 0x0100000f);
|
||||
|
||||
/* Disable target IRef on PLL */
|
||||
tmp = vlv_dpio_read(dev_priv, phy, VLV_PLL_DW16(ch));
|
||||
tmp = vlv_dpio_read(display->drm, phy, VLV_PLL_DW16(ch));
|
||||
tmp &= 0x00ffffff;
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PLL_DW16(ch), tmp);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PLL_DW16(ch), tmp);
|
||||
|
||||
/* Disable fast lock */
|
||||
vlv_dpio_write(dev_priv, phy, VLV_CMN_DW0, 0x610);
|
||||
vlv_dpio_write(display->drm, phy, VLV_CMN_DW0, 0x610);
|
||||
|
||||
/* Set idtafcrecal before PLL is enabled */
|
||||
tmp = DPIO_M1_DIV(clock->m1) |
|
||||
|
|
@ -1942,48 +1941,42 @@ static void vlv_prepare_pll(const struct intel_crtc_state *crtc_state)
|
|||
* Note: don't use the DAC post divider as it seems unstable.
|
||||
*/
|
||||
tmp |= DPIO_S1_DIV(DPIO_S1_DIV_HDMIDP);
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PLL_DW3(ch), tmp);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PLL_DW3(ch), tmp);
|
||||
|
||||
tmp |= DPIO_ENABLE_CALIBRATION;
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PLL_DW3(ch), tmp);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PLL_DW3(ch), tmp);
|
||||
|
||||
/* Set HBR and RBR LPF coefficients */
|
||||
if (crtc_state->port_clock == 162000 ||
|
||||
intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG) ||
|
||||
intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PLL_DW18(ch),
|
||||
0x009f0003);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PLL_DW18(ch), 0x009f0003);
|
||||
else
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PLL_DW18(ch),
|
||||
0x00d0000f);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PLL_DW18(ch), 0x00d0000f);
|
||||
|
||||
if (intel_crtc_has_dp_encoder(crtc_state)) {
|
||||
/* Use SSC source */
|
||||
if (pipe == PIPE_A)
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PLL_DW5(ch),
|
||||
0x0df40000);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PLL_DW5(ch), 0x0df40000);
|
||||
else
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PLL_DW5(ch),
|
||||
0x0df70000);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PLL_DW5(ch), 0x0df70000);
|
||||
} else { /* HDMI or VGA */
|
||||
/* Use bend source */
|
||||
if (pipe == PIPE_A)
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PLL_DW5(ch),
|
||||
0x0df70000);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PLL_DW5(ch), 0x0df70000);
|
||||
else
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PLL_DW5(ch),
|
||||
0x0df40000);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PLL_DW5(ch), 0x0df40000);
|
||||
}
|
||||
|
||||
coreclk = vlv_dpio_read(dev_priv, phy, VLV_PLL_DW7(ch));
|
||||
coreclk = vlv_dpio_read(display->drm, phy, VLV_PLL_DW7(ch));
|
||||
coreclk = (coreclk & 0x0000ff00) | 0x01c00000;
|
||||
if (intel_crtc_has_dp_encoder(crtc_state))
|
||||
coreclk |= 0x01000000;
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PLL_DW7(ch), coreclk);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PLL_DW7(ch), coreclk);
|
||||
|
||||
vlv_dpio_write(dev_priv, phy, VLV_PLL_DW19(ch), 0x87871000);
|
||||
vlv_dpio_write(display->drm, phy, VLV_PLL_DW19(ch), 0x87871000);
|
||||
|
||||
vlv_dpio_put(dev_priv);
|
||||
vlv_dpio_put(display->drm);
|
||||
}
|
||||
|
||||
static void _vlv_enable_pll(const struct intel_crtc_state *crtc_state)
|
||||
|
|
@ -2028,8 +2021,8 @@ void vlv_enable_pll(const struct intel_crtc_state *crtc_state)
|
|||
|
||||
static void chv_prepare_pll(const 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);
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||
const struct dpll *clock = &crtc_state->dpll;
|
||||
enum dpio_channel ch = vlv_pipe_to_channel(crtc->pipe);
|
||||
enum dpio_phy phy = vlv_pipe_to_phy(crtc->pipe);
|
||||
|
|
@ -2038,44 +2031,44 @@ static void chv_prepare_pll(const struct intel_crtc_state *crtc_state)
|
|||
|
||||
m2_frac = clock->m2 & 0x3fffff;
|
||||
|
||||
vlv_dpio_get(dev_priv);
|
||||
vlv_dpio_get(display->drm);
|
||||
|
||||
/* p1 and p2 divider */
|
||||
vlv_dpio_write(dev_priv, phy, CHV_CMN_DW13(ch),
|
||||
vlv_dpio_write(display->drm, phy, CHV_CMN_DW13(ch),
|
||||
DPIO_CHV_S1_DIV(5) |
|
||||
DPIO_CHV_P1_DIV(clock->p1) |
|
||||
DPIO_CHV_P2_DIV(clock->p2) |
|
||||
DPIO_CHV_K_DIV(1));
|
||||
|
||||
/* Feedback post-divider - m2 */
|
||||
vlv_dpio_write(dev_priv, phy, CHV_PLL_DW0(ch),
|
||||
vlv_dpio_write(display->drm, phy, CHV_PLL_DW0(ch),
|
||||
DPIO_CHV_M2_DIV(clock->m2 >> 22));
|
||||
|
||||
/* Feedback refclk divider - n and m1 */
|
||||
vlv_dpio_write(dev_priv, phy, CHV_PLL_DW1(ch),
|
||||
vlv_dpio_write(display->drm, phy, CHV_PLL_DW1(ch),
|
||||
DPIO_CHV_M1_DIV(DPIO_CHV_M1_DIV_BY_2) |
|
||||
DPIO_CHV_N_DIV(1));
|
||||
|
||||
/* M2 fraction division */
|
||||
vlv_dpio_write(dev_priv, phy, CHV_PLL_DW2(ch),
|
||||
vlv_dpio_write(display->drm, phy, CHV_PLL_DW2(ch),
|
||||
DPIO_CHV_M2_FRAC_DIV(m2_frac));
|
||||
|
||||
/* M2 fraction division enable */
|
||||
tmp = vlv_dpio_read(dev_priv, phy, CHV_PLL_DW3(ch));
|
||||
tmp = vlv_dpio_read(display->drm, phy, CHV_PLL_DW3(ch));
|
||||
tmp &= ~(DPIO_CHV_FEEDFWD_GAIN_MASK | DPIO_CHV_FRAC_DIV_EN);
|
||||
tmp |= DPIO_CHV_FEEDFWD_GAIN(2);
|
||||
if (m2_frac)
|
||||
tmp |= DPIO_CHV_FRAC_DIV_EN;
|
||||
vlv_dpio_write(dev_priv, phy, CHV_PLL_DW3(ch), tmp);
|
||||
vlv_dpio_write(display->drm, phy, CHV_PLL_DW3(ch), tmp);
|
||||
|
||||
/* Program digital lock detect threshold */
|
||||
tmp = vlv_dpio_read(dev_priv, phy, CHV_PLL_DW9(ch));
|
||||
tmp = vlv_dpio_read(display->drm, phy, CHV_PLL_DW9(ch));
|
||||
tmp &= ~(DPIO_CHV_INT_LOCK_THRESHOLD_MASK |
|
||||
DPIO_CHV_INT_LOCK_THRESHOLD_SEL_COARSE);
|
||||
tmp |= DPIO_CHV_INT_LOCK_THRESHOLD(0x5);
|
||||
if (!m2_frac)
|
||||
tmp |= DPIO_CHV_INT_LOCK_THRESHOLD_SEL_COARSE;
|
||||
vlv_dpio_write(dev_priv, phy, CHV_PLL_DW9(ch), tmp);
|
||||
vlv_dpio_write(display->drm, phy, CHV_PLL_DW9(ch), tmp);
|
||||
|
||||
/* Loop filter */
|
||||
if (clock->vco == 5400000) {
|
||||
|
|
@ -2100,40 +2093,39 @@ static void chv_prepare_pll(const struct intel_crtc_state *crtc_state)
|
|||
DPIO_CHV_GAIN_CTRL(0x3);
|
||||
tribuf_calcntr = 0;
|
||||
}
|
||||
vlv_dpio_write(dev_priv, phy, CHV_PLL_DW6(ch), loopfilter);
|
||||
vlv_dpio_write(display->drm, phy, CHV_PLL_DW6(ch), loopfilter);
|
||||
|
||||
tmp = vlv_dpio_read(dev_priv, phy, CHV_PLL_DW8(ch));
|
||||
tmp = vlv_dpio_read(display->drm, phy, CHV_PLL_DW8(ch));
|
||||
tmp &= ~DPIO_CHV_TDC_TARGET_CNT_MASK;
|
||||
tmp |= DPIO_CHV_TDC_TARGET_CNT(tribuf_calcntr);
|
||||
vlv_dpio_write(dev_priv, phy, CHV_PLL_DW8(ch), tmp);
|
||||
vlv_dpio_write(display->drm, phy, CHV_PLL_DW8(ch), tmp);
|
||||
|
||||
/* AFC Recal */
|
||||
vlv_dpio_write(dev_priv, phy, CHV_CMN_DW14(ch),
|
||||
vlv_dpio_read(dev_priv, phy, CHV_CMN_DW14(ch)) |
|
||||
vlv_dpio_write(display->drm, phy, CHV_CMN_DW14(ch),
|
||||
vlv_dpio_read(display->drm, phy, CHV_CMN_DW14(ch)) |
|
||||
DPIO_AFC_RECAL);
|
||||
|
||||
vlv_dpio_put(dev_priv);
|
||||
vlv_dpio_put(display->drm);
|
||||
}
|
||||
|
||||
static void _chv_enable_pll(const 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);
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||
const struct i9xx_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.i9xx;
|
||||
enum dpio_channel ch = vlv_pipe_to_channel(crtc->pipe);
|
||||
enum dpio_phy phy = vlv_pipe_to_phy(crtc->pipe);
|
||||
enum pipe pipe = crtc->pipe;
|
||||
u32 tmp;
|
||||
|
||||
vlv_dpio_get(dev_priv);
|
||||
vlv_dpio_get(display->drm);
|
||||
|
||||
/* Enable back the 10bit clock to display controller */
|
||||
tmp = vlv_dpio_read(dev_priv, phy, CHV_CMN_DW14(ch));
|
||||
tmp = vlv_dpio_read(display->drm, phy, CHV_CMN_DW14(ch));
|
||||
tmp |= DPIO_DCLKP_EN;
|
||||
vlv_dpio_write(dev_priv, phy, CHV_CMN_DW14(ch), tmp);
|
||||
vlv_dpio_write(display->drm, phy, CHV_CMN_DW14(ch), tmp);
|
||||
|
||||
vlv_dpio_put(dev_priv);
|
||||
vlv_dpio_put(display->drm);
|
||||
|
||||
/*
|
||||
* Need to wait > 100ns between dclkp clock enable bit and PLL enable.
|
||||
|
|
@ -2252,7 +2244,6 @@ void vlv_disable_pll(struct intel_display *display, enum pipe pipe)
|
|||
|
||||
void chv_disable_pll(struct intel_display *display, enum pipe pipe)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
enum dpio_channel ch = vlv_pipe_to_channel(pipe);
|
||||
enum dpio_phy phy = vlv_pipe_to_phy(pipe);
|
||||
u32 val;
|
||||
|
|
@ -2268,14 +2259,14 @@ void chv_disable_pll(struct intel_display *display, enum pipe pipe)
|
|||
intel_de_write(display, DPLL(display, pipe), val);
|
||||
intel_de_posting_read(display, DPLL(display, pipe));
|
||||
|
||||
vlv_dpio_get(dev_priv);
|
||||
vlv_dpio_get(display->drm);
|
||||
|
||||
/* Disable 10bit clock to display controller */
|
||||
val = vlv_dpio_read(dev_priv, phy, CHV_CMN_DW14(ch));
|
||||
val = vlv_dpio_read(display->drm, phy, CHV_CMN_DW14(ch));
|
||||
val &= ~DPIO_DCLKP_EN;
|
||||
vlv_dpio_write(dev_priv, phy, CHV_CMN_DW14(ch), val);
|
||||
vlv_dpio_write(display->drm, phy, CHV_CMN_DW14(ch), val);
|
||||
|
||||
vlv_dpio_put(dev_priv);
|
||||
vlv_dpio_put(display->drm);
|
||||
}
|
||||
|
||||
void i9xx_disable_pll(const struct intel_crtc_state *crtc_state)
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ struct intel_dpll_hw_state;
|
|||
void intel_dpll_init_clock_hook(struct intel_display *display);
|
||||
int intel_dpll_crtc_compute_clock(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc);
|
||||
int intel_dpll_crtc_get_shared_dpll(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc);
|
||||
int intel_dpll_crtc_get_dpll(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc);
|
||||
int i9xx_calc_dpll_params(int refclk, struct dpll *clock);
|
||||
u32 i9xx_dpll_compute_fp(const struct dpll *dpll);
|
||||
void i9xx_dpll_get_hw_state(struct intel_crtc *crtc,
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -30,18 +30,18 @@
|
|||
#include "intel_display_power.h"
|
||||
#include "intel_wakeref.h"
|
||||
|
||||
#define for_each_shared_dpll(__display, __pll, __i) \
|
||||
for ((__i) = 0; (__i) < (__display)->dpll.num_shared_dpll && \
|
||||
((__pll) = &(__display)->dpll.shared_dplls[(__i)]) ; (__i)++)
|
||||
#define for_each_dpll(__display, __pll, __i) \
|
||||
for ((__i) = 0; (__i) < (__display)->dpll.num_dpll && \
|
||||
((__pll) = &(__display)->dpll.dplls[(__i)]) ; (__i)++)
|
||||
|
||||
enum tc_port;
|
||||
struct drm_printer;
|
||||
struct intel_atomic_state;
|
||||
struct intel_crtc;
|
||||
struct intel_crtc_state;
|
||||
struct intel_dpll_funcs;
|
||||
struct intel_encoder;
|
||||
struct intel_shared_dpll;
|
||||
struct intel_shared_dpll_funcs;
|
||||
|
||||
/**
|
||||
* enum intel_dpll_id - possible DPLL ids
|
||||
|
|
@ -280,7 +280,7 @@ struct intel_dpll_hw_state {
|
|||
};
|
||||
|
||||
/**
|
||||
* struct intel_shared_dpll_state - hold the DPLL atomic state
|
||||
* struct intel_dpll_state - hold the DPLL atomic state
|
||||
*
|
||||
* This structure holds an atomic state for the DPLL, that can represent
|
||||
* either its current state (in struct &intel_shared_dpll) or a desired
|
||||
|
|
@ -289,7 +289,7 @@ struct intel_dpll_hw_state {
|
|||
*
|
||||
* See also intel_reserve_shared_dplls() and intel_release_shared_dplls().
|
||||
*/
|
||||
struct intel_shared_dpll_state {
|
||||
struct intel_dpll_state {
|
||||
/**
|
||||
* @pipe_mask: mask of pipes using this DPLL, active or not
|
||||
*/
|
||||
|
|
@ -314,7 +314,7 @@ struct dpll_info {
|
|||
/**
|
||||
* @funcs: platform specific hooks
|
||||
*/
|
||||
const struct intel_shared_dpll_funcs *funcs;
|
||||
const struct intel_dpll_funcs *funcs;
|
||||
|
||||
/**
|
||||
* @id: unique identifier for this DPLL
|
||||
|
|
@ -344,16 +344,16 @@ struct dpll_info {
|
|||
};
|
||||
|
||||
/**
|
||||
* struct intel_shared_dpll - display PLL with tracked state and users
|
||||
* struct intel_dpll - display PLL with tracked state and users
|
||||
*/
|
||||
struct intel_shared_dpll {
|
||||
struct intel_dpll {
|
||||
/**
|
||||
* @state:
|
||||
*
|
||||
* Store the state for the pll, including its hw state
|
||||
* and CRTCs using it.
|
||||
*/
|
||||
struct intel_shared_dpll_state state;
|
||||
struct intel_dpll_state state;
|
||||
|
||||
/**
|
||||
* @index: index for atomic state
|
||||
|
|
@ -387,41 +387,41 @@ struct intel_shared_dpll {
|
|||
#define SKL_DPLL2 2
|
||||
#define SKL_DPLL3 3
|
||||
|
||||
/* shared dpll functions */
|
||||
struct intel_shared_dpll *
|
||||
intel_get_shared_dpll_by_id(struct intel_display *display,
|
||||
enum intel_dpll_id id);
|
||||
void assert_shared_dpll(struct intel_display *display,
|
||||
struct intel_shared_dpll *pll,
|
||||
bool state);
|
||||
#define assert_shared_dpll_enabled(d, p) assert_shared_dpll(d, p, true)
|
||||
#define assert_shared_dpll_disabled(d, p) assert_shared_dpll(d, p, false)
|
||||
int intel_compute_shared_dplls(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc,
|
||||
struct intel_encoder *encoder);
|
||||
int intel_reserve_shared_dplls(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc,
|
||||
struct intel_encoder *encoder);
|
||||
void intel_release_shared_dplls(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc);
|
||||
void intel_unreference_shared_dpll_crtc(const struct intel_crtc *crtc,
|
||||
const struct intel_shared_dpll *pll,
|
||||
struct intel_shared_dpll_state *shared_dpll_state);
|
||||
/* dpll functions */
|
||||
struct intel_dpll *
|
||||
intel_get_dpll_by_id(struct intel_display *display,
|
||||
enum intel_dpll_id id);
|
||||
void assert_dpll(struct intel_display *display,
|
||||
struct intel_dpll *pll,
|
||||
bool state);
|
||||
#define assert_dpll_enabled(d, p) assert_dpll(d, p, true)
|
||||
#define assert_dpll_disabled(d, p) assert_dpll(d, p, false)
|
||||
int intel_dpll_compute(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc,
|
||||
struct intel_encoder *encoder);
|
||||
int intel_dpll_reserve(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc,
|
||||
struct intel_encoder *encoder);
|
||||
void intel_dpll_release(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc);
|
||||
void intel_dpll_crtc_put(const struct intel_crtc *crtc,
|
||||
const struct intel_dpll *pll,
|
||||
struct intel_dpll_state *shared_dpll_state);
|
||||
void icl_set_active_port_dpll(struct intel_crtc_state *crtc_state,
|
||||
enum icl_port_dpll_id port_dpll_id);
|
||||
void intel_update_active_dpll(struct intel_atomic_state *state,
|
||||
void intel_dpll_update_active(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc,
|
||||
struct intel_encoder *encoder);
|
||||
int intel_dpll_get_freq(struct intel_display *display,
|
||||
const struct intel_shared_dpll *pll,
|
||||
const struct intel_dpll *pll,
|
||||
const struct intel_dpll_hw_state *dpll_hw_state);
|
||||
bool intel_dpll_get_hw_state(struct intel_display *display,
|
||||
struct intel_shared_dpll *pll,
|
||||
struct intel_dpll *pll,
|
||||
struct intel_dpll_hw_state *dpll_hw_state);
|
||||
void intel_enable_shared_dpll(const struct intel_crtc_state *crtc_state);
|
||||
void intel_disable_shared_dpll(const struct intel_crtc_state *crtc_state);
|
||||
void intel_shared_dpll_swap_state(struct intel_atomic_state *state);
|
||||
void intel_shared_dpll_init(struct intel_display *display);
|
||||
void intel_dpll_enable(const struct intel_crtc_state *crtc_state);
|
||||
void intel_dpll_disable(const struct intel_crtc_state *crtc_state);
|
||||
void intel_dpll_swap_state(struct intel_atomic_state *state);
|
||||
void intel_dpll_init(struct intel_display *display);
|
||||
void intel_dpll_update_ref_clks(struct intel_display *display);
|
||||
void intel_dpll_readout_hw_state(struct intel_display *display);
|
||||
void intel_dpll_sanitize_state(struct intel_display *display);
|
||||
|
|
@ -435,8 +435,8 @@ bool intel_dpll_compare_hw_state(struct intel_display *display,
|
|||
enum intel_dpll_id icl_tc_port_to_pll_id(enum tc_port tc_port);
|
||||
bool intel_dpll_is_combophy(enum intel_dpll_id id);
|
||||
|
||||
void intel_shared_dpll_state_verify(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc);
|
||||
void intel_shared_dpll_verify_disabled(struct intel_atomic_state *state);
|
||||
void intel_dpll_state_verify(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc);
|
||||
void intel_dpll_verify_disabled(struct intel_atomic_state *state);
|
||||
|
||||
#endif /* _INTEL_DPLL_MGR_H_ */
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include "gt/gen8_ppgtt.h"
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "intel_display_core.h"
|
||||
#include "intel_display_rpm.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dpt.h"
|
||||
|
|
@ -126,7 +127,7 @@ struct i915_vma *intel_dpt_pin_to_ggtt(struct i915_address_space *vm,
|
|||
unsigned int alignment)
|
||||
{
|
||||
struct drm_i915_private *i915 = vm->i915;
|
||||
struct intel_display *display = &i915->display;
|
||||
struct intel_display *display = i915->display;
|
||||
struct i915_dpt *dpt = i915_vm_to_dpt(vm);
|
||||
struct ref_tracker *wakeref;
|
||||
struct i915_vma *vma;
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* Copyright © 2023 Intel Corporation
|
||||
*/
|
||||
|
||||
#include "i915_reg.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dpt_common.h"
|
||||
#include "skl_universal_plane_regs.h"
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@
|
|||
#include <linux/debugfs.h>
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include "intel_atomic.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_drrs.h"
|
||||
#include "intel_frontbuffer.h"
|
||||
|
|
|
|||
|
|
@ -7,11 +7,10 @@
|
|||
#include <drm/drm_print.h>
|
||||
#include <drm/drm_vblank.h>
|
||||
|
||||
#include "i915_irq.h"
|
||||
#include "i915_reg.h"
|
||||
#include "i915_utils.h"
|
||||
#include "intel_crtc.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_rpm.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dsb.h"
|
||||
|
|
@ -94,6 +93,10 @@ struct intel_dsb {
|
|||
/* see DSB_REG_VALUE_MASK */
|
||||
#define DSB_OPCODE_POLL 0xA
|
||||
/* see DSB_REG_VALUE_MASK */
|
||||
#define DSB_OPCODE_GOSUB 0xC /* ptl+ */
|
||||
#define DSB_GOSUB_HEAD_SHIFT 26
|
||||
#define DSB_GOSUB_TAIL_SHIFT 0
|
||||
#define DSB_GOSUB_CONVERT_ADDR(x) ((x) >> 6)
|
||||
|
||||
static bool pre_commit_is_vrr_active(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
|
|
@ -205,6 +208,15 @@ static bool assert_dsb_has_room(struct intel_dsb *dsb)
|
|||
crtc->base.base.id, crtc->base.name, dsb->id);
|
||||
}
|
||||
|
||||
static bool assert_dsb_tail_is_aligned(struct intel_dsb *dsb)
|
||||
{
|
||||
struct intel_crtc *crtc = dsb->crtc;
|
||||
struct intel_display *display = to_intel_display(crtc->base.dev);
|
||||
|
||||
return !drm_WARN_ON(display->drm,
|
||||
!IS_ALIGNED(dsb->free_pos * 4, CACHELINE_BYTES));
|
||||
}
|
||||
|
||||
static void intel_dsb_dump(struct intel_dsb *dsb)
|
||||
{
|
||||
struct intel_crtc *crtc = dsb->crtc;
|
||||
|
|
@ -229,13 +241,40 @@ static bool is_dsb_busy(struct intel_display *display, enum pipe pipe,
|
|||
return intel_de_read_fw(display, DSB_CTRL(pipe, dsb_id)) & DSB_STATUS_BUSY;
|
||||
}
|
||||
|
||||
unsigned int intel_dsb_size(struct intel_dsb *dsb)
|
||||
{
|
||||
return dsb->free_pos * 4;
|
||||
}
|
||||
|
||||
unsigned int intel_dsb_head(struct intel_dsb *dsb)
|
||||
{
|
||||
return intel_dsb_buffer_ggtt_offset(&dsb->dsb_buf);
|
||||
}
|
||||
|
||||
static unsigned int intel_dsb_tail(struct intel_dsb *dsb)
|
||||
{
|
||||
return intel_dsb_buffer_ggtt_offset(&dsb->dsb_buf) + intel_dsb_size(dsb);
|
||||
}
|
||||
|
||||
static void intel_dsb_ins_align(struct intel_dsb *dsb)
|
||||
{
|
||||
/*
|
||||
* Every instruction should be 8 byte aligned.
|
||||
*
|
||||
* The only way to get unaligned free_pos is via
|
||||
* intel_dsb_reg_write_indexed() which already
|
||||
* makes sure the next dword is zeroed, so no need
|
||||
* to clear it here.
|
||||
*/
|
||||
dsb->free_pos = ALIGN(dsb->free_pos, 2);
|
||||
}
|
||||
|
||||
static void intel_dsb_emit(struct intel_dsb *dsb, u32 ldw, u32 udw)
|
||||
{
|
||||
if (!assert_dsb_has_room(dsb))
|
||||
return;
|
||||
|
||||
/* Every instruction should be 8 byte aligned. */
|
||||
dsb->free_pos = ALIGN(dsb->free_pos, 2);
|
||||
intel_dsb_ins_align(dsb);
|
||||
|
||||
dsb->ins_start_offset = dsb->free_pos;
|
||||
dsb->ins[0] = ldw;
|
||||
|
|
@ -493,6 +532,8 @@ static void intel_dsb_align_tail(struct intel_dsb *dsb)
|
|||
{
|
||||
u32 aligned_tail, tail;
|
||||
|
||||
intel_dsb_ins_align(dsb);
|
||||
|
||||
tail = dsb->free_pos * 4;
|
||||
aligned_tail = ALIGN(tail, CACHELINE_BYTES);
|
||||
|
||||
|
|
@ -503,20 +544,90 @@ static void intel_dsb_align_tail(struct intel_dsb *dsb)
|
|||
dsb->free_pos = aligned_tail / 4;
|
||||
}
|
||||
|
||||
void intel_dsb_finish(struct intel_dsb *dsb)
|
||||
static void intel_dsb_gosub_align(struct intel_dsb *dsb)
|
||||
{
|
||||
struct intel_crtc *crtc = dsb->crtc;
|
||||
u32 aligned_tail, tail;
|
||||
|
||||
intel_dsb_ins_align(dsb);
|
||||
|
||||
tail = dsb->free_pos * 4;
|
||||
aligned_tail = ALIGN(tail, CACHELINE_BYTES);
|
||||
|
||||
/*
|
||||
* DSB_FORCE_DEWAKE remains active even after DSB is
|
||||
* disabled, so make sure to clear it (if set during
|
||||
* intel_dsb_commit()). And clear DSB_ENABLE_DEWAKE as
|
||||
* well for good measure.
|
||||
* Wa_16024917128
|
||||
* "Ensure GOSUB is not placed in cacheline QW slot 6 or 7 (numbered 0-7)"
|
||||
*/
|
||||
intel_dsb_reg_write(dsb, DSB_PMCTRL(crtc->pipe, dsb->id), 0);
|
||||
intel_dsb_reg_write_masked(dsb, DSB_PMCTRL_2(crtc->pipe, dsb->id),
|
||||
DSB_FORCE_DEWAKE, 0);
|
||||
if (aligned_tail - tail <= 2 * 8)
|
||||
intel_dsb_buffer_memset(&dsb->dsb_buf, dsb->free_pos, 0,
|
||||
aligned_tail - tail);
|
||||
|
||||
dsb->free_pos = aligned_tail / 4;
|
||||
}
|
||||
|
||||
void intel_dsb_gosub(struct intel_dsb *dsb,
|
||||
struct intel_dsb *sub_dsb)
|
||||
{
|
||||
struct intel_crtc *crtc = dsb->crtc;
|
||||
struct intel_display *display = to_intel_display(crtc->base.dev);
|
||||
unsigned int head, tail;
|
||||
u64 head_tail;
|
||||
|
||||
if (drm_WARN_ON(display->drm, dsb->id != sub_dsb->id))
|
||||
return;
|
||||
|
||||
if (!assert_dsb_tail_is_aligned(sub_dsb))
|
||||
return;
|
||||
|
||||
intel_dsb_gosub_align(dsb);
|
||||
|
||||
head = intel_dsb_head(sub_dsb);
|
||||
tail = intel_dsb_tail(sub_dsb);
|
||||
|
||||
/*
|
||||
* The GOSUB instruction has the following memory layout.
|
||||
*
|
||||
* +------------------------------------------------------------+
|
||||
* | Opcode | Rsvd | Head Ptr | Tail Ptr |
|
||||
* | 0x0c | | | |
|
||||
* +------------------------------------------------------------+
|
||||
* |<- 8bits->|<- 4bits ->|<-- 26bits -->|<-- 26bits -->|
|
||||
*
|
||||
* We have only 26 bits each to represent the head and tail
|
||||
* pointers even though the addresses itself are of 32 bit. However, this
|
||||
* is not a problem because the addresses are 64 bit aligned and therefore
|
||||
* the last 6 bits are always Zero's. Therefore, we right shift the address
|
||||
* by 6 before embedding it into the GOSUB instruction.
|
||||
*/
|
||||
|
||||
head_tail = ((u64)(DSB_GOSUB_CONVERT_ADDR(head)) << DSB_GOSUB_HEAD_SHIFT) |
|
||||
((u64)(DSB_GOSUB_CONVERT_ADDR(tail)) << DSB_GOSUB_TAIL_SHIFT);
|
||||
|
||||
intel_dsb_emit(dsb, lower_32_bits(head_tail),
|
||||
(DSB_OPCODE_GOSUB << DSB_OPCODE_SHIFT) |
|
||||
upper_32_bits(head_tail));
|
||||
|
||||
/*
|
||||
* "NOTE: the instructions within the cacheline
|
||||
* FOLLOWING the GOSUB instruction must be NOPs."
|
||||
*/
|
||||
intel_dsb_align_tail(dsb);
|
||||
}
|
||||
|
||||
void intel_dsb_gosub_finish(struct intel_dsb *dsb)
|
||||
{
|
||||
intel_dsb_align_tail(dsb);
|
||||
|
||||
/*
|
||||
* Wa_16024917128
|
||||
* "Ensure that all subroutines called by GOSUB end with a cacheline of NOPs"
|
||||
*/
|
||||
intel_dsb_noop(dsb, 8);
|
||||
|
||||
intel_dsb_buffer_flush_map(&dsb->dsb_buf);
|
||||
}
|
||||
|
||||
void intel_dsb_finish(struct intel_dsb *dsb)
|
||||
{
|
||||
intel_dsb_align_tail(dsb);
|
||||
|
||||
intel_dsb_buffer_flush_map(&dsb->dsb_buf);
|
||||
|
|
@ -539,6 +650,9 @@ static u32 dsb_error_int_status(struct intel_display *display)
|
|||
if (DISPLAY_VER(display) >= 14)
|
||||
errors |= DSB_ATS_FAULT_INT_STATUS;
|
||||
|
||||
if (DISPLAY_VER(display) >= 30)
|
||||
errors |= DSB_GOSUB_INT_STATUS;
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
|
|
@ -553,17 +667,46 @@ static u32 dsb_error_int_en(struct intel_display *display)
|
|||
if (DISPLAY_VER(display) >= 14)
|
||||
errors |= DSB_ATS_FAULT_INT_EN;
|
||||
|
||||
/*
|
||||
* Wa_16024917128
|
||||
* "Disable nested GOSUB interrupt (DSB_INTERRUPT bit 21)"
|
||||
*/
|
||||
if (0 && DISPLAY_VER(display) >= 30)
|
||||
errors |= DSB_GOSUB_INT_EN;
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME calibrate these sensibly, ideally compute based on
|
||||
* the number of regisetrs to be written. But that requires
|
||||
* measuring the actual DSB execution speed on each platform
|
||||
* (and the speed also depends on CDCLK and memory clock)...
|
||||
*/
|
||||
static int intel_dsb_noarm_exec_time_us(void)
|
||||
{
|
||||
return 80;
|
||||
}
|
||||
|
||||
static int intel_dsb_arm_exec_time_us(void)
|
||||
{
|
||||
return 20;
|
||||
}
|
||||
|
||||
int intel_dsb_exec_time_us(void)
|
||||
{
|
||||
return intel_dsb_noarm_exec_time_us() +
|
||||
intel_dsb_arm_exec_time_us();
|
||||
}
|
||||
|
||||
void intel_dsb_vblank_evade(struct intel_atomic_state *state,
|
||||
struct intel_dsb *dsb)
|
||||
{
|
||||
struct intel_crtc *crtc = dsb->crtc;
|
||||
const struct intel_crtc_state *crtc_state =
|
||||
intel_pre_commit_crtc_state(state, crtc);
|
||||
/* FIXME calibrate sensibly */
|
||||
int latency = intel_usecs_to_scanlines(&crtc_state->hw.adjusted_mode, 20);
|
||||
int latency = intel_usecs_to_scanlines(&crtc_state->hw.adjusted_mode,
|
||||
intel_dsb_arm_exec_time_us());
|
||||
int start, end;
|
||||
|
||||
/*
|
||||
|
|
@ -605,13 +748,11 @@ static void _intel_dsb_chain(struct intel_atomic_state *state,
|
|||
struct intel_display *display = to_intel_display(state->base.dev);
|
||||
struct intel_crtc *crtc = dsb->crtc;
|
||||
enum pipe pipe = crtc->pipe;
|
||||
u32 tail;
|
||||
|
||||
if (drm_WARN_ON(display->drm, dsb->id == chained_dsb->id))
|
||||
return;
|
||||
|
||||
tail = chained_dsb->free_pos * 4;
|
||||
if (drm_WARN_ON(display->drm, !IS_ALIGNED(tail, CACHELINE_BYTES)))
|
||||
if (!assert_dsb_tail_is_aligned(chained_dsb))
|
||||
return;
|
||||
|
||||
intel_dsb_reg_write(dsb, DSB_CTRL(pipe, chained_dsb->id),
|
||||
|
|
@ -631,13 +772,15 @@ static void _intel_dsb_chain(struct intel_atomic_state *state,
|
|||
intel_dsb_reg_write(dsb, DSB_PMCTRL(pipe, chained_dsb->id),
|
||||
DSB_ENABLE_DEWAKE |
|
||||
DSB_SCANLINE_FOR_DEWAKE(hw_dewake_scanline));
|
||||
} else {
|
||||
intel_dsb_reg_write(dsb, DSB_PMCTRL(pipe, chained_dsb->id), 0);
|
||||
}
|
||||
|
||||
intel_dsb_reg_write(dsb, DSB_HEAD(pipe, chained_dsb->id),
|
||||
intel_dsb_buffer_ggtt_offset(&chained_dsb->dsb_buf));
|
||||
intel_dsb_head(chained_dsb));
|
||||
|
||||
intel_dsb_reg_write(dsb, DSB_TAIL(pipe, chained_dsb->id),
|
||||
intel_dsb_buffer_ggtt_offset(&chained_dsb->dsb_buf) + tail);
|
||||
intel_dsb_tail(chained_dsb));
|
||||
|
||||
if (ctrl & DSB_WAIT_FOR_VBLANK) {
|
||||
/*
|
||||
|
|
@ -652,6 +795,13 @@ static void _intel_dsb_chain(struct intel_atomic_state *state,
|
|||
intel_dsb_wait_scanline_out(state, dsb,
|
||||
dsb_dewake_scanline_start(state, crtc),
|
||||
dsb_dewake_scanline_end(state, crtc));
|
||||
|
||||
/*
|
||||
* DSB_FORCE_DEWAKE remains active even after DSB is
|
||||
* disabled, so make sure to clear it.
|
||||
*/
|
||||
intel_dsb_reg_write_masked(dsb, DSB_PMCTRL_2(crtc->pipe, dsb->id),
|
||||
DSB_FORCE_DEWAKE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -676,16 +826,19 @@ void intel_dsb_wait_vblank_delay(struct intel_atomic_state *state,
|
|||
intel_dsb_wait_usec(dsb, usecs);
|
||||
}
|
||||
|
||||
static void _intel_dsb_commit(struct intel_dsb *dsb, u32 ctrl,
|
||||
int hw_dewake_scanline)
|
||||
/**
|
||||
* intel_dsb_commit() - Trigger workload execution of DSB.
|
||||
* @dsb: DSB context
|
||||
*
|
||||
* This function is used to do actual write to hardware using DSB.
|
||||
*/
|
||||
void intel_dsb_commit(struct intel_dsb *dsb)
|
||||
{
|
||||
struct intel_crtc *crtc = dsb->crtc;
|
||||
struct intel_display *display = to_intel_display(crtc->base.dev);
|
||||
enum pipe pipe = crtc->pipe;
|
||||
u32 tail;
|
||||
|
||||
tail = dsb->free_pos * 4;
|
||||
if (drm_WARN_ON(display->drm, !IS_ALIGNED(tail, CACHELINE_BYTES)))
|
||||
if (!assert_dsb_tail_is_aligned(dsb))
|
||||
return;
|
||||
|
||||
if (is_dsb_busy(display, pipe, dsb->id)) {
|
||||
|
|
@ -695,7 +848,7 @@ static void _intel_dsb_commit(struct intel_dsb *dsb, u32 ctrl,
|
|||
}
|
||||
|
||||
intel_de_write_fw(display, DSB_CTRL(pipe, dsb->id),
|
||||
ctrl | DSB_ENABLE);
|
||||
DSB_ENABLE);
|
||||
|
||||
intel_de_write_fw(display, DSB_CHICKEN(pipe, dsb->id),
|
||||
dsb->chicken);
|
||||
|
|
@ -704,45 +857,13 @@ static void _intel_dsb_commit(struct intel_dsb *dsb, u32 ctrl,
|
|||
dsb_error_int_status(display) | DSB_PROG_INT_STATUS |
|
||||
dsb_error_int_en(display) | DSB_PROG_INT_EN);
|
||||
|
||||
intel_de_write_fw(display, DSB_PMCTRL(pipe, dsb->id), 0);
|
||||
|
||||
intel_de_write_fw(display, DSB_HEAD(pipe, dsb->id),
|
||||
intel_dsb_buffer_ggtt_offset(&dsb->dsb_buf));
|
||||
|
||||
if (hw_dewake_scanline >= 0) {
|
||||
int diff, position;
|
||||
|
||||
intel_de_write_fw(display, DSB_PMCTRL(pipe, dsb->id),
|
||||
DSB_ENABLE_DEWAKE |
|
||||
DSB_SCANLINE_FOR_DEWAKE(hw_dewake_scanline));
|
||||
|
||||
/*
|
||||
* Force DEwake immediately if we're already past
|
||||
* or close to racing past the target scanline.
|
||||
*/
|
||||
position = intel_de_read_fw(display, PIPEDSL(display, pipe)) & PIPEDSL_LINE_MASK;
|
||||
|
||||
diff = hw_dewake_scanline - position;
|
||||
intel_de_write_fw(display, DSB_PMCTRL_2(pipe, dsb->id),
|
||||
(diff >= 0 && diff < 5 ? DSB_FORCE_DEWAKE : 0) |
|
||||
DSB_BLOCK_DEWAKE_EXTENSION);
|
||||
}
|
||||
intel_dsb_head(dsb));
|
||||
|
||||
intel_de_write_fw(display, DSB_TAIL(pipe, dsb->id),
|
||||
intel_dsb_buffer_ggtt_offset(&dsb->dsb_buf) + tail);
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_dsb_commit() - Trigger workload execution of DSB.
|
||||
* @dsb: DSB context
|
||||
* @wait_for_vblank: wait for vblank before executing
|
||||
*
|
||||
* This function is used to do actual write to hardware using DSB.
|
||||
*/
|
||||
void intel_dsb_commit(struct intel_dsb *dsb,
|
||||
bool wait_for_vblank)
|
||||
{
|
||||
_intel_dsb_commit(dsb,
|
||||
wait_for_vblank ? DSB_WAIT_FOR_VBLANK : 0,
|
||||
wait_for_vblank ? dsb->hw_dewake_scanline : -1);
|
||||
intel_dsb_tail(dsb));
|
||||
}
|
||||
|
||||
void intel_dsb_wait(struct intel_dsb *dsb)
|
||||
|
|
@ -895,4 +1016,7 @@ void intel_dsb_irq_handler(struct intel_display *display,
|
|||
if (errors & DSB_POLL_ERR_INT_STATUS)
|
||||
drm_err(display->drm, "[CRTC:%d:%s] DSB %d poll error\n",
|
||||
crtc->base.base.id, crtc->base.name, dsb_id);
|
||||
if (errors & DSB_GOSUB_INT_STATUS)
|
||||
drm_err(display->drm, "[CRTC:%d:%s] DSB %d GOSUB programming error\n",
|
||||
crtc->base.base.id, crtc->base.name, dsb_id);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,12 +26,16 @@ enum intel_dsb_id {
|
|||
I915_MAX_DSBS,
|
||||
};
|
||||
|
||||
unsigned int intel_dsb_size(struct intel_dsb *dsb);
|
||||
unsigned int intel_dsb_head(struct intel_dsb *dsb);
|
||||
struct intel_dsb *intel_dsb_prepare(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc,
|
||||
enum intel_dsb_id dsb_id,
|
||||
unsigned int max_cmds);
|
||||
void intel_dsb_finish(struct intel_dsb *dsb);
|
||||
void intel_dsb_gosub_finish(struct intel_dsb *dsb);
|
||||
void intel_dsb_cleanup(struct intel_dsb *dsb);
|
||||
int intel_dsb_exec_time_us(void);
|
||||
void intel_dsb_reg_write(struct intel_dsb *dsb,
|
||||
i915_reg_t reg, u32 val);
|
||||
void intel_dsb_reg_write_indexed(struct intel_dsb *dsb,
|
||||
|
|
@ -57,13 +61,14 @@ void intel_dsb_vblank_evade(struct intel_atomic_state *state,
|
|||
void intel_dsb_poll(struct intel_dsb *dsb,
|
||||
i915_reg_t reg, u32 mask, u32 val,
|
||||
int wait_us, int count);
|
||||
void intel_dsb_gosub(struct intel_dsb *dsb,
|
||||
struct intel_dsb *sub_dsb);
|
||||
void intel_dsb_chain(struct intel_atomic_state *state,
|
||||
struct intel_dsb *dsb,
|
||||
struct intel_dsb *chained_dsb,
|
||||
bool wait_for_vblank);
|
||||
|
||||
void intel_dsb_commit(struct intel_dsb *dsb,
|
||||
bool wait_for_vblank);
|
||||
void intel_dsb_commit(struct intel_dsb *dsb);
|
||||
void intel_dsb_wait(struct intel_dsb *dsb);
|
||||
|
||||
void intel_dsb_irq_handler(struct intel_display *display,
|
||||
|
|
|
|||
|
|
@ -51,11 +51,13 @@
|
|||
#define DSB_RESET_SM_STATE_MASK REG_GENMASK(5, 4)
|
||||
#define DSB_RUN_SM_STATE_MASK REG_GENMASK(2, 0)
|
||||
#define DSB_INTERRUPT(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x28)
|
||||
#define DSB_GOSUB_INT_EN REG_BIT(21) /* ptl+ */
|
||||
#define DSB_ATS_FAULT_INT_EN REG_BIT(20) /* mtl+ */
|
||||
#define DSB_GTT_FAULT_INT_EN REG_BIT(19)
|
||||
#define DSB_RSPTIMEOUT_INT_EN REG_BIT(18)
|
||||
#define DSB_POLL_ERR_INT_EN REG_BIT(17)
|
||||
#define DSB_PROG_INT_EN REG_BIT(16)
|
||||
#define DSB_GOSUB_INT_STATUS REG_BIT(5) /* ptl+ */
|
||||
#define DSB_ATS_FAULT_INT_STATUS REG_BIT(4) /* mtl+ */
|
||||
#define DSB_GTT_FAULT_INT_STATUS REG_BIT(3)
|
||||
#define DSB_RSPTIMEOUT_INT_STATUS REG_BIT(2)
|
||||
|
|
|
|||
|
|
@ -36,12 +36,11 @@
|
|||
#include <drm/drm_crtc.h>
|
||||
#include <drm/drm_edid.h>
|
||||
#include <drm/drm_print.h>
|
||||
|
||||
#include <video/mipi_display.h>
|
||||
|
||||
#include "i915_reg.h"
|
||||
#include "i915_utils.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dsi.h"
|
||||
#include "intel_dsi_vbt.h"
|
||||
|
|
|
|||
|
|
@ -34,11 +34,11 @@
|
|||
#include <drm/drm_print.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
|
||||
#include "i915_reg.h"
|
||||
#include "i915_utils.h"
|
||||
#include "intel_connector.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_driver.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dvo.h"
|
||||
#include "intel_dvo_dev.h"
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
#include <linux/workqueue.h>
|
||||
|
||||
#include "i915_drv.h"
|
||||
|
||||
#include "intel_display_core.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_encoder.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include "intel_atomic_plane.h"
|
||||
#include "intel_bo.h"
|
||||
#include "intel_display.h"
|
||||
#include "intel_display_core.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dpt.h"
|
||||
#include "intel_fb.h"
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include "gem/i915_gem_object.h"
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "intel_display_core.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_fb.h"
|
||||
#include "intel_fb_bo.h"
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "i915_drv.h"
|
||||
#include "intel_atomic_plane.h"
|
||||
#include "intel_display_core.h"
|
||||
#include "intel_display_rpm.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dpt.h"
|
||||
|
|
|
|||
|
|
@ -45,9 +45,10 @@
|
|||
#include <drm/drm_fourcc.h>
|
||||
|
||||
#include "gem/i915_gem_stolen.h"
|
||||
|
||||
#include "gt/intel_gt_types.h"
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include "i915_utils.h"
|
||||
#include "i915_vgpu.h"
|
||||
#include "i915_vma.h"
|
||||
|
|
@ -55,6 +56,7 @@
|
|||
#include "intel_cdclk.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_device.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_rpm.h"
|
||||
#include "intel_display_trace.h"
|
||||
#include "intel_display_types.h"
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include "gem/i915_gem_lmem.h"
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "intel_display_core.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_fb.h"
|
||||
#include "intel_fbdev_fb.h"
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include "intel_crtc.h"
|
||||
#include "intel_ddi.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dp.h"
|
||||
#include "intel_fdi.h"
|
||||
|
|
@ -910,7 +911,7 @@ void hsw_fdi_link_train(struct intel_encoder *encoder,
|
|||
intel_de_write(display, FDI_RX_CTL(PIPE_A), rx_ctl_val);
|
||||
|
||||
/* Configure Port Clock Select */
|
||||
drm_WARN_ON(display->drm, crtc_state->shared_dpll->info->id != DPLL_ID_SPLL);
|
||||
drm_WARN_ON(display->drm, crtc_state->intel_dpll->info->id != DPLL_ID_SPLL);
|
||||
intel_ddi_enable_clock(encoder, crtc_state);
|
||||
|
||||
/* Start the training iterating through available voltages and emphasis,
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include "i915_reg.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_irq.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_trace.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_fbc.h"
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
#include "i915_irq.h"
|
||||
#include "i915_reg.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_gmbus.h"
|
||||
#include "intel_gmbus_regs.h"
|
||||
|
|
@ -414,7 +415,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);
|
||||
ret = intel_de_wait_fw(display, GMBUS2(display), GMBUS_ACTIVE, 0, 10, NULL);
|
||||
|
||||
intel_de_write_fw(display, GMBUS4(display), 0);
|
||||
remove_wait_queue(&display->gmbus.wait_queue, &wait);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
#ifndef __INTEL_GMBUS_REGS_H__
|
||||
#define __INTEL_GMBUS_REGS_H__
|
||||
|
||||
#include "i915_reg_defs.h"
|
||||
#include "intel_display_reg_defs.h"
|
||||
|
||||
#define __GMBUS_MMIO_BASE(__display) ((__display)->gmbus.mmio_base)
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include "intel_de.h"
|
||||
#include "intel_display_power.h"
|
||||
#include "intel_display_power_well.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_rpm.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dp_mst.h"
|
||||
|
|
|
|||
|
|
@ -41,11 +41,9 @@
|
|||
#include <drm/drm_print.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
#include <drm/intel/intel_lpe_audio.h>
|
||||
|
||||
#include <media/cec-notifier.h>
|
||||
|
||||
#include "g4x_hdmi.h"
|
||||
#include "i915_reg.h"
|
||||
#include "i915_utils.h"
|
||||
#include "intel_atomic.h"
|
||||
#include "intel_audio.h"
|
||||
|
|
@ -54,6 +52,7 @@
|
|||
#include "intel_ddi.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_driver.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dp.h"
|
||||
#include "intel_gmbus.h"
|
||||
|
|
|
|||
|
|
@ -30,8 +30,10 @@
|
|||
#include "i915_irq.h"
|
||||
#include "intel_connector.h"
|
||||
#include "intel_display_power.h"
|
||||
#include "intel_display_core.h"
|
||||
#include "intel_display_rpm.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dp.h"
|
||||
#include "intel_hdcp.h"
|
||||
#include "intel_hotplug.h"
|
||||
#include "intel_hotplug_irq.h"
|
||||
|
|
@ -905,9 +907,14 @@ void intel_hpd_poll_enable(struct intel_display *display)
|
|||
*/
|
||||
void intel_hpd_poll_disable(struct intel_display *display)
|
||||
{
|
||||
struct intel_encoder *encoder;
|
||||
|
||||
if (!HAS_DISPLAY(display))
|
||||
return;
|
||||
|
||||
for_each_intel_dp(display->drm, encoder)
|
||||
intel_dp_dpcd_set_probe(enc_to_intel_dp(encoder), true);
|
||||
|
||||
WRITE_ONCE(display->hotplug.poll_enabled, false);
|
||||
|
||||
spin_lock_irq(&display->irq.lock);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include "i915_utils.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_irq.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dp_aux.h"
|
||||
#include "intel_gmbus.h"
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
#ifndef __INTEL_HTI_REGS_H__
|
||||
#define __INTEL_HTI_REGS_H__
|
||||
|
||||
#include "i915_reg_defs.h"
|
||||
#include "intel_display_reg_defs.h"
|
||||
|
||||
#define HDPORT_STATE _MMIO(0x45050)
|
||||
#define HDPORT_DPLL_USED_MASK REG_GENMASK(15, 12)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,11 @@
|
|||
* Copyright © 2023 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/int_log.h>
|
||||
#include <linux/math.h>
|
||||
|
||||
#include <drm/drm_fixed.h>
|
||||
#include <drm/drm_print.h>
|
||||
|
||||
|
|
@ -10,11 +15,33 @@
|
|||
#include "intel_crtc.h"
|
||||
#include "intel_display_core.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dp.h"
|
||||
#include "intel_dp_mst.h"
|
||||
#include "intel_dp_tunnel.h"
|
||||
#include "intel_fdi.h"
|
||||
#include "intel_link_bw.h"
|
||||
|
||||
static int get_forced_link_bpp_x16(struct intel_atomic_state *state,
|
||||
const struct intel_crtc *crtc)
|
||||
{
|
||||
struct intel_digital_connector_state *conn_state;
|
||||
struct intel_connector *connector;
|
||||
int force_bpp_x16 = INT_MAX;
|
||||
int i;
|
||||
|
||||
for_each_new_intel_connector_in_state(state, connector, conn_state, i) {
|
||||
if (conn_state->base.crtc != &crtc->base)
|
||||
continue;
|
||||
|
||||
if (!connector->link.force_bpp_x16)
|
||||
continue;
|
||||
|
||||
force_bpp_x16 = min(force_bpp_x16, connector->link.force_bpp_x16);
|
||||
}
|
||||
|
||||
return force_bpp_x16 < INT_MAX ? force_bpp_x16 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_link_bw_init_limits - initialize BW limits
|
||||
* @state: Atomic state
|
||||
|
|
@ -31,9 +58,10 @@ void intel_link_bw_init_limits(struct intel_atomic_state *state,
|
|||
limits->force_fec_pipes = 0;
|
||||
limits->bpp_limit_reached_pipes = 0;
|
||||
for_each_pipe(display, pipe) {
|
||||
struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe);
|
||||
const struct intel_crtc_state *crtc_state =
|
||||
intel_atomic_get_new_crtc_state(state,
|
||||
intel_crtc_for_pipe(display, pipe));
|
||||
intel_atomic_get_new_crtc_state(state, crtc);
|
||||
int forced_bpp_x16 = get_forced_link_bpp_x16(state, crtc);
|
||||
|
||||
if (state->base.duplicated && crtc_state) {
|
||||
limits->max_bpp_x16[pipe] = crtc_state->max_link_bpp_x16;
|
||||
|
|
@ -42,15 +70,19 @@ void intel_link_bw_init_limits(struct intel_atomic_state *state,
|
|||
} else {
|
||||
limits->max_bpp_x16[pipe] = INT_MAX;
|
||||
}
|
||||
|
||||
if (forced_bpp_x16)
|
||||
limits->max_bpp_x16[pipe] = min(limits->max_bpp_x16[pipe], forced_bpp_x16);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_link_bw_reduce_bpp - reduce maximum link bpp for a selected pipe
|
||||
* __intel_link_bw_reduce_bpp - reduce maximum link bpp for a selected pipe
|
||||
* @state: atomic state
|
||||
* @limits: link BW limits
|
||||
* @pipe_mask: mask of pipes to select from
|
||||
* @reason: explanation of why bpp reduction is needed
|
||||
* @reduce_forced_bpp: allow reducing bpps below their forced link bpp
|
||||
*
|
||||
* Select the pipe from @pipe_mask with the biggest link bpp value and set the
|
||||
* maximum of link bpp in @limits below this value. Modeset the selected pipe,
|
||||
|
|
@ -64,10 +96,11 @@ void intel_link_bw_init_limits(struct intel_atomic_state *state,
|
|||
* - %-ENOSPC if no pipe can further reduce its link bpp
|
||||
* - Other negative error, if modesetting the selected pipe failed
|
||||
*/
|
||||
int intel_link_bw_reduce_bpp(struct intel_atomic_state *state,
|
||||
struct intel_link_bw_limits *limits,
|
||||
u8 pipe_mask,
|
||||
const char *reason)
|
||||
static int __intel_link_bw_reduce_bpp(struct intel_atomic_state *state,
|
||||
struct intel_link_bw_limits *limits,
|
||||
u8 pipe_mask,
|
||||
const char *reason,
|
||||
bool reduce_forced_bpp)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(state);
|
||||
enum pipe max_bpp_pipe = INVALID_PIPE;
|
||||
|
|
@ -97,6 +130,10 @@ int intel_link_bw_reduce_bpp(struct intel_atomic_state *state,
|
|||
*/
|
||||
link_bpp_x16 = fxp_q4_from_int(crtc_state->pipe_bpp);
|
||||
|
||||
if (!reduce_forced_bpp &&
|
||||
link_bpp_x16 <= get_forced_link_bpp_x16(state, crtc))
|
||||
continue;
|
||||
|
||||
if (link_bpp_x16 > max_bpp_x16) {
|
||||
max_bpp_x16 = link_bpp_x16;
|
||||
max_bpp_pipe = crtc->pipe;
|
||||
|
|
@ -112,6 +149,21 @@ int intel_link_bw_reduce_bpp(struct intel_atomic_state *state,
|
|||
BIT(max_bpp_pipe));
|
||||
}
|
||||
|
||||
int intel_link_bw_reduce_bpp(struct intel_atomic_state *state,
|
||||
struct intel_link_bw_limits *limits,
|
||||
u8 pipe_mask,
|
||||
const char *reason)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Try to keep any forced link BPP. */
|
||||
ret = __intel_link_bw_reduce_bpp(state, limits, pipe_mask, reason, false);
|
||||
if (ret == -ENOSPC)
|
||||
ret = __intel_link_bw_reduce_bpp(state, limits, pipe_mask, reason, true);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_link_bw_set_bpp_limit_for_pipe - set link bpp limit for a pipe to its minimum
|
||||
* @state: atomic state
|
||||
|
|
@ -245,3 +297,176 @@ int intel_link_bw_atomic_check(struct intel_atomic_state *state,
|
|||
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
static int force_link_bpp_show(struct seq_file *m, void *data)
|
||||
{
|
||||
struct intel_connector *connector = m->private;
|
||||
|
||||
seq_printf(m, FXP_Q4_FMT "\n", FXP_Q4_ARGS(connector->link.force_bpp_x16));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int str_to_fxp_q4_nonneg_int(const char *str, int *val_x16)
|
||||
{
|
||||
unsigned int val;
|
||||
int err;
|
||||
|
||||
err = kstrtouint(str, 10, &val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (val > INT_MAX >> 4)
|
||||
return -ERANGE;
|
||||
|
||||
*val_x16 = fxp_q4_from_int(val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* modifies str */
|
||||
static int str_to_fxp_q4_nonneg(char *str, int *val_x16)
|
||||
{
|
||||
const char *int_str;
|
||||
char *frac_str;
|
||||
int frac_digits;
|
||||
int frac_val;
|
||||
int err;
|
||||
|
||||
int_str = strim(str);
|
||||
frac_str = strchr(int_str, '.');
|
||||
|
||||
if (frac_str)
|
||||
*frac_str++ = '\0';
|
||||
|
||||
err = str_to_fxp_q4_nonneg_int(int_str, val_x16);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (!frac_str)
|
||||
return 0;
|
||||
|
||||
/* prevent negative number/leading +- sign mark */
|
||||
if (!isdigit(*frac_str))
|
||||
return -EINVAL;
|
||||
|
||||
err = str_to_fxp_q4_nonneg_int(frac_str, &frac_val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
frac_digits = strlen(frac_str);
|
||||
if (frac_digits > intlog10(INT_MAX) >> 24 ||
|
||||
frac_val > INT_MAX - int_pow(10, frac_digits) / 2)
|
||||
return -ERANGE;
|
||||
|
||||
frac_val = DIV_ROUND_CLOSEST(frac_val, (int)int_pow(10, frac_digits));
|
||||
|
||||
if (*val_x16 > INT_MAX - frac_val)
|
||||
return -ERANGE;
|
||||
|
||||
*val_x16 += frac_val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int user_str_to_fxp_q4_nonneg(const char __user *ubuf, size_t len, int *val_x16)
|
||||
{
|
||||
char *kbuf;
|
||||
int err;
|
||||
|
||||
kbuf = memdup_user_nul(ubuf, len);
|
||||
if (IS_ERR(kbuf))
|
||||
return PTR_ERR(kbuf);
|
||||
|
||||
err = str_to_fxp_q4_nonneg(kbuf, val_x16);
|
||||
|
||||
kfree(kbuf);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static bool connector_supports_dsc(struct intel_connector *connector)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(connector);
|
||||
|
||||
switch (connector->base.connector_type) {
|
||||
case DRM_MODE_CONNECTOR_eDP:
|
||||
return intel_dp_has_dsc(connector);
|
||||
case DRM_MODE_CONNECTOR_DisplayPort:
|
||||
if (connector->mst.dp)
|
||||
return HAS_DSC_MST(display);
|
||||
|
||||
return HAS_DSC(display);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
force_link_bpp_write(struct file *file, const char __user *ubuf, size_t len, loff_t *offp)
|
||||
{
|
||||
struct seq_file *m = file->private_data;
|
||||
struct intel_connector *connector = m->private;
|
||||
struct intel_display *display = to_intel_display(connector);
|
||||
int min_bpp;
|
||||
int bpp_x16;
|
||||
int err;
|
||||
|
||||
err = user_str_to_fxp_q4_nonneg(ubuf, len, &bpp_x16);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* TODO: Make the non-DSC min_bpp value connector specific. */
|
||||
if (connector_supports_dsc(connector))
|
||||
min_bpp = intel_dp_dsc_min_src_compressed_bpp();
|
||||
else
|
||||
min_bpp = intel_display_min_pipe_bpp();
|
||||
|
||||
if (bpp_x16 &&
|
||||
(bpp_x16 < fxp_q4_from_int(min_bpp) ||
|
||||
bpp_x16 > fxp_q4_from_int(intel_display_max_pipe_bpp(display))))
|
||||
return -EINVAL;
|
||||
|
||||
err = drm_modeset_lock_single_interruptible(&display->drm->mode_config.connection_mutex);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
connector->link.force_bpp_x16 = bpp_x16;
|
||||
|
||||
drm_modeset_unlock(&display->drm->mode_config.connection_mutex);
|
||||
|
||||
*offp += len;
|
||||
|
||||
return len;
|
||||
}
|
||||
DEFINE_SHOW_STORE_ATTRIBUTE(force_link_bpp);
|
||||
|
||||
void intel_link_bw_connector_debugfs_add(struct intel_connector *connector)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(connector);
|
||||
struct dentry *root = connector->base.debugfs_entry;
|
||||
|
||||
switch (connector->base.connector_type) {
|
||||
case DRM_MODE_CONNECTOR_DisplayPort:
|
||||
case DRM_MODE_CONNECTOR_eDP:
|
||||
break;
|
||||
case DRM_MODE_CONNECTOR_VGA:
|
||||
case DRM_MODE_CONNECTOR_SVIDEO:
|
||||
case DRM_MODE_CONNECTOR_LVDS:
|
||||
case DRM_MODE_CONNECTOR_DVID:
|
||||
if (HAS_FDI(display))
|
||||
break;
|
||||
|
||||
return;
|
||||
case DRM_MODE_CONNECTOR_HDMIA:
|
||||
if (HAS_FDI(display) && !HAS_DDI(display))
|
||||
break;
|
||||
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
debugfs_create_file("intel_force_link_bpp", 0644, root,
|
||||
connector, &force_link_bpp_fops);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include "intel_display_limits.h"
|
||||
|
||||
struct intel_atomic_state;
|
||||
struct intel_connector;
|
||||
struct intel_crtc_state;
|
||||
|
||||
struct intel_link_bw_limits {
|
||||
|
|
@ -32,5 +33,6 @@ bool intel_link_bw_set_bpp_limit_for_pipe(struct intel_atomic_state *state,
|
|||
enum pipe pipe);
|
||||
int intel_link_bw_atomic_check(struct intel_atomic_state *state,
|
||||
struct intel_link_bw_limits *new_limits);
|
||||
void intel_link_bw_connector_debugfs_add(struct intel_connector *connector);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -29,9 +29,9 @@
|
|||
#include <drm/drm_edid.h>
|
||||
#include <drm/drm_print.h>
|
||||
|
||||
#include "i915_reg.h"
|
||||
#include "i915_utils.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dp.h"
|
||||
#include "intel_hdmi.h"
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@
|
|||
#include <drm/drm_print.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
|
||||
#include "i915_reg.h"
|
||||
#include "intel_atomic.h"
|
||||
#include "intel_backlight.h"
|
||||
#include "intel_connector.h"
|
||||
|
|
@ -249,7 +248,7 @@ static void intel_pre_enable_lvds(struct intel_atomic_state *state,
|
|||
|
||||
if (HAS_PCH_SPLIT(display)) {
|
||||
assert_fdi_rx_pll_disabled(display, pipe);
|
||||
assert_shared_dpll_disabled(display, crtc_state->shared_dpll);
|
||||
assert_dpll_disabled(display, crtc_state->intel_dpll);
|
||||
} else {
|
||||
assert_pll_disabled(display, pipe);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include "intel_de.h"
|
||||
#include "intel_display.h"
|
||||
#include "intel_display_power.h"
|
||||
#include "intel_display_regs.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dmc.h"
|
||||
#include "intel_fifo_underrun.h"
|
||||
|
|
@ -92,10 +93,10 @@ static void intel_crtc_disable_noatomic_begin(struct intel_crtc *crtc,
|
|||
crtc->active = false;
|
||||
crtc->base.enabled = false;
|
||||
|
||||
if (crtc_state->shared_dpll)
|
||||
intel_unreference_shared_dpll_crtc(crtc,
|
||||
crtc_state->shared_dpll,
|
||||
&crtc_state->shared_dpll->state);
|
||||
if (crtc_state->intel_dpll)
|
||||
intel_dpll_crtc_put(crtc,
|
||||
crtc_state->intel_dpll,
|
||||
&crtc_state->intel_dpll->state);
|
||||
}
|
||||
|
||||
static void set_encoder_for_connector(struct intel_connector *connector,
|
||||
|
|
@ -565,7 +566,7 @@ static bool has_bogus_dpll_config(const struct intel_crtc_state *crtc_state)
|
|||
*/
|
||||
return display->platform.sandybridge &&
|
||||
crtc_state->hw.active &&
|
||||
crtc_state->shared_dpll &&
|
||||
crtc_state->intel_dpll &&
|
||||
crtc_state->port_clock == 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -243,7 +243,7 @@ void intel_modeset_verify_crtc(struct intel_atomic_state *state,
|
|||
intel_wm_state_verify(state, crtc);
|
||||
verify_connector_state(state, crtc);
|
||||
verify_crtc_state(state, crtc);
|
||||
intel_shared_dpll_state_verify(state, crtc);
|
||||
intel_dpll_state_verify(state, crtc);
|
||||
intel_mpllb_state_verify(state, crtc);
|
||||
intel_cx0pll_state_verify(state, crtc);
|
||||
}
|
||||
|
|
@ -252,5 +252,5 @@ void intel_modeset_verify_disabled(struct intel_atomic_state *state)
|
|||
{
|
||||
verify_encoder_state(state);
|
||||
verify_connector_state(state, NULL);
|
||||
intel_shared_dpll_verify_disabled(state);
|
||||
intel_dpll_verify_disabled(state);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
#include "i915_drv.h"
|
||||
#include "intel_acpi.h"
|
||||
#include "intel_backlight.h"
|
||||
#include "intel_display_core.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_opregion.h"
|
||||
#include "intel_pci_config.h"
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue