Commit 351221ff authored by Ville Syrjälä's avatar Ville Syrjälä

drm/i915: Move DDI clock readout to encoder->get_config()

Move the *_get_ddi_pll() stuff into the encodet->get_config() hook.
There it neatly sits next to the matching .{enable,disable}_clock()
functions.

In order to avoid excessive boilerplate I changed the behaviour
such that all platforms now do the readout via
crtc_state->port_dpll[].

ICL+ TC is still a bit special due to TBTPLL not having a functional
.get_freq(). Should probably change that by adopting the LCPLL
approach, but that would require a fairly substantial rework of the
DPLL ID handling. So leave it for later.
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210224144214.24803-5-ville.syrjala@linux.intel.comReviewed-by: default avatarMika Kahola <mika.kahola@intel.com>
parent d0f1bfc6
......@@ -1490,14 +1490,10 @@ static void gen11_dsi_get_cmd_mode_config(struct intel_dsi *intel_dsi,
static void gen11_dsi_get_config(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config)
{
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
/* FIXME: adapt icl_ddi_clock_get() for DSI and use that? */
pipe_config->port_clock = intel_dpll_get_freq(i915,
pipe_config->shared_dpll,
&pipe_config->dpll_hw_state);
intel_ddi_get_clock(encoder, pipe_config, icl_ddi_combo_get_pll(encoder));
pipe_config->hw.adjusted_mode.crtc_clock = intel_dsi->pclk;
if (intel_dsi->dual_link)
......
......@@ -142,7 +142,7 @@ static void hsw_crt_get_config(struct intel_encoder *encoder,
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
intel_ddi_get_config(encoder, pipe_config);
hsw_ddi_get_config(encoder, pipe_config);
pipe_config->hw.adjusted_mode.flags &= ~(DRM_MODE_FLAG_PHSYNC |
DRM_MODE_FLAG_NHSYNC |
......
This diff is collapsed.
......@@ -30,9 +30,15 @@ void intel_ddi_fdi_post_disable(struct intel_atomic_state *state,
const struct drm_connector_state *old_conn_state);
void intel_ddi_enable_clock(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state);
void intel_ddi_get_clock(struct intel_encoder *encoder,
struct intel_crtc_state *crtc_state,
struct intel_shared_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);
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);
void intel_prepare_dp_ddi_buffers(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state);
void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
......@@ -48,8 +54,6 @@ void intel_ddi_disable_pipe_clock(const struct intel_crtc_state *crtc_state);
void intel_ddi_set_dp_msa(const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state);
bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector);
void intel_ddi_get_config(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config);
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,
......
......@@ -6554,212 +6554,6 @@ static bool ilk_get_pipe_config(struct intel_crtc *crtc,
return ret;
}
static void dg1_get_ddi_pll(struct drm_i915_private *dev_priv, enum port port,
struct intel_crtc_state *pipe_config)
{
enum icl_port_dpll_id port_dpll_id = ICL_PORT_DPLL_DEFAULT;
enum phy phy = intel_port_to_phy(dev_priv, port);
struct icl_port_dpll *port_dpll;
struct intel_shared_dpll *pll;
enum intel_dpll_id id;
bool pll_active;
u32 clk_sel;
clk_sel = intel_de_read(dev_priv, DG1_DPCLKA_CFGCR0(phy)) & DG1_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy);
id = DG1_DPCLKA_CFGCR0_DDI_CLK_SEL_DPLL_MAP(clk_sel, phy);
if (WARN_ON(id > DPLL_ID_DG1_DPLL3))
return;
pll = intel_get_shared_dpll_by_id(dev_priv, id);
port_dpll = &pipe_config->icl_port_dplls[port_dpll_id];
port_dpll->pll = pll;
pll_active = intel_dpll_get_hw_state(dev_priv, pll,
&port_dpll->hw_state);
drm_WARN_ON(&dev_priv->drm, !pll_active);
icl_set_active_port_dpll(pipe_config, port_dpll_id);
}
static void icl_get_ddi_pll(struct drm_i915_private *dev_priv, enum port port,
struct intel_crtc_state *pipe_config)
{
enum phy phy = intel_port_to_phy(dev_priv, port);
enum icl_port_dpll_id port_dpll_id;
struct icl_port_dpll *port_dpll;
struct intel_shared_dpll *pll;
enum intel_dpll_id id;
bool pll_active;
i915_reg_t reg;
u32 temp;
if (intel_phy_is_combo(dev_priv, phy)) {
u32 mask, shift;
if (IS_ALDERLAKE_S(dev_priv)) {
reg = ADLS_DPCLKA_CFGCR(phy);
mask = ADLS_DPCLKA_CFGCR_DDI_CLK_SEL_MASK(phy);
shift = ADLS_DPCLKA_CFGCR_DDI_SHIFT(phy);
} else if (IS_ROCKETLAKE(dev_priv)) {
reg = ICL_DPCLKA_CFGCR0;
mask = RKL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy);
shift = RKL_DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(phy);
} else {
reg = ICL_DPCLKA_CFGCR0;
mask = ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy);
shift = ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(phy);
}
temp = intel_de_read(dev_priv, reg) & mask;
id = temp >> shift;
port_dpll_id = ICL_PORT_DPLL_DEFAULT;
} else if (intel_phy_is_tc(dev_priv, phy)) {
u32 clk_sel = intel_de_read(dev_priv, DDI_CLK_SEL(port)) & DDI_CLK_SEL_MASK;
if (clk_sel == DDI_CLK_SEL_MG) {
id = icl_tc_port_to_pll_id(intel_port_to_tc(dev_priv,
port));
port_dpll_id = ICL_PORT_DPLL_MG_PHY;
} else {
drm_WARN_ON(&dev_priv->drm,
clk_sel < DDI_CLK_SEL_TBT_162);
id = DPLL_ID_ICL_TBTPLL;
port_dpll_id = ICL_PORT_DPLL_DEFAULT;
}
} else {
drm_WARN(&dev_priv->drm, 1, "Invalid port %x\n", port);
return;
}
pll = intel_get_shared_dpll_by_id(dev_priv, id);
port_dpll = &pipe_config->icl_port_dplls[port_dpll_id];
port_dpll->pll = pll;
pll_active = intel_dpll_get_hw_state(dev_priv, pll,
&port_dpll->hw_state);
drm_WARN_ON(&dev_priv->drm, !pll_active);
icl_set_active_port_dpll(pipe_config, port_dpll_id);
}
static void cnl_get_ddi_pll(struct drm_i915_private *dev_priv, enum port port,
struct intel_crtc_state *pipe_config)
{
struct intel_shared_dpll *pll;
enum intel_dpll_id id;
bool pll_active;
u32 temp;
temp = intel_de_read(dev_priv, DPCLKA_CFGCR0) & DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port);
id = temp >> DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(port);
if (drm_WARN_ON(&dev_priv->drm, id < SKL_DPLL0 || id > SKL_DPLL2))
return;
pll = intel_get_shared_dpll_by_id(dev_priv, id);
pipe_config->shared_dpll = pll;
pll_active = intel_dpll_get_hw_state(dev_priv, pll,
&pipe_config->dpll_hw_state);
drm_WARN_ON(&dev_priv->drm, !pll_active);
}
static void bxt_get_ddi_pll(struct drm_i915_private *dev_priv,
enum port port,
struct intel_crtc_state *pipe_config)
{
struct intel_shared_dpll *pll;
enum intel_dpll_id id;
bool pll_active;
switch (port) {
case PORT_A:
id = DPLL_ID_SKL_DPLL0;
break;
case PORT_B:
id = DPLL_ID_SKL_DPLL1;
break;
case PORT_C:
id = DPLL_ID_SKL_DPLL2;
break;
default:
drm_err(&dev_priv->drm, "Incorrect port type\n");
return;
}
pll = intel_get_shared_dpll_by_id(dev_priv, id);
pipe_config->shared_dpll = pll;
pll_active = intel_dpll_get_hw_state(dev_priv, pll,
&pipe_config->dpll_hw_state);
drm_WARN_ON(&dev_priv->drm, !pll_active);
}
static void skl_get_ddi_pll(struct drm_i915_private *dev_priv, enum port port,
struct intel_crtc_state *pipe_config)
{
struct intel_shared_dpll *pll;
enum intel_dpll_id id;
bool pll_active;
u32 temp;
temp = intel_de_read(dev_priv, DPLL_CTRL2) & DPLL_CTRL2_DDI_CLK_SEL_MASK(port);
id = temp >> (port * 3 + 1);
if (drm_WARN_ON(&dev_priv->drm, id < SKL_DPLL0 || id > SKL_DPLL3))
return;
pll = intel_get_shared_dpll_by_id(dev_priv, id);
pipe_config->shared_dpll = pll;
pll_active = intel_dpll_get_hw_state(dev_priv, pll,
&pipe_config->dpll_hw_state);
drm_WARN_ON(&dev_priv->drm, !pll_active);
}
static void hsw_get_ddi_pll(struct drm_i915_private *dev_priv, enum port port,
struct intel_crtc_state *pipe_config)
{
struct intel_shared_dpll *pll;
enum intel_dpll_id id;
u32 ddi_pll_sel = intel_de_read(dev_priv, PORT_CLK_SEL(port));
bool pll_active;
switch (ddi_pll_sel) {
case PORT_CLK_SEL_WRPLL1:
id = DPLL_ID_WRPLL1;
break;
case PORT_CLK_SEL_WRPLL2:
id = DPLL_ID_WRPLL2;
break;
case PORT_CLK_SEL_SPLL:
id = DPLL_ID_SPLL;
break;
case PORT_CLK_SEL_LCPLL_810:
id = DPLL_ID_LCPLL_810;
break;
case PORT_CLK_SEL_LCPLL_1350:
id = DPLL_ID_LCPLL_1350;
break;
case PORT_CLK_SEL_LCPLL_2700:
id = DPLL_ID_LCPLL_2700;
break;
default:
MISSING_CASE(ddi_pll_sel);
fallthrough;
case PORT_CLK_SEL_NONE:
return;
}
pll = intel_get_shared_dpll_by_id(dev_priv, id);
pipe_config->shared_dpll = pll;
pll_active = intel_dpll_get_hw_state(dev_priv, pll,
&pipe_config->dpll_hw_state);
drm_WARN_ON(&dev_priv->drm, !pll_active);
}
static bool hsw_get_transcoder_state(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config,
struct intel_display_power_domain_set *power_domain_set)
......@@ -6916,19 +6710,6 @@ static void hsw_get_ddi_port_state(struct intel_crtc *crtc,
port = TRANS_DDI_FUNC_CTL_VAL_TO_PORT(tmp);
}
if (IS_DG1(dev_priv))
dg1_get_ddi_pll(dev_priv, port, pipe_config);
else if (INTEL_GEN(dev_priv) >= 11)
icl_get_ddi_pll(dev_priv, port, pipe_config);
else if (IS_CANNONLAKE(dev_priv))
cnl_get_ddi_pll(dev_priv, port, pipe_config);
else if (IS_GEN9_LP(dev_priv))
bxt_get_ddi_pll(dev_priv, port, pipe_config);
else if (IS_GEN9_BC(dev_priv))
skl_get_ddi_pll(dev_priv, port, pipe_config);
else
hsw_get_ddi_pll(dev_priv, port, pipe_config);
/*
* Haswell has only FDI/PCH transcoder A. It is which is connected to
* DDI E. So just check whether this pipe is wired to DDI E and whether
......
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