Commit e047c7be authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-intel-next-queued-2020-11-03' of...

Merge tag 'drm-intel-next-queued-2020-11-03' of git://anongit.freedesktop.org/drm/drm-intel into drm-next

drm/i915 features for v5.11

Highlights:
- More DG1 enabling (Lucas, Matt, Aditya, Anshuman, Clinton, Matt, Stuart, Venkata)
- Integer scaling filter support (Pankaj Bharadiya)
- Asynchronous flip support (Karthik)

Generic:
- Fix gen12 forcewake tables (Matt)
- Haswell PCI ID updates (Alexei Podtelezhnikov)

Display:
- ICL+ DSI command mode enabling (Vandita)
- Shutdown displays grafecully on reboot/shutdown (Ville)
- Don't register display debugfs when there is no display (Lucas)
- Fix RKL CDCLK table (Matt)
- Limit EHL/JSL eDP to HBR2 (José)
- Handle incorrectly set (by BIOS) PLLs and DP link rates at probe (Imre)
- Fix mode valid check wrt bpp for "YCbCr 4:2:0 only" modes (Ville)
- State checker and dump fixes (Ville)
- DP AUX backlight updates (Aaron Ma, Sean Paul)
- Add DP LTTPR non-transparent link training mode (Imre)
- PSR2 selective fetch enabling (José)
- VBT updates (José)
- HDCP updates (Ramalingam)

Cleanups and refactoring:
- HPD pin, AUX channel, and Type-C port identifier cleanup (Ville)
- Hotplug and irq refactoring (Ville)
- Better DDI encoder and AUX channel names (Ville)
- Color LUT code cleanups (Ville)
- Combo PHY code cleanups (Ville)
- LSPCON code cleanups (Ville)
- Documentation fixes (Mauro, Chris)
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/87o8kehbaj.fsf@intel.com
parents 1cd260a7 139caf7c
......@@ -118,6 +118,12 @@ Atomic Plane Helpers
.. kernel-doc:: drivers/gpu/drm/i915/display/intel_atomic_plane.c
:internal:
Asynchronous Page Flip
----------------------
.. kernel-doc:: drivers/gpu/drm/i915/display/intel_display.c
:doc: asynchronous flip implementation
Output Probing
--------------
......
......@@ -469,6 +469,8 @@ static int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
return -EFAULT;
set_out_fence_for_crtc(state->state, crtc, fence_ptr);
} else if (property == crtc->scaling_filter_property) {
state->scaling_filter = val;
} else if (crtc->funcs->atomic_set_property) {
return crtc->funcs->atomic_set_property(crtc, state, property, val);
} else {
......@@ -503,6 +505,8 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc,
*val = (state->gamma_lut) ? state->gamma_lut->base.id : 0;
else if (property == config->prop_out_fence_ptr)
*val = 0;
else if (property == crtc->scaling_filter_property)
*val = state->scaling_filter;
else if (crtc->funcs->atomic_get_property)
return crtc->funcs->atomic_get_property(crtc, state, property, val);
else
......@@ -585,6 +589,8 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane,
sizeof(struct drm_rect),
&replaced);
return ret;
} else if (property == plane->scaling_filter_property) {
state->scaling_filter = val;
} else if (plane->funcs->atomic_set_property) {
return plane->funcs->atomic_set_property(plane, state,
property, val);
......@@ -643,6 +649,8 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
} else if (property == config->prop_fb_damage_clips) {
*val = (state->fb_damage_clips) ?
state->fb_damage_clips->base.id : 0;
} else if (property == plane->scaling_filter_property) {
*val = state->scaling_filter;
} else if (plane->funcs->atomic_get_property) {
return plane->funcs->atomic_get_property(plane, state, property, val);
} else {
......
......@@ -194,6 +194,19 @@
* Note that all the property extensions described here apply either to the
* plane or the CRTC (e.g. for the background color, which currently is not
* exposed and assumed to be black).
*
* SCALING_FILTER:
*
* Indicates scaling filter to be used for plane scaler
*
* The value of this property can be one of the following:
* Default:
* Driver's default scaling filter
* Nearest Neighbor:
* Nearest Neighbor scaling filter
*
* Drivers can set up this property for a plane by calling
* drm_plane_create_scaling_filter_property
*/
/**
......
......@@ -229,6 +229,15 @@ struct dma_fence *drm_crtc_create_fence(struct drm_crtc *crtc)
* user-space must set this property to 0.
*
* Setting MODE_ID to 0 will release reserved resources for the CRTC.
* SCALING_FILTER:
* Atomic property for setting the scaling filter for CRTC scaler
*
* The value of this property can be one of the following:
* Default:
* Driver's default scaling filter
* Nearest Neighbor:
* Nearest Neighbor scaling filter
*
*/
/**
......@@ -774,3 +783,34 @@ int drm_mode_crtc_set_obj_prop(struct drm_mode_object *obj,
return ret;
}
/**
* drm_crtc_create_scaling_filter_property - create a new scaling filter
* property
*
* @crtc: drm CRTC
* @supported_filters: bitmask of supported scaling filters, must include
* BIT(DRM_SCALING_FILTER_DEFAULT).
*
* This function lets driver to enable the scaling filter property on a given
* CRTC.
*
* RETURNS:
* Zero for success or -errno
*/
int drm_crtc_create_scaling_filter_property(struct drm_crtc *crtc,
unsigned int supported_filters)
{
struct drm_property *prop =
drm_create_scaling_filter_prop(crtc->dev, supported_filters);
if (IS_ERR(prop))
return PTR_ERR(prop);
drm_object_attach_property(&crtc->base, prop,
DRM_SCALING_FILTER_DEFAULT);
crtc->scaling_filter_property = prop;
return 0;
}
EXPORT_SYMBOL(drm_crtc_create_scaling_filter_property);
......@@ -72,6 +72,9 @@ int drm_crtc_force_disable(struct drm_crtc *crtc);
struct dma_fence *drm_crtc_create_fence(struct drm_crtc *crtc);
struct drm_property *
drm_create_scaling_filter_prop(struct drm_device *dev,
unsigned int supported_filters);
/* IOCTLs */
int drm_mode_getcrtc(struct drm_device *dev,
void *data, struct drm_file *file_priv);
......
......@@ -150,11 +150,8 @@ void drm_dp_link_train_clock_recovery_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
}
EXPORT_SYMBOL(drm_dp_link_train_clock_recovery_delay);
void drm_dp_link_train_channel_eq_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
static void __drm_dp_link_train_channel_eq_delay(unsigned long rd_interval)
{
unsigned long rd_interval = dpcd[DP_TRAINING_AUX_RD_INTERVAL] &
DP_TRAINING_AUX_RD_MASK;
if (rd_interval > 4)
DRM_DEBUG_KMS("AUX interval %lu, out of range (max 4)\n",
rd_interval);
......@@ -166,8 +163,35 @@ void drm_dp_link_train_channel_eq_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
usleep_range(rd_interval, rd_interval * 2);
}
void drm_dp_link_train_channel_eq_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
{
__drm_dp_link_train_channel_eq_delay(dpcd[DP_TRAINING_AUX_RD_INTERVAL] &
DP_TRAINING_AUX_RD_MASK);
}
EXPORT_SYMBOL(drm_dp_link_train_channel_eq_delay);
void drm_dp_lttpr_link_train_clock_recovery_delay(void)
{
usleep_range(100, 200);
}
EXPORT_SYMBOL(drm_dp_lttpr_link_train_clock_recovery_delay);
static u8 dp_lttpr_phy_cap(const u8 phy_cap[DP_LTTPR_PHY_CAP_SIZE], int r)
{
return phy_cap[r - DP_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER1];
}
void drm_dp_lttpr_link_train_channel_eq_delay(const u8 phy_cap[DP_LTTPR_PHY_CAP_SIZE])
{
u8 interval = dp_lttpr_phy_cap(phy_cap,
DP_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER1) &
DP_TRAINING_AUX_RD_MASK;
__drm_dp_link_train_channel_eq_delay(interval);
}
EXPORT_SYMBOL(drm_dp_lttpr_link_train_channel_eq_delay);
u8 drm_dp_link_rate_to_bw_code(int link_rate)
{
/* Spec says link_bw = link_rate / 0.27Gbps */
......@@ -363,6 +387,59 @@ int drm_dp_dpcd_read_link_status(struct drm_dp_aux *aux,
}
EXPORT_SYMBOL(drm_dp_dpcd_read_link_status);
/**
* drm_dp_dpcd_read_phy_link_status - get the link status information for a DP PHY
* @aux: DisplayPort AUX channel
* @dp_phy: the DP PHY to get the link status for
* @link_status: buffer to return the status in
*
* Fetch the AUX DPCD registers for the DPRX or an LTTPR PHY link status. The
* layout of the returned @link_status matches the DPCD register layout of the
* DPRX PHY link status.
*
* Returns 0 if the information was read successfully or a negative error code
* on failure.
*/
int drm_dp_dpcd_read_phy_link_status(struct drm_dp_aux *aux,
enum drm_dp_phy dp_phy,
u8 link_status[DP_LINK_STATUS_SIZE])
{
int ret;
if (dp_phy == DP_PHY_DPRX) {
ret = drm_dp_dpcd_read(aux,
DP_LANE0_1_STATUS,
link_status,
DP_LINK_STATUS_SIZE);
if (ret < 0)
return ret;
WARN_ON(ret != DP_LINK_STATUS_SIZE);
return 0;
}
ret = drm_dp_dpcd_read(aux,
DP_LANE0_1_STATUS_PHY_REPEATER(dp_phy),
link_status,
DP_LINK_STATUS_SIZE - 1);
if (ret < 0)
return ret;
WARN_ON(ret != DP_LINK_STATUS_SIZE - 1);
/* Convert the LTTPR to the sink PHY link status layout */
memmove(&link_status[DP_SINK_STATUS - DP_LANE0_1_STATUS + 1],
&link_status[DP_SINK_STATUS - DP_LANE0_1_STATUS],
DP_LINK_STATUS_SIZE - (DP_SINK_STATUS - DP_LANE0_1_STATUS) - 1);
link_status[DP_SINK_STATUS - DP_LANE0_1_STATUS] = 0;
return 0;
}
EXPORT_SYMBOL(drm_dp_dpcd_read_phy_link_status);
static bool is_edid_digital_input_dp(const struct edid *edid)
{
return edid && edid->revision >= 4 &&
......@@ -1882,6 +1959,7 @@ static const struct edid_quirk edid_quirk_list[] = {
{ MFG(0x4d, 0x10), PROD_ID(0xc7, 0x14), BIT(DP_QUIRK_FORCE_DPCD_BACKLIGHT) },
{ MFG(0x4d, 0x10), PROD_ID(0xe6, 0x14), BIT(DP_QUIRK_FORCE_DPCD_BACKLIGHT) },
{ MFG(0x4c, 0x83), PROD_ID(0x47, 0x41), BIT(DP_QUIRK_FORCE_DPCD_BACKLIGHT) },
{ MFG(0x09, 0xe5), PROD_ID(0xde, 0x08), BIT(DP_QUIRK_FORCE_DPCD_BACKLIGHT) },
};
#undef MFG
......@@ -2103,6 +2181,153 @@ int drm_dp_dsc_sink_supported_input_bpcs(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_S
}
EXPORT_SYMBOL(drm_dp_dsc_sink_supported_input_bpcs);
/**
* drm_dp_read_lttpr_common_caps - read the LTTPR common capabilities
* @aux: DisplayPort AUX channel
* @caps: buffer to return the capability info in
*
* Read capabilities common to all LTTPRs.
*
* Returns 0 on success or a negative error code on failure.
*/
int drm_dp_read_lttpr_common_caps(struct drm_dp_aux *aux,
u8 caps[DP_LTTPR_COMMON_CAP_SIZE])
{
int ret;
ret = drm_dp_dpcd_read(aux,
DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV,
caps, DP_LTTPR_COMMON_CAP_SIZE);
if (ret < 0)
return ret;
WARN_ON(ret != DP_LTTPR_COMMON_CAP_SIZE);
return 0;
}
EXPORT_SYMBOL(drm_dp_read_lttpr_common_caps);
/**
* drm_dp_read_lttpr_phy_caps - read the capabilities for a given LTTPR PHY
* @aux: DisplayPort AUX channel
* @dp_phy: LTTPR PHY to read the capabilities for
* @caps: buffer to return the capability info in
*
* Read the capabilities for the given LTTPR PHY.
*
* Returns 0 on success or a negative error code on failure.
*/
int drm_dp_read_lttpr_phy_caps(struct drm_dp_aux *aux,
enum drm_dp_phy dp_phy,
u8 caps[DP_LTTPR_PHY_CAP_SIZE])
{
int ret;
ret = drm_dp_dpcd_read(aux,
DP_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER(dp_phy),
caps, DP_LTTPR_PHY_CAP_SIZE);
if (ret < 0)
return ret;
WARN_ON(ret != DP_LTTPR_PHY_CAP_SIZE);
return 0;
}
EXPORT_SYMBOL(drm_dp_read_lttpr_phy_caps);
static u8 dp_lttpr_common_cap(const u8 caps[DP_LTTPR_COMMON_CAP_SIZE], int r)
{
return caps[r - DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
}
/**
* drm_dp_lttpr_count - get the number of detected LTTPRs
* @caps: LTTPR common capabilities
*
* Get the number of detected LTTPRs from the LTTPR common capabilities info.
*
* Returns:
* -ERANGE if more than supported number (8) of LTTPRs are detected
* -EINVAL if the DP_PHY_REPEATER_CNT register contains an invalid value
* otherwise the number of detected LTTPRs
*/
int drm_dp_lttpr_count(const u8 caps[DP_LTTPR_COMMON_CAP_SIZE])
{
u8 count = dp_lttpr_common_cap(caps, DP_PHY_REPEATER_CNT);
switch (hweight8(count)) {
case 0:
return 0;
case 1:
return 8 - ilog2(count);
case 8:
return -ERANGE;
default:
return -EINVAL;
}
}
EXPORT_SYMBOL(drm_dp_lttpr_count);
/**
* drm_dp_lttpr_max_link_rate - get the maximum link rate supported by all LTTPRs
* @caps: LTTPR common capabilities
*
* Returns the maximum link rate supported by all detected LTTPRs.
*/
int drm_dp_lttpr_max_link_rate(const u8 caps[DP_LTTPR_COMMON_CAP_SIZE])
{
u8 rate = dp_lttpr_common_cap(caps, DP_MAX_LINK_RATE_PHY_REPEATER);
return drm_dp_bw_code_to_link_rate(rate);
}
EXPORT_SYMBOL(drm_dp_lttpr_max_link_rate);
/**
* drm_dp_lttpr_max_lane_count - get the maximum lane count supported by all LTTPRs
* @caps: LTTPR common capabilities
*
* Returns the maximum lane count supported by all detected LTTPRs.
*/
int drm_dp_lttpr_max_lane_count(const u8 caps[DP_LTTPR_COMMON_CAP_SIZE])
{
u8 max_lanes = dp_lttpr_common_cap(caps, DP_MAX_LANE_COUNT_PHY_REPEATER);
return max_lanes & DP_MAX_LANE_COUNT_MASK;
}
EXPORT_SYMBOL(drm_dp_lttpr_max_lane_count);
/**
* drm_dp_lttpr_voltage_swing_level_3_supported - check for LTTPR vswing3 support
* @caps: LTTPR PHY capabilities
*
* Returns true if the @caps for an LTTPR TX PHY indicate support for
* voltage swing level 3.
*/
bool
drm_dp_lttpr_voltage_swing_level_3_supported(const u8 caps[DP_LTTPR_PHY_CAP_SIZE])
{
u8 txcap = dp_lttpr_phy_cap(caps, DP_TRANSMITTER_CAPABILITY_PHY_REPEATER1);
return txcap & DP_VOLTAGE_SWING_LEVEL_3_SUPPORTED;
}
EXPORT_SYMBOL(drm_dp_lttpr_voltage_swing_level_3_supported);
/**
* drm_dp_lttpr_pre_emphasis_level_3_supported - check for LTTPR preemph3 support
* @caps: LTTPR PHY capabilities
*
* Returns true if the @caps for an LTTPR TX PHY indicate support for
* pre-emphasis level 3.
*/
bool
drm_dp_lttpr_pre_emphasis_level_3_supported(const u8 caps[DP_LTTPR_PHY_CAP_SIZE])
{
u8 txcap = dp_lttpr_phy_cap(caps, DP_TRANSMITTER_CAPABILITY_PHY_REPEATER1);
return txcap & DP_PRE_EMPHASIS_LEVEL_3_SUPPORTED;
}
EXPORT_SYMBOL(drm_dp_lttpr_pre_emphasis_level_3_supported);
/**
* drm_dp_get_phy_test_pattern() - get the requested pattern from the sink.
* @aux: DisplayPort AUX channel
......
......@@ -1231,3 +1231,76 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
return ret;
}
struct drm_property *
drm_create_scaling_filter_prop(struct drm_device *dev,
unsigned int supported_filters)
{
struct drm_property *prop;
static const struct drm_prop_enum_list props[] = {
{ DRM_SCALING_FILTER_DEFAULT, "Default" },
{ DRM_SCALING_FILTER_NEAREST_NEIGHBOR, "Nearest Neighbor" },
};
unsigned int valid_mode_mask = BIT(DRM_SCALING_FILTER_DEFAULT) |
BIT(DRM_SCALING_FILTER_NEAREST_NEIGHBOR);
int i;
if (WARN_ON((supported_filters & ~valid_mode_mask) ||
((supported_filters & BIT(DRM_SCALING_FILTER_DEFAULT)) == 0)))
return ERR_PTR(-EINVAL);
prop = drm_property_create(dev, DRM_MODE_PROP_ENUM,
"SCALING_FILTER",
hweight32(supported_filters));
if (!prop)
return ERR_PTR(-ENOMEM);
for (i = 0; i < ARRAY_SIZE(props); i++) {
int ret;
if (!(BIT(props[i].type) & supported_filters))
continue;
ret = drm_property_add_enum(prop, props[i].type,
props[i].name);
if (ret) {
drm_property_destroy(dev, prop);
return ERR_PTR(ret);
}
}
return prop;
}
/**
* drm_plane_create_scaling_filter_property - create a new scaling filter
* property
*
* @plane: drm plane
* @supported_filters: bitmask of supported scaling filters, must include
* BIT(DRM_SCALING_FILTER_DEFAULT).
*
* This function lets driver to enable the scaling filter property on a given
* plane.
*
* RETURNS:
* Zero for success or -errno
*/
int drm_plane_create_scaling_filter_property(struct drm_plane *plane,
unsigned int supported_filters)
{
struct drm_property *prop =
drm_create_scaling_filter_prop(plane->dev, supported_filters);
if (IS_ERR(prop))
return PTR_ERR(prop);
drm_object_attach_property(&plane->base, prop,
DRM_SCALING_FILTER_DEFAULT);
plane->scaling_filter_property = prop;
return 0;
}
EXPORT_SYMBOL(drm_plane_create_scaling_filter_property);
......@@ -205,6 +205,32 @@ static int dsi_send_pkt_payld(struct intel_dsi_host *host,
return 0;
}
void icl_dsi_frame_update(struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
u32 tmp, mode_flags;
enum port port;
mode_flags = crtc_state->mode_flags;
/*
* case 1 also covers dual link
* In case of dual link, frame update should be set on
* DSI_0
*/
if (mode_flags & I915_MODE_FLAG_DSI_USE_TE0)
port = PORT_A;
else if (mode_flags & I915_MODE_FLAG_DSI_USE_TE1)
port = PORT_B;
else
return;
tmp = intel_de_read(dev_priv, DSI_CMD_FRMCTL(port));
tmp |= DSI_FRAME_UPDATE_REQUEST;
intel_de_write(dev_priv, DSI_CMD_FRMCTL(port), tmp);
}
static void dsi_program_swing_and_deemphasis(struct intel_encoder *encoder)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
......@@ -429,7 +455,7 @@ static void gen11_dsi_config_phy_lanes_sequence(struct intel_encoder *encoder)
intel_de_write(dev_priv, ICL_PORT_TX_DW2_GRP(phy), tmp);
/* For EHL, TGL, set latency optimization for PCS_DW1 lanes */
if (IS_ELKHARTLAKE(dev_priv) || (INTEL_GEN(dev_priv) >= 12)) {
if (IS_JSL_EHL(dev_priv) || (INTEL_GEN(dev_priv) >= 12)) {
tmp = intel_de_read(dev_priv,
ICL_PORT_PCS_DW1_AUX(phy));
tmp &= ~LATENCY_OPTIM_MASK;
......@@ -586,7 +612,7 @@ gen11_dsi_setup_dphy_timings(struct intel_encoder *encoder,
}
}
if (IS_ELKHARTLAKE(dev_priv)) {
if (IS_JSL_EHL(dev_priv)) {
for_each_dsi_phy(phy, intel_dsi->phys) {
tmp = intel_de_read(dev_priv, ICL_DPHY_CHKN(phy));
tmp |= ICL_DPHY_CHKN_AFE_OVER_PPI_STRAP;
......@@ -1447,6 +1473,18 @@ static bool gen11_dsi_is_periodic_cmd_mode(struct intel_dsi *intel_dsi)
return (val & DSI_PERIODIC_FRAME_UPDATE_ENABLE);
}
static void gen11_dsi_get_cmd_mode_config(struct intel_dsi *intel_dsi,
struct intel_crtc_state *pipe_config)
{
if (intel_dsi->ports == (BIT(PORT_B) | BIT(PORT_A)))
pipe_config->mode_flags |= I915_MODE_FLAG_DSI_USE_TE1 |
I915_MODE_FLAG_DSI_USE_TE0;
else if (intel_dsi->ports == BIT(PORT_B))
pipe_config->mode_flags |= I915_MODE_FLAG_DSI_USE_TE1;
else
pipe_config->mode_flags |= I915_MODE_FLAG_DSI_USE_TE0;
}
static void gen11_dsi_get_config(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config)
{
......@@ -1468,6 +1506,10 @@ static void gen11_dsi_get_config(struct intel_encoder *encoder,
pipe_config->output_types |= BIT(INTEL_OUTPUT_DSI);
pipe_config->pipe_bpp = bdw_get_pipemisc_bpp(crtc);
/* Get the details on which TE should be enabled */
if (is_cmd_mode(intel_dsi))
gen11_dsi_get_cmd_mode_config(intel_dsi, pipe_config);
if (gen11_dsi_is_periodic_cmd_mode(intel_dsi))
pipe_config->mode_flags |= I915_MODE_FLAG_DSI_PERIODIC_CMD_MODE;
}
......@@ -1562,18 +1604,8 @@ static int gen11_dsi_compute_config(struct intel_encoder *encoder,
* receive TE from the slave if
* dual link is enabled
*/
if (is_cmd_mode(intel_dsi)) {
if (intel_dsi->ports == (BIT(PORT_B) | BIT(PORT_A)))
pipe_config->mode_flags |=
I915_MODE_FLAG_DSI_USE_TE1 |
I915_MODE_FLAG_DSI_USE_TE0;
else if (intel_dsi->ports == BIT(PORT_B))
pipe_config->mode_flags |=
I915_MODE_FLAG_DSI_USE_TE1;
else
pipe_config->mode_flags |=
I915_MODE_FLAG_DSI_USE_TE0;
}
if (is_cmd_mode(intel_dsi))
gen11_dsi_get_cmd_mode_config(intel_dsi, pipe_config);
return 0;
}
......@@ -1636,6 +1668,19 @@ static bool gen11_dsi_get_hw_state(struct intel_encoder *encoder,
return ret;
}
static bool gen11_dsi_initial_fastset_check(struct intel_encoder *encoder,
struct intel_crtc_state *crtc_state)
{
if (crtc_state->dsc.compression_enable) {
drm_dbg_kms(encoder->base.dev, "Forcing full modeset due to DSC being enabled\n");
crtc_state->uapi.mode_changed = true;
return false;
}
return true;
}
static void gen11_dsi_encoder_destroy(struct drm_encoder *encoder)
{
intel_encoder_destroy(encoder);
......@@ -1891,6 +1936,7 @@ void icl_dsi_init(struct drm_i915_private *dev_priv)
encoder->update_pipe = intel_panel_update_backlight;
encoder->compute_config = gen11_dsi_compute_config;
encoder->get_hw_state = gen11_dsi_get_hw_state;
encoder->initial_fastset_check = gen11_dsi_initial_fastset_check;
encoder->type = INTEL_OUTPUT_DSI;
encoder->cloneable = 0;
encoder->pipe_mask = ~0;
......
......@@ -262,6 +262,7 @@ void intel_plane_copy_uapi_to_hw_state(struct intel_plane_state *plane_state,
plane_state->hw.rotation = from_plane_state->uapi.rotation;
plane_state->hw.color_encoding = from_plane_state->uapi.color_encoding;
plane_state->hw.color_range = from_plane_state->uapi.color_range;
plane_state->hw.scaling_filter = from_plane_state->uapi.scaling_filter;
}
void intel_plane_set_invisible(struct intel_crtc_state *crtc_state,
......@@ -408,7 +409,11 @@ void intel_update_plane(struct intel_plane *plane,
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
trace_intel_update_plane(&plane->base, crtc);
plane->update_plane(plane, crtc_state, plane_state);
if (crtc_state->uapi.async_flip && plane->async_flip)
plane->async_flip(plane, crtc_state, plane_state);
else
plane->update_plane(plane, crtc_state, plane_state);
}
void intel_disable_plane(struct intel_plane *plane,
......
......@@ -425,6 +425,7 @@ parse_lfp_backlight(struct drm_i915_private *dev_priv,
const struct bdb_lfp_backlight_data *backlight_data;
const struct lfp_backlight_data_entry *entry;
int panel_type = dev_priv->vbt.panel_type;
u16 level;
backlight_data = find_section(bdb, BDB_LVDS_BACKLIGHT);
if (!backlight_data)
......@@ -459,14 +460,39 @@ parse_lfp_backlight(struct drm_i915_private *dev_priv,
dev_priv->vbt.backlight.pwm_freq_hz = entry->pwm_freq_hz;
dev_priv->vbt.backlight.active_low_pwm = entry->active_low_pwm;
dev_priv->vbt.backlight.min_brightness = entry->min_brightness;
if (bdb->version >= 234) {
u16 min_level;
bool scale;
level = backlight_data->brightness_level[panel_type].level;
min_level = backlight_data->brightness_min_level[panel_type].level;
if (bdb->version >= 236)
scale = backlight_data->brightness_precision_bits[panel_type] == 16;
else
scale = level > 255;
if (scale)
min_level = min_level / 255;
if (min_level > 255) {
drm_warn(&dev_priv->drm, "Brightness min level > 255\n");
level = 255;
}
dev_priv->vbt.backlight.min_brightness = min_level;
} else {
level = backlight_data->level[panel_type];
dev_priv->vbt.backlight.min_brightness = entry->min_brightness;
}
drm_dbg_kms(&dev_priv->drm,
"VBT backlight PWM modulation frequency %u Hz, "
"active %s, min brightness %u, level %u, controller %u\n",
dev_priv->vbt.backlight.pwm_freq_hz,
dev_priv->vbt.backlight.active_low_pwm ? "low" : "high",
dev_priv->vbt.backlight.min_brightness,
backlight_data->level[panel_type],
level,
dev_priv->vbt.backlight.controller);
}
......@@ -1602,7 +1628,9 @@ static u8 map_ddc_pin(struct drm_i915_private *dev_priv, u8 vbt_pin)
const u8 *ddc_pin_map;
int n_entries;
if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP) {
if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG1) {
return vbt_pin;
} else if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP) {
ddc_pin_map = icp_ddc_pin_map;
n_entries = ARRAY_SIZE(icp_ddc_pin_map);
} else if (HAS_PCH_CNP(dev_priv)) {
......@@ -1660,20 +1688,18 @@ static enum port dvo_port_to_port(struct drm_i915_private *dev_priv,
[PORT_I] = { DVO_PORT_HDMII, DVO_PORT_DPI, -1 },
};
/*
* Bspec lists the ports as A, B, C, D - however internally in our
* driver we keep them as PORT_A, PORT_B, PORT_D and PORT_E so the
* registers in Display Engine match the right offsets. Apply the
* mapping here to translate from VBT to internal convention.
* RKL VBT uses PHY based mapping. Combo PHYs A,B,C,D
* map to DDI A,B,TC1,TC2 respectively.
*/
static const int rkl_port_mapping[][3] = {
[PORT_A] = { DVO_PORT_HDMIA, DVO_PORT_DPA, -1 },
[PORT_B] = { DVO_PORT_HDMIB, DVO_PORT_DPB, -1 },
[PORT_C] = { -1 },
[PORT_D] = { DVO_PORT_HDMIC, DVO_PORT_DPC, -1 },
[PORT_E] = { DVO_PORT_HDMID, DVO_PORT_DPD, -1 },
[PORT_TC1] = { DVO_PORT_HDMIC, DVO_PORT_DPC, -1 },
[PORT_TC2] = { DVO_PORT_HDMID, DVO_PORT_DPD, -1 },
};
if (IS_ROCKETLAKE(dev_priv))
if (IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv))
return __dvo_port_to_port(ARRAY_SIZE(rkl_port_mapping),
ARRAY_SIZE(rkl_port_mapping[0]),
rkl_port_mapping,
......@@ -1889,7 +1915,7 @@ parse_general_definitions(struct drm_i915_private *dev_priv,
expected_size = 37;
} else if (bdb->version <= 215) {
expected_size = 38;
} else if (bdb->version <= 229) {
} else if (bdb->version <= 237) {
expected_size = 39;
} else {
expected_size = sizeof(*child);
......@@ -2638,10 +2664,16 @@ enum aux_ch intel_bios_port_aux_ch(struct drm_i915_private *dev_priv,
aux_ch = AUX_CH_B;
break;
case DP_AUX_C:
aux_ch = IS_ROCKETLAKE(dev_priv) ? AUX_CH_D : AUX_CH_C;
/*
* RKL/DG1 VBT uses PHY based mapping. Combo PHYs A,B,C,D
* map to DDI A,B,TC1,TC2 respectively.
*/
aux_ch = (IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv)) ?
AUX_CH_USBC1 : AUX_CH_C;
break;
case DP_AUX_D:
aux_ch = IS_ROCKETLAKE(dev_priv) ? AUX_CH_E : AUX_CH_D;
aux_ch = (IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv)) ?
AUX_CH_USBC2 : AUX_CH_D;
break;
case DP_AUX_E:
aux_ch = AUX_CH_E;
......
......@@ -1233,6 +1233,30 @@ static const struct intel_cdclk_vals icl_cdclk_table[] = {
{}
};
static const struct intel_cdclk_vals rkl_cdclk_table[] = {
{ .refclk = 19200, .cdclk = 172800, .divider = 4, .ratio = 36 },
{ .refclk = 19200, .cdclk = 192000, .divider = 4, .ratio = 40 },
{ .refclk = 19200, .cdclk = 307200, .divider = 4, .ratio = 64 },
{ .refclk = 19200, .cdclk = 326400, .divider = 8, .ratio = 136 },
{ .refclk = 19200, .cdclk = 556800, .divider = 4, .ratio = 116 },
{ .refclk = 19200, .cdclk = 652800, .divider = 4, .ratio = 136 },
{ .refclk = 24000, .cdclk = 180000, .divider = 4, .ratio = 30 },
{ .refclk = 24000, .cdclk = 192000, .divider = 4, .ratio = 32 },
{ .refclk = 24000, .cdclk = 312000, .divider = 4, .ratio = 52 },
{ .refclk = 24000, .cdclk = 324000, .divider = 8, .ratio = 108 },
{ .refclk = 24000, .cdclk = 552000, .divider = 4, .ratio = 92 },
{ .refclk = 24000, .cdclk = 648000, .divider = 4, .ratio = 108 },
{ .refclk = 38400, .cdclk = 172800, .divider = 4, .ratio = 18 },
{ .refclk = 38400, .cdclk = 192000, .divider = 4, .ratio = 20 },
{ .refclk = 38400, .cdclk = 307200, .divider = 4, .ratio = 32 },
{ .refclk = 38400, .cdclk = 326400, .divider = 8, .ratio = 68 },
{ .refclk = 38400, .cdclk = 556800, .divider = 4, .ratio = 58 },
{ .refclk = 38400, .cdclk = 652800, .divider = 4, .ratio = 68 },
{}
};
static int bxt_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk)
{
const struct intel_cdclk_vals *table = dev_priv->cdclk.table;
......@@ -2588,7 +2612,7 @@ static int intel_compute_max_dotclk(struct drm_i915_private *dev_priv)
*/
void intel_update_max_cdclk(struct drm_i915_private *dev_priv)
{
if (IS_ELKHARTLAKE(dev_priv)) {
if (IS_JSL_EHL(dev_priv)) {
if (dev_priv->cdclk.hw.ref == 24000)
dev_priv->max_cdclk_freq = 552000;
else
......@@ -2680,6 +2704,18 @@ void intel_update_cdclk(struct drm_i915_private *dev_priv)
DIV_ROUND_UP(dev_priv->cdclk.hw.cdclk, 1000));
}
static int dg1_rawclk(struct drm_i915_private *dev_priv)
{
/*
* DG1 always uses a 38.4 MHz rawclk. The bspec tells us
* "Program Numerator=2, Denominator=4, Divider=37 decimal."
*/
I915_WRITE(PCH_RAWCLK_FREQ,
CNP_RAWCLK_DEN(4) | CNP_RAWCLK_DIV(37) | ICP_RAWCLK_NUM(2));
return 38400;
}
static int cnp_rawclk(struct drm_i915_private *dev_priv)
{
u32 rawclk;
......@@ -2788,7 +2824,9 @@ u32 intel_read_rawclk(struct drm_i915_private *dev_priv)
{
u32 freq;
if (INTEL_PCH_TYPE(dev_priv) >= PCH_CNP)
if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG1)
freq = dg1_rawclk(dev_priv);
else if (INTEL_PCH_TYPE(dev_priv) >= PCH_CNP)
freq = cnp_rawclk(dev_priv);
else if (HAS_PCH_SPLIT(dev_priv))
freq = pch_rawclk(dev_priv);
......@@ -2809,13 +2847,19 @@ u32 intel_read_rawclk(struct drm_i915_private *dev_priv)
*/
void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv)
{
if (INTEL_GEN(dev_priv) >= 12) {
if (IS_ROCKETLAKE(dev_priv)) {
dev_priv->display.set_cdclk = bxt_set_cdclk;
dev_priv->display.bw_calc_min_cdclk = skl_bw_calc_min_cdclk;
dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk;
dev_priv->display.calc_voltage_level = tgl_calc_voltage_level;
dev_priv->cdclk.table = rkl_cdclk_table;
} else if (INTEL_GEN(dev_priv) >= 12) {
dev_priv->display.set_cdclk = bxt_set_cdclk;
dev_priv->display.bw_calc_min_cdclk = skl_bw_calc_min_cdclk;
dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk;
dev_priv->display.calc_voltage_level = tgl_calc_voltage_level;
dev_priv->cdclk.table = icl_cdclk_table;
} else if (IS_ELKHARTLAKE(dev_priv)) {
} else if (IS_JSL_EHL(dev_priv)) {
dev_priv->display.set_cdclk = bxt_set_cdclk;
dev_priv->display.bw_calc_min_cdclk = skl_bw_calc_min_cdclk;
dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk;
......
......@@ -638,10 +638,17 @@ static void ilk_load_luts(const struct intel_crtc_state *crtc_state)
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
switch (crtc_state->gamma_mode) {
case GAMMA_MODE_MODE_8BIT:
ilk_load_lut_8(crtc, gamma_lut);
else
break;
case GAMMA_MODE_MODE_10BIT:
ilk_load_lut_10(crtc, gamma_lut);
break;
default:
MISSING_CASE(crtc_state->gamma_mode);
break;
}
}
static int ivb_lut_10_size(u32 prec_index)
......@@ -745,21 +752,27 @@ static void ivb_load_luts(const struct intel_crtc_state *crtc_state)
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
const struct drm_property_blob *blob = gamma_lut ?: degamma_lut;
if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) {
ilk_load_lut_8(crtc, gamma_lut);
} else if (crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT) {
switch (crtc_state->gamma_mode) {
case GAMMA_MODE_MODE_8BIT:
ilk_load_lut_8(crtc, blob);
break;
case GAMMA_MODE_MODE_SPLIT:
ivb_load_lut_10(crtc, degamma_lut, PAL_PREC_SPLIT_MODE |
PAL_PREC_INDEX_VALUE(0));
ivb_load_lut_ext_max(crtc_state);
ivb_load_lut_10(crtc, gamma_lut, PAL_PREC_SPLIT_MODE |
PAL_PREC_INDEX_VALUE(512));
} else {
const struct drm_property_blob *blob = gamma_lut ?: degamma_lut;
break;
case GAMMA_MODE_MODE_10BIT:
ivb_load_lut_10(crtc, blob,
PAL_PREC_INDEX_VALUE(0));
ivb_load_lut_ext_max(crtc_state);
break;
default:
MISSING_CASE(crtc_state->gamma_mode);
break;
}
}
......@@ -768,21 +781,28 @@ static void bdw_load_luts(const struct intel_crtc_state *crtc_state)
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
const struct drm_property_blob *blob = gamma_lut ?: degamma_lut;
if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) {
ilk_load_lut_8(crtc, gamma_lut);
} else if (crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT) {
switch (crtc_state->gamma_mode) {
case GAMMA_MODE_MODE_8BIT:
ilk_load_lut_8(crtc, blob);
break;
case GAMMA_MODE_MODE_SPLIT:
bdw_load_lut_10(crtc, degamma_lut, PAL_PREC_SPLIT_MODE |
PAL_PREC_INDEX_VALUE(0));
ivb_load_lut_ext_max(crtc_state);
bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_SPLIT_MODE |
PAL_PREC_INDEX_VALUE(512));
} else {
const struct drm_property_blob *blob = gamma_lut ?: degamma_lut;
break;
case GAMMA_MODE_MODE_10BIT:
bdw_load_lut_10(crtc, blob,
PAL_PREC_INDEX_VALUE(0));
ivb_load_lut_ext_max(crtc_state);
break;
default:
MISSING_CASE(crtc_state->gamma_mode);
break;
}
}
......@@ -818,12 +838,14 @@ static void glk_load_degamma_lut(const struct intel_crtc_state *crtc_state)
* as compared to just 16 to achieve this.
*/
intel_de_write(dev_priv, PRE_CSC_GAMC_DATA(pipe),
lut[i].green);
lut[i].green);
}
/* Clamp values > 1.0. */
while (i++ < 35)
intel_de_write(dev_priv, PRE_CSC_GAMC_DATA(pipe), 1 << 16);
intel_de_write(dev_priv, PRE_CSC_GAMC_INDEX(pipe), 0);
}
static void glk_load_degamma_lut_linear(const struct intel_crtc_state *crtc_state)
......@@ -851,6 +873,8 @@ static void glk_load_degamma_lut_linear(const struct intel_crtc_state *crtc_stat
/* Clamp values > 1.0. */
while (i++ < 35)
intel_de_write(dev_priv, PRE_CSC_GAMC_DATA(pipe), 1 << 16);
intel_de_write(dev_priv, PRE_CSC_GAMC_INDEX(pipe), 0);
}
static void glk_load_luts(const struct intel_crtc_state *crtc_state)
......@@ -871,11 +895,17 @@ static void glk_load_luts(const struct intel_crtc_state *crtc_state)
else
glk_load_degamma_lut_linear(crtc_state);
if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) {
switch (crtc_state->gamma_mode) {
case GAMMA_MODE_MODE_8BIT:
ilk_load_lut_8(crtc, gamma_lut);
} else {
break;
case GAMMA_MODE_MODE_10BIT:
bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0));
ivb_load_lut_ext_max(crtc_state);
break;
default:
MISSING_CASE(crtc_state->gamma_mode);
break;
}
}
......@@ -1007,9 +1037,13 @@ static void icl_load_luts(const struct intel_crtc_state *crtc_state)
icl_program_gamma_superfine_segment(crtc_state);
icl_program_gamma_multi_segment(crtc_state);
break;
default:
case GAMMA_MODE_MODE_10BIT:
bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0));
ivb_load_lut_ext_max(crtc_state);
break;
default:
MISSING_CASE(crtc_state->gamma_mode);
break;
}
intel_dsb_commit(crtc_state);
......@@ -1026,13 +1060,6 @@ static u32 chv_cgm_degamma_udw(const struct drm_color_lut *color)
return drm_color_lut_extract(color->red, 14);
}
static void chv_cgm_gamma_pack(struct drm_color_lut *entry, u32 ldw, u32 udw)
{
entry->green = intel_color_lut_pack(REG_FIELD_GET(CGM_PIPE_GAMMA_GREEN_MASK, ldw), 10);
entry->blue = intel_color_lut_pack(REG_FIELD_GET(CGM_PIPE_GAMMA_BLUE_MASK, ldw), 10);
entry->red = intel_color_lut_pack(REG_FIELD_GET(CGM_PIPE_GAMMA_RED_MASK, udw), 10);
}
static void chv_load_cgm_degamma(struct intel_crtc *crtc,
const struct drm_property_blob *blob)
{
......@@ -1060,6 +1087,13 @@ static u32 chv_cgm_gamma_udw(const struct drm_color_lut *color)
return drm_color_lut_extract(color->red, 10);
}
static void chv_cgm_gamma_pack(struct drm_color_lut *entry, u32 ldw, u32 udw)
{
entry->green = intel_color_lut_pack(REG_FIELD_GET(CGM_PIPE_GAMMA_GREEN_MASK, ldw), 10);
entry->blue = intel_color_lut_pack(REG_FIELD_GET(CGM_PIPE_GAMMA_BLUE_MASK, ldw), 10);
entry->red = intel_color_lut_pack(REG_FIELD_GET(CGM_PIPE_GAMMA_RED_MASK, udw), 10);
}
static void chv_load_cgm_gamma(struct intel_crtc *crtc,
const struct drm_property_blob *blob)
{
......@@ -1733,7 +1767,7 @@ bool intel_color_lut_equal(struct drm_property_blob *blob1,
break;
default:
MISSING_CASE(gamma_mode);
return false;
return false;
}
return true;
......@@ -1913,23 +1947,34 @@ static void ilk_read_luts(struct intel_crtc_state *crtc_state)
if ((crtc_state->csc_mode & CSC_POSITION_BEFORE_GAMMA) == 0)
return;
if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
switch (crtc_state->gamma_mode) {
case GAMMA_MODE_MODE_8BIT:
crtc_state->hw.gamma_lut = ilk_read_lut_8(crtc);
else
break;
case GAMMA_MODE_MODE_10BIT:
crtc_state->hw.gamma_lut = ilk_read_lut_10(crtc);
break;
default:
MISSING_CASE(crtc_state->gamma_mode);
break;
}
}
static struct drm_property_blob *glk_read_lut_10(struct intel_crtc *crtc,
/* On BDW+ the index auto increment mode actually works */
static struct drm_property_blob *bdw_read_lut_10(struct intel_crtc *crtc,
u32 prec_index)
{
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
int i, hw_lut_size = ivb_lut_10_size(prec_index);
int lut_size = INTEL_INFO(dev_priv)->color.gamma_lut_size;
enum pipe pipe = crtc->pipe;
struct drm_property_blob *blob;
struct drm_color_lut *lut;
drm_WARN_ON(&dev_priv->drm, lut_size != hw_lut_size);
blob = drm_property_create_blob(&dev_priv->drm,
sizeof(struct drm_color_lut) * hw_lut_size,
sizeof(struct drm_color_lut) * lut_size,
NULL);
if (IS_ERR(blob))
return NULL;
......@@ -1939,7 +1984,7 @@ static struct drm_property_blob *glk_read_lut_10(struct intel_crtc *crtc,
intel_de_write(dev_priv, PREC_PAL_INDEX(pipe),
prec_index | PAL_PREC_AUTO_INCREMENT);
for (i = 0; i < hw_lut_size; i++) {
for (i = 0; i < lut_size; i++) {
u32 val = intel_de_read(dev_priv, PREC_PAL_DATA(pipe));
ilk_lut_10_pack(&lut[i], val);
......@@ -1957,10 +2002,17 @@ static void glk_read_luts(struct intel_crtc_state *crtc_state)
if (!crtc_state->gamma_enable)
return;
if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
switch (crtc_state->gamma_mode) {
case GAMMA_MODE_MODE_8BIT:
crtc_state->hw.gamma_lut = ilk_read_lut_8(crtc);
else
crtc_state->hw.gamma_lut = glk_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
break;
case GAMMA_MODE_MODE_10BIT:
crtc_state->hw.gamma_lut = bdw_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
break;
default:
MISSING_CASE(crtc_state->gamma_mode);
break;
}
}
static struct drm_property_blob *
......@@ -2012,11 +2064,15 @@ static void icl_read_luts(struct intel_crtc_state *crtc_state)
case GAMMA_MODE_MODE_8BIT:
crtc_state->hw.gamma_lut = ilk_read_lut_8(crtc);
break;
case GAMMA_MODE_MODE_10BIT:
crtc_state->hw.gamma_lut = bdw_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
break;
case GAMMA_MODE_MODE_12BIT_MULTI_SEGMENTED:
crtc_state->hw.gamma_lut = icl_read_lut_multi_segment(crtc);
break;
default:
crtc_state->hw.gamma_lut = glk_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
MISSING_CASE(crtc_state->gamma_mode);
break;
}
}
......
......@@ -188,8 +188,9 @@ static bool has_phy_misc(struct drm_i915_private *i915, enum phy phy)
* PHY-B and may not even have instances of the register for the
* other combo PHY's.
*/
if (IS_ELKHARTLAKE(i915) ||
IS_ROCKETLAKE(i915))
if (IS_JSL_EHL(i915) ||
IS_ROCKETLAKE(i915) ||
IS_DG1(i915))
return phy < PHY_C;
return true;
......@@ -242,14 +243,14 @@ static bool phy_is_master(struct drm_i915_private *dev_priv, enum phy phy)
*
* ICL,TGL:
* A(master) -> B(slave), C(slave)
* RKL:
* RKL,DG1:
* A(master) -> B(slave)
* C(master) -> D(slave)
*
* We must set the IREFGEN bit for any PHY acting as a master
* to another PHY.
*/
if (IS_ROCKETLAKE(dev_priv) && phy == PHY_C)
if ((IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv)) && phy == PHY_C)
return true;
return phy == PHY_A;
......@@ -282,7 +283,7 @@ static bool icl_combo_phy_verify_state(struct drm_i915_private *dev_priv,
ret &= check_phy_reg(dev_priv, phy, ICL_PORT_COMP_DW8(phy),
IREFGEN, IREFGEN);
if (IS_ELKHARTLAKE(dev_priv)) {
if (IS_JSL_EHL(dev_priv)) {
if (ehl_vbt_ddi_d_present(dev_priv))
expected_val = ICL_PHY_MISC_MUX_DDID;
......@@ -376,7 +377,7 @@ static void icl_combo_phys_init(struct drm_i915_private *dev_priv)
* "internal" child devices.
*/
val = intel_de_read(dev_priv, ICL_PHY_MISC(phy));
if (IS_ELKHARTLAKE(dev_priv) && phy == PHY_A) {
if (IS_JSL_EHL(dev_priv) && phy == PHY_A) {
val &= ~ICL_PHY_MISC_MUX_DDID;
if (ehl_vbt_ddi_d_present(dev_priv))
......
......@@ -40,13 +40,16 @@
#define GEN12_CSR_MAX_FW_SIZE ICL_CSR_MAX_FW_SIZE
#define DG1_CSR_PATH "i915/dg1_dmc_ver2_02.bin"
#define DG1_CSR_VERSION_REQUIRED CSR_VERSION(2, 2)
MODULE_FIRMWARE(DG1_CSR_PATH);
#define RKL_CSR_PATH "i915/rkl_dmc_ver2_02.bin"
#define RKL_CSR_VERSION_REQUIRED CSR_VERSION(2, 2)
MODULE_FIRMWARE(RKL_CSR_PATH);
#define TGL_CSR_PATH "i915/tgl_dmc_ver2_08.bin"
#define TGL_CSR_VERSION_REQUIRED CSR_VERSION(2, 8)
#define TGL_CSR_MAX_FW_SIZE 0x6000
MODULE_FIRMWARE(TGL_CSR_PATH);
#define ICL_CSR_PATH "i915/icl_dmc_ver1_09.bin"
......@@ -686,14 +689,17 @@ void intel_csr_ucode_init(struct drm_i915_private *dev_priv)
*/
intel_csr_runtime_pm_get(dev_priv);
if (IS_ROCKETLAKE(dev_priv)) {
if (IS_DG1(dev_priv)) {
csr->fw_path = DG1_CSR_PATH;
csr->required_version = DG1_CSR_VERSION_REQUIRED;
csr->max_fw_size = GEN12_CSR_MAX_FW_SIZE;
} else if (IS_ROCKETLAKE(dev_priv)) {
csr->fw_path = RKL_CSR_PATH;
csr->required_version = RKL_CSR_VERSION_REQUIRED;
csr->max_fw_size = GEN12_CSR_MAX_FW_SIZE;
} else if (INTEL_GEN(dev_priv) >= 12) {
csr->fw_path = TGL_CSR_PATH;
csr->required_version = TGL_CSR_VERSION_REQUIRED;
/* Allow to load fw via parameter using the last known size */
csr->max_fw_size = GEN12_CSR_MAX_FW_SIZE;
} else if (IS_GEN(dev_priv, 11)) {
csr->fw_path = ICL_CSR_PATH;
......
This diff is collapsed.
......@@ -7,6 +7,7 @@
#define __INTEL_DDI_H__
#include "intel_display.h"
#include "i915_reg.h"
struct drm_connector_state;
struct drm_i915_private;
......@@ -18,6 +19,10 @@ struct intel_dpll_hw_state;
struct intel_encoder;
enum transcoder;
i915_reg_t dp_tp_ctl_reg(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state);
i915_reg_t dp_tp_status_reg(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state);
void intel_ddi_fdi_post_disable(struct intel_atomic_state *state,
struct intel_encoder *intel_encoder,
const struct intel_crtc_state *old_crtc_state,
......@@ -41,8 +46,10 @@ void intel_ddi_set_vc_payload_alloc(const struct intel_crtc_state *crtc_state,
bool state);
void intel_ddi_compute_min_voltage_level(struct drm_i915_private *dev_priv,
struct intel_crtc_state *crtc_state);
u32 bxt_signal_levels(struct intel_dp *intel_dp);
u32 ddi_signal_levels(struct intel_dp *intel_dp);
u32 bxt_signal_levels(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state);
u32 ddi_signal_levels(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state);
int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder,
enum transcoder cpu_transcoder,
bool enable);
......
......@@ -28,6 +28,7 @@
#include <drm/drm_util.h>
enum link_m_n_set;
enum drm_scaling_filter;
struct dpll;
struct drm_connector;
struct drm_device;
......@@ -207,6 +208,14 @@ enum port {
PORT_H,
PORT_I,
/* tgl+ */
PORT_TC1 = PORT_D,
PORT_TC2,
PORT_TC3,
PORT_TC4,
PORT_TC5,
PORT_TC6,
I915_MAX_PORTS
};
......@@ -243,14 +252,14 @@ static inline const char *port_identifier(enum port port)
}
enum tc_port {
PORT_TC_NONE = -1,
TC_PORT_NONE = -1,
PORT_TC1 = 0,
PORT_TC2,
PORT_TC3,
PORT_TC4,
PORT_TC5,
PORT_TC6,
TC_PORT_1 = 0,
TC_PORT_2,
TC_PORT_3,
TC_PORT_4,
TC_PORT_5,
TC_PORT_6,
I915_MAX_TC_PORTS
};
......@@ -282,6 +291,14 @@ enum aux_ch {
AUX_CH_G,
AUX_CH_H,
AUX_CH_I,
/* tgl+ */
AUX_CH_USBC1 = AUX_CH_D,
AUX_CH_USBC2,
AUX_CH_USBC3,
AUX_CH_USBC4,
AUX_CH_USBC5,
AUX_CH_USBC6,
};
#define aux_ch_name(a) ((a) + 'A')
......@@ -599,6 +616,9 @@ void intel_crtc_arm_fifo_underrun(struct intel_crtc *crtc,
u16 skl_scaler_calc_phase(int sub, int scale, bool chroma_center);
void skl_scaler_disable(const struct intel_crtc_state *old_crtc_state);
u32 skl_scaler_get_filter_select(enum drm_scaling_filter filter, int set);
void skl_scaler_setup_filter(struct drm_i915_private *dev_priv, enum pipe pipe,
int id, int set, enum drm_scaling_filter filter);
void ilk_pfit_disable(const struct intel_crtc_state *old_crtc_state);
u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state);
......
......@@ -518,8 +518,13 @@ static int i915_dmc_info(struct seq_file *m, void *unused)
CSR_VERSION_MINOR(csr->version));
if (INTEL_GEN(dev_priv) >= 12) {
dc5_reg = TGL_DMC_DEBUG_DC5_COUNT;
dc6_reg = TGL_DMC_DEBUG_DC6_COUNT;
if (IS_DGFX(dev_priv)) {
dc5_reg = DG1_DMC_DEBUG_DC5_COUNT;
} else {
dc5_reg = TGL_DMC_DEBUG_DC5_COUNT;
dc6_reg = TGL_DMC_DEBUG_DC6_COUNT;
}
/*
* NOTE: DMC_DEBUG3 is a general purpose reg.
* According to B.Specs:49196 DMC f/w reuses DC5/6 counter
......
......@@ -1424,6 +1424,7 @@ static void vlv_display_power_well_init(struct drm_i915_private *dev_priv)
return;
intel_hpd_init(dev_priv);
intel_hpd_poll_disable(dev_priv);
/* Re-enable the ADPA, if we have one */
for_each_intel_encoder(&dev_priv->drm, encoder) {
......@@ -1449,7 +1450,7 @@ static void vlv_display_power_well_deinit(struct drm_i915_private *dev_priv)
/* Prevent us from re-enabling polling on accident in late suspend */
if (!dev_priv->drm.dev->power.is_suspended)
intel_hpd_poll_init(dev_priv);
intel_hpd_poll_enable(dev_priv);
}
static void vlv_display_power_well_enable(struct drm_i915_private *dev_priv,
......@@ -3650,7 +3651,7 @@ static const struct i915_power_well_desc cnl_power_wells[] = {
.name = "DDI F IO power well",
.domains = CNL_DISPLAY_DDI_F_IO_POWER_DOMAINS,
.ops = &hsw_power_well_ops,
.id = DISP_PW_ID_NONE,
.id = CNL_DISP_PW_DDI_F_IO,
{
.hsw.regs = &hsw_power_well_regs,
.hsw.idx = CNL_PW_CTL_IDX_DDI_F,
......@@ -3660,7 +3661,7 @@ static const struct i915_power_well_desc cnl_power_wells[] = {
.name = "AUX F",
.domains = CNL_DISPLAY_AUX_F_POWER_DOMAINS,
.ops = &hsw_power_well_ops,
.id = DISP_PW_ID_NONE,
.id = CNL_DISP_PW_DDI_F_AUX,
{
.hsw.regs = &hsw_power_well_regs,
.hsw.idx = CNL_PW_CTL_IDX_AUX_F,
......@@ -4150,7 +4151,7 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
.name = "TC cold off",
.domains = TGL_TC_COLD_OFF_POWER_DOMAINS,
.ops = &tgl_tc_cold_off_ops,
.id = DISP_PW_ID_NONE,
.id = TGL_DISP_PW_TC_COLD_OFF,
},
{
.name = "AUX A",
......@@ -4492,7 +4493,10 @@ static u32 get_allowed_dc_mask(const struct drm_i915_private *dev_priv,
int max_dc;
if (INTEL_GEN(dev_priv) >= 12) {
max_dc = 4;
if (IS_DG1(dev_priv))
max_dc = 3;
else
max_dc = 4;
/*
* DC9 has a separate HW flow from the rest of the DC states,
* not depending on the DMC firmware. It's needed by system
......@@ -4554,13 +4558,18 @@ static u32 get_allowed_dc_mask(const struct drm_i915_private *dev_priv,
static int
__set_power_wells(struct i915_power_domains *power_domains,
const struct i915_power_well_desc *power_well_descs,
int power_well_count)
int power_well_descs_sz, u64 skip_mask)
{
struct drm_i915_private *i915 = container_of(power_domains,
struct drm_i915_private,
power_domains);
u64 power_well_ids = 0;
int i;
int power_well_count = 0;
int i, plt_idx = 0;
for (i = 0; i < power_well_descs_sz; i++)
if (!(BIT_ULL(power_well_descs[i].id) & skip_mask))
power_well_count++;
power_domains->power_well_count = power_well_count;
power_domains->power_wells =
......@@ -4570,10 +4579,14 @@ __set_power_wells(struct i915_power_domains *power_domains,
if (!power_domains->power_wells)
return -ENOMEM;
for (i = 0; i < power_well_count; i++) {
for (i = 0; i < power_well_descs_sz; i++) {
enum i915_power_well_id id = power_well_descs[i].id;
power_domains->power_wells[i].desc = &power_well_descs[i];
if (BIT_ULL(id) & skip_mask)
continue;
power_domains->power_wells[plt_idx++].desc =
&power_well_descs[i];
if (id == DISP_PW_ID_NONE)
continue;
......@@ -4586,9 +4599,12 @@ __set_power_wells(struct i915_power_domains *power_domains,
return 0;
}
#define set_power_wells(power_domains, __power_well_descs) \
#define set_power_wells_mask(power_domains, __power_well_descs, skip_mask) \
__set_power_wells(power_domains, __power_well_descs, \
ARRAY_SIZE(__power_well_descs))
ARRAY_SIZE(__power_well_descs), skip_mask)
#define set_power_wells(power_domains, __power_well_descs) \
set_power_wells_mask(power_domains, __power_well_descs, 0)
/**
* intel_power_domains_init - initializes the power domain structures
......@@ -4622,23 +4638,21 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv)
* The enabling order will be from lower to higher indexed wells,
* the disabling order is reversed.
*/
if (IS_ROCKETLAKE(dev_priv)) {
if (IS_DG1(dev_priv)) {
err = set_power_wells_mask(power_domains, tgl_power_wells,
BIT_ULL(TGL_DISP_PW_TC_COLD_OFF));
} else if (IS_ROCKETLAKE(dev_priv)) {
err = set_power_wells(power_domains, rkl_power_wells);
} else if (IS_GEN(dev_priv, 12)) {
err = set_power_wells(power_domains, tgl_power_wells);
} else if (IS_GEN(dev_priv, 11)) {
err = set_power_wells(power_domains, icl_power_wells);
} else if (IS_CANNONLAKE(dev_priv)) {
} else if (IS_CNL_WITH_PORT_F(dev_priv)) {
err = set_power_wells(power_domains, cnl_power_wells);
/*
* DDI and Aux IO are getting enabled for all ports
* regardless the presence or use. So, in order to avoid
* timeouts, lets remove them from the list
* for the SKUs without port F.
*/
if (!IS_CNL_WITH_PORT_F(dev_priv))
power_domains->power_well_count -= 2;
} else if (IS_CANNONLAKE(dev_priv)) {
err = set_power_wells_mask(power_domains, cnl_power_wells,
BIT_ULL(CNL_DISP_PW_DDI_F_IO) |
BIT_ULL(CNL_DISP_PW_DDI_F_AUX));
} else if (IS_GEMINILAKE(dev_priv)) {
err = set_power_wells(power_domains, glk_power_wells);
} else if (IS_BROXTON(dev_priv)) {
......@@ -4758,6 +4772,17 @@ static void gen9_dbuf_disable(struct drm_i915_private *dev_priv)
gen9_dbuf_slices_update(dev_priv, 0);
}
static void gen12_dbuf_slices_config(struct drm_i915_private *dev_priv)
{
const int num_slices = INTEL_INFO(dev_priv)->num_supported_dbuf_slices;
enum dbuf_slice slice;
for (slice = DBUF_S1; slice < (DBUF_S1 + num_slices); slice++)
intel_de_rmw(dev_priv, DBUF_CTL_S(slice),
DBUF_TRACKER_STATE_SERVICE_MASK,
DBUF_TRACKER_STATE_SERVICE(8));
}
static void icl_mbus_init(struct drm_i915_private *dev_priv)
{
unsigned long abox_regs = INTEL_INFO(dev_priv)->abox_mask;
......@@ -5263,8 +5288,9 @@ static void tgl_bw_buddy_init(struct drm_i915_private *dev_priv)
unsigned long abox_mask = INTEL_INFO(dev_priv)->abox_mask;
int config, i;
if (IS_TGL_DISP_REVID(dev_priv, TGL_REVID_A0, TGL_REVID_B0))
/* Wa_1409767108: tgl */
if (IS_DG1_REVID(dev_priv, DG1_REVID_A0, DG1_REVID_A0) ||
IS_TGL_DISP_REVID(dev_priv, TGL_REVID_A0, TGL_REVID_B0))
/* Wa_1409767108:tgl,dg1 */
table = wa_1409767108_buddy_page_masks;
else
table = tgl_buddy_page_masks;
......@@ -5326,6 +5352,9 @@ static void icl_display_core_init(struct drm_i915_private *dev_priv,
/* 4. Enable CDCLK. */
intel_cdclk_init_hw(dev_priv);
if (INTEL_GEN(dev_priv) >= 12)
gen12_dbuf_slices_config(dev_priv);
/* 5. Enable DBUF. */
gen9_dbuf_enable(dev_priv);
......
......@@ -101,8 +101,11 @@ enum i915_power_well_id {
SKL_DISP_PW_MISC_IO,
SKL_DISP_PW_1,
SKL_DISP_PW_2,
CNL_DISP_PW_DDI_F_IO,
CNL_DISP_PW_DDI_F_AUX,
ICL_DISP_PW_3,
SKL_DISP_DC_OFF,
TGL_DISP_PW_TC_COLD_OFF,
};
#define POWER_DOMAIN_PIPE(pipe) ((pipe) + POWER_DOMAIN_PIPE_A)
......
......@@ -187,6 +187,21 @@ struct intel_encoder {
* be set correctly before calling this function. */
void (*get_config)(struct intel_encoder *,
struct intel_crtc_state *pipe_config);
/*
* Optional hook called during init/resume to sync any state
* stored in the encoder (eg. DP link parameters) wrt. the HW state.
*/
void (*sync_state)(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state);
/*
* Optional hook, returning true if this encoder allows a fastset
* during the initial commit, false otherwise.
*/
bool (*initial_fastset_check)(struct intel_encoder *encoder,
struct intel_crtc_state *crtc_state);
/*
* Acquires the power domains needed for an active encoder during
* hardware state readout.
......@@ -199,6 +214,11 @@ struct intel_encoder {
* device interrupts are disabled.
*/
void (*suspend)(struct intel_encoder *);
/*
* Called during system reboot/shutdown after all the
* encoders have been disabled and suspended.
*/
void (*shutdown)(struct intel_encoder *encoder);
enum hpd_pin hpd_pin;
enum intel_display_power_domain power_domain;
/* for communication with audio component; protected by av_mutex */
......@@ -515,6 +535,7 @@ struct intel_plane_state {
unsigned int rotation;
enum drm_color_encoding color_encoding;
enum drm_color_range color_range;
enum drm_scaling_filter scaling_filter;
} hw;
struct i915_ggtt_view view;
......@@ -805,6 +826,7 @@ struct intel_crtc_state {
bool active, enable;
struct drm_property_blob *degamma_lut, *gamma_lut, *ctm;
struct drm_display_mode mode, adjusted_mode;
enum drm_scaling_filter scaling_filter;
} hw;
/**
......@@ -1035,9 +1057,6 @@ struct intel_crtc_state {
/* Output format RGB/YCBCR etc */
enum intel_output_format output_format;
/* Output down scaling is done in LSPCON device */
bool lspcon_downsampling;
/* enable pipe gamma? */
bool gamma_enable;
......@@ -1183,6 +1202,9 @@ struct intel_plane {
struct intel_plane_state *plane_state);
int (*min_cdclk)(const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state);
void (*async_flip)(struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state);
};
struct intel_watermark_params {
......@@ -1270,7 +1292,6 @@ struct intel_dp {
int link_rate;
u8 lane_count;
u8 sink_count;
bool link_mst;
bool link_trained;
bool has_hdmi_sink;
bool has_audio;
......@@ -1280,6 +1301,8 @@ struct intel_dp {
u8 downstream_ports[DP_MAX_DOWNSTREAM_PORTS];
u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE];
u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE];
u8 lttpr_common_caps[DP_LTTPR_COMMON_CAP_SIZE];
u8 lttpr_phy_caps[DP_MAX_LTTPR_COUNT][DP_LTTPR_PHY_CAP_SIZE];
u8 fec_capable;
/* source rates */
int num_source_rates;
......@@ -1312,8 +1335,6 @@ struct intel_dp {
unsigned long last_backlight_off;
ktime_t panel_power_off_time;
struct notifier_block edp_notifier;
/*
* Pipe whose power sequencer is currently locked into
* this port. Only relevant on VLV/CHV.
......@@ -1336,14 +1357,6 @@ struct intel_dp {
bool is_mst;
int active_mst_links;
/*
* DP_TP_* registers may be either on port or transcoder register space.
*/
struct {
i915_reg_t dp_tp_ctl;
i915_reg_t dp_tp_status;
} regs;
/* connector directly attached - won't be use for modeset in mst world */
struct intel_connector *attached_connector;
......@@ -1363,13 +1376,19 @@ struct intel_dp {
i915_reg_t (*aux_ch_data_reg)(struct intel_dp *dp, int index);
/* This is called before a link training is starterd */
void (*prepare_link_retrain)(struct intel_dp *intel_dp);
void (*set_link_train)(struct intel_dp *intel_dp, u8 dp_train_pat);
void (*set_idle_link_train)(struct intel_dp *intel_dp);
void (*set_signal_levels)(struct intel_dp *intel_dp);
void (*prepare_link_retrain)(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state);
void (*set_link_train)(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state,
u8 dp_train_pat);
void (*set_idle_link_train)(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state);
void (*set_signal_levels)(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state);
u8 (*preemph_max)(struct intel_dp *intel_dp);
u8 (*voltage_max)(struct intel_dp *intel_dp);
u8 (*voltage_max)(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state);
/* Displayport compliance testing */
struct intel_dp_compliance compliance;
......
This diff is collapsed.
......@@ -10,6 +10,7 @@
#include "i915_reg.h"
enum intel_output_format;
enum pipe;
enum port;
struct drm_connector_state;
......@@ -35,7 +36,7 @@ void intel_dp_adjust_compliance_config(struct intel_dp *intel_dp,
struct link_config_limits *limits);
bool intel_dp_limited_color_range(const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state);
int intel_dp_min_bpp(const struct intel_crtc_state *crtc_state);
int intel_dp_min_bpp(enum intel_output_format output_format);
bool intel_dp_port_enabled(struct drm_i915_private *dev_priv,
i915_reg_t dp_reg, enum port port,
enum pipe *pipe);
......@@ -44,19 +45,19 @@ bool intel_dp_init(struct drm_i915_private *dev_priv, i915_reg_t output_reg,
bool intel_dp_init_connector(struct intel_digital_port *dig_port,
struct intel_connector *intel_connector);
void intel_dp_set_link_params(struct intel_dp *intel_dp,
int link_rate, u8 lane_count,
bool link_mst);
int link_rate, int lane_count);
int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
int link_rate, u8 lane_count);
int intel_dp_retrain_link(struct intel_encoder *encoder,
struct drm_modeset_acquire_ctx *ctx);
void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode);
void intel_dp_set_power(struct intel_dp *intel_dp, u8 mode);
void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp);
void intel_dp_sink_set_decompression_state(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state,
bool enable);
void intel_dp_encoder_reset(struct drm_encoder *encoder);
void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder);
void intel_dp_encoder_shutdown(struct intel_encoder *intel_encoder);
void intel_dp_encoder_flush_work(struct drm_encoder *encoder);
int intel_dp_compute_config(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config,
......@@ -92,16 +93,15 @@ void intel_edp_drrs_flush(struct drm_i915_private *dev_priv,
void
intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state,
u8 dp_train_pat);
void
intel_dp_set_signal_levels(struct intel_dp *intel_dp);
void intel_dp_set_idle_link_train(struct intel_dp *intel_dp);
intel_dp_set_signal_levels(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state);
void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock,
u8 *link_bw, u8 *rate_select);
bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp);
bool intel_dp_source_supports_hbr3(struct intel_dp *intel_dp);
bool
intel_dp_get_link_status(struct intel_dp *intel_dp, u8 *link_status);
bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp);
int intel_dp_link_required(int pixel_clock, int bpp);
......@@ -122,7 +122,6 @@ void intel_read_dp_sdp(struct intel_encoder *encoder,
struct intel_crtc_state *crtc_state,
unsigned int type);
bool intel_digital_port_connected(struct intel_encoder *encoder);
void intel_dp_process_phy_request(struct intel_dp *intel_dp);
static inline unsigned int intel_dp_unused_lane_mask(int lane_count)
{
......@@ -139,4 +138,9 @@ void intel_ddi_update_pipe(struct intel_atomic_state *state,
int intel_dp_init_hdcp(struct intel_digital_port *dig_port,
struct intel_connector *intel_connector);
bool intel_dp_initial_fastset_check(struct intel_encoder *encoder,
struct intel_crtc_state *crtc_state);
void intel_dp_sync_state(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state);
#endif /* __INTEL_DP_H__ */
......@@ -343,8 +343,7 @@ intel_dp_aux_display_control_capable(struct intel_connector *connector)
* the panel can support backlight control over the aux channel
*/
if (intel_dp->edp_dpcd[1] & DP_EDP_TCON_BACKLIGHT_ADJUSTMENT_CAP &&
(intel_dp->edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_AUX_SET_CAP) &&
!(intel_dp->edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_PWM_PIN_CAP)) {
(intel_dp->edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_AUX_SET_CAP)) {
drm_dbg_kms(&i915->drm, "AUX Backlight Control Supported!\n");
return true;
}
......
......@@ -8,11 +8,24 @@
#include <drm/drm_dp_helper.h>
struct intel_crtc_state;
struct intel_dp;
int intel_dp_lttpr_init(struct intel_dp *intel_dp);
void intel_dp_get_adjust_train(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state,
enum drm_dp_phy dp_phy,
const u8 link_status[DP_LINK_STATUS_SIZE]);
void intel_dp_start_link_train(struct intel_dp *intel_dp);
void intel_dp_stop_link_train(struct intel_dp *intel_dp);
void intel_dp_start_link_train(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state);
void intel_dp_stop_link_train(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state);
/* Get the TPSx symbol type of the value programmed to DP_TRAINING_PATTERN_SET */
static inline u8 intel_dp_training_pattern_symbol(u8 pattern)
{
return pattern & ~DP_LINK_SCRAMBLING_DISABLE;
}
#endif /* __INTEL_DP_LINK_TRAINING_H__ */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment