1
0
Fork 0
mirror of synced 2025-03-06 20:59:54 +01:00

Merge tag 'drm-msm-fixes-2025-02-20' of https://gitlab.freedesktop.org/drm/msm into drm-fixes

Fixes for v6.14-rc4

Display:
* More catalog fixes:
 - to skip watchdog programming through top block if its not present
 - fix the setting of WB mask to ensure the WB input control is programmed
   correctly through ping-pong
 - drop lm_pair for sm6150 as that chipset does not have any 3dmerge block
* Fix the mode validation logic for DP/eDP to account for widebus (2ppc)
  to allow high clock resolutions
* Fix to disable dither during encoder disable as otherwise this was
  causing kms_writeback failure due to resource sharing between
* WB and DSI paths as DSI uses dither but WB does not
* Fixes for virtual planes, namely to drop extraneous return and fix
  uninitialized variables
* Fix to avoid spill-over of DSC encoder block bits when programming
  the bits-per-component
* Fixes in the DSI PHY to protect against concurrent access of
  PHY_CMN_CLK_CFG regs between clock and display drivers

Core/GPU:
* Fix non-blocking fence wait incorrectly rounding up to 1 jiffy timeout
* Only print GMU fw version once, instead of each time the GPU resumes

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Rob Clark <robdclark@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/CAF6AEGtt2AODBXdod8ULXcAygf_qYvwRDVeUVtODx=2jErp6cA@mail.gmail.com
This commit is contained in:
Dave Airlie 2025-02-21 10:50:28 +10:00
commit 9a1cd7d6df
15 changed files with 75 additions and 49 deletions

View file

@ -813,10 +813,10 @@ static int a6xx_gmu_fw_load(struct a6xx_gmu *gmu)
} }
ver = gmu_read(gmu, REG_A6XX_GMU_CORE_FW_VERSION); ver = gmu_read(gmu, REG_A6XX_GMU_CORE_FW_VERSION);
DRM_INFO("Loaded GMU firmware v%u.%u.%u\n", DRM_INFO_ONCE("Loaded GMU firmware v%u.%u.%u\n",
FIELD_GET(A6XX_GMU_CORE_FW_VERSION_MAJOR__MASK, ver), FIELD_GET(A6XX_GMU_CORE_FW_VERSION_MAJOR__MASK, ver),
FIELD_GET(A6XX_GMU_CORE_FW_VERSION_MINOR__MASK, ver), FIELD_GET(A6XX_GMU_CORE_FW_VERSION_MINOR__MASK, ver),
FIELD_GET(A6XX_GMU_CORE_FW_VERSION_STEP__MASK, ver)); FIELD_GET(A6XX_GMU_CORE_FW_VERSION_STEP__MASK, ver));
return 0; return 0;
} }

View file

@ -297,7 +297,7 @@ static const struct dpu_wb_cfg sm8150_wb[] = {
{ {
.name = "wb_2", .id = WB_2, .name = "wb_2", .id = WB_2,
.base = 0x65000, .len = 0x2c8, .base = 0x65000, .len = 0x2c8,
.features = WB_SDM845_MASK, .features = WB_SM8250_MASK,
.format_list = wb2_formats_rgb, .format_list = wb2_formats_rgb,
.num_formats = ARRAY_SIZE(wb2_formats_rgb), .num_formats = ARRAY_SIZE(wb2_formats_rgb),
.clk_ctrl = DPU_CLK_CTRL_WB2, .clk_ctrl = DPU_CLK_CTRL_WB2,

View file

@ -304,7 +304,7 @@ static const struct dpu_wb_cfg sc8180x_wb[] = {
{ {
.name = "wb_2", .id = WB_2, .name = "wb_2", .id = WB_2,
.base = 0x65000, .len = 0x2c8, .base = 0x65000, .len = 0x2c8,
.features = WB_SDM845_MASK, .features = WB_SM8250_MASK,
.format_list = wb2_formats_rgb, .format_list = wb2_formats_rgb,
.num_formats = ARRAY_SIZE(wb2_formats_rgb), .num_formats = ARRAY_SIZE(wb2_formats_rgb),
.clk_ctrl = DPU_CLK_CTRL_WB2, .clk_ctrl = DPU_CLK_CTRL_WB2,

View file

@ -116,14 +116,12 @@ static const struct dpu_lm_cfg sm6150_lm[] = {
.sblk = &sdm845_lm_sblk, .sblk = &sdm845_lm_sblk,
.pingpong = PINGPONG_0, .pingpong = PINGPONG_0,
.dspp = DSPP_0, .dspp = DSPP_0,
.lm_pair = LM_1,
}, { }, {
.name = "lm_1", .id = LM_1, .name = "lm_1", .id = LM_1,
.base = 0x45000, .len = 0x320, .base = 0x45000, .len = 0x320,
.features = MIXER_QCM2290_MASK, .features = MIXER_QCM2290_MASK,
.sblk = &sdm845_lm_sblk, .sblk = &sdm845_lm_sblk,
.pingpong = PINGPONG_1, .pingpong = PINGPONG_1,
.lm_pair = LM_0,
}, { }, {
.name = "lm_2", .id = LM_2, .name = "lm_2", .id = LM_2,
.base = 0x46000, .len = 0x320, .base = 0x46000, .len = 0x320,

View file

@ -144,7 +144,7 @@ static const struct dpu_wb_cfg sm6125_wb[] = {
{ {
.name = "wb_2", .id = WB_2, .name = "wb_2", .id = WB_2,
.base = 0x65000, .len = 0x2c8, .base = 0x65000, .len = 0x2c8,
.features = WB_SDM845_MASK, .features = WB_SM8250_MASK,
.format_list = wb2_formats_rgb, .format_list = wb2_formats_rgb,
.num_formats = ARRAY_SIZE(wb2_formats_rgb), .num_formats = ARRAY_SIZE(wb2_formats_rgb),
.clk_ctrl = DPU_CLK_CTRL_WB2, .clk_ctrl = DPU_CLK_CTRL_WB2,

View file

@ -1228,8 +1228,6 @@ static int dpu_crtc_reassign_planes(struct drm_crtc *crtc, struct drm_crtc_state
done: done:
kfree(states); kfree(states);
return ret; return ret;
return 0;
} }
static int dpu_crtc_atomic_check(struct drm_crtc *crtc, static int dpu_crtc_atomic_check(struct drm_crtc *crtc,

View file

@ -2281,6 +2281,9 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc)
} }
} }
if (phys_enc->hw_pp && phys_enc->hw_pp->ops.setup_dither)
phys_enc->hw_pp->ops.setup_dither(phys_enc->hw_pp, NULL);
/* reset the merge 3D HW block */ /* reset the merge 3D HW block */
if (phys_enc->hw_pp && phys_enc->hw_pp->merge_3d) { if (phys_enc->hw_pp && phys_enc->hw_pp->merge_3d) {
phys_enc->hw_pp->merge_3d->ops.setup_3d_mode(phys_enc->hw_pp->merge_3d, phys_enc->hw_pp->merge_3d->ops.setup_3d_mode(phys_enc->hw_pp->merge_3d,

View file

@ -52,6 +52,7 @@ static void dpu_hw_dsc_config(struct dpu_hw_dsc *hw_dsc,
u32 slice_last_group_size; u32 slice_last_group_size;
u32 det_thresh_flatness; u32 det_thresh_flatness;
bool is_cmd_mode = !(mode & DSC_MODE_VIDEO); bool is_cmd_mode = !(mode & DSC_MODE_VIDEO);
bool input_10_bits = dsc->bits_per_component == 10;
DPU_REG_WRITE(c, DSC_COMMON_MODE, mode); DPU_REG_WRITE(c, DSC_COMMON_MODE, mode);
@ -68,7 +69,7 @@ static void dpu_hw_dsc_config(struct dpu_hw_dsc *hw_dsc,
data |= (dsc->line_buf_depth << 3); data |= (dsc->line_buf_depth << 3);
data |= (dsc->simple_422 << 2); data |= (dsc->simple_422 << 2);
data |= (dsc->convert_rgb << 1); data |= (dsc->convert_rgb << 1);
data |= dsc->bits_per_component; data |= input_10_bits;
DPU_REG_WRITE(c, DSC_ENC, data); DPU_REG_WRITE(c, DSC_ENC, data);

View file

@ -272,7 +272,7 @@ static void _setup_mdp_ops(struct dpu_hw_mdp_ops *ops,
if (cap & BIT(DPU_MDP_VSYNC_SEL)) if (cap & BIT(DPU_MDP_VSYNC_SEL))
ops->setup_vsync_source = dpu_hw_setup_vsync_sel; ops->setup_vsync_source = dpu_hw_setup_vsync_sel;
else else if (!(cap & BIT(DPU_MDP_PERIPH_0_REMOVED)))
ops->setup_vsync_source = dpu_hw_setup_wd_timer; ops->setup_vsync_source = dpu_hw_setup_wd_timer;
ops->get_safe_status = dpu_hw_get_safe_status; ops->get_safe_status = dpu_hw_get_safe_status;

View file

@ -1164,7 +1164,6 @@ int dpu_assign_plane_resources(struct dpu_global_state *global_state,
unsigned int num_planes) unsigned int num_planes)
{ {
unsigned int i; unsigned int i;
int ret;
for (i = 0; i < num_planes; i++) { for (i = 0; i < num_planes; i++) {
struct drm_plane_state *plane_state = states[i]; struct drm_plane_state *plane_state = states[i];
@ -1173,13 +1172,13 @@ int dpu_assign_plane_resources(struct dpu_global_state *global_state,
!plane_state->visible) !plane_state->visible)
continue; continue;
ret = dpu_plane_virtual_assign_resources(crtc, global_state, int ret = dpu_plane_virtual_assign_resources(crtc, global_state,
state, plane_state); state, plane_state);
if (ret) if (ret)
break; return ret;
} }
return ret; return 0;
} }
static void dpu_plane_flush_csc(struct dpu_plane *pdpu, struct dpu_sw_pipe *pipe) static void dpu_plane_flush_csc(struct dpu_plane *pdpu, struct dpu_sw_pipe *pipe)

View file

@ -930,16 +930,17 @@ enum drm_mode_status msm_dp_bridge_mode_valid(struct drm_bridge *bridge,
return -EINVAL; return -EINVAL;
} }
if (mode->clock > DP_MAX_PIXEL_CLK_KHZ)
return MODE_CLOCK_HIGH;
msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display); msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
link_info = &msm_dp_display->panel->link_info; link_info = &msm_dp_display->panel->link_info;
if (drm_mode_is_420_only(&dp->connector->display_info, mode) && if ((drm_mode_is_420_only(&dp->connector->display_info, mode) &&
msm_dp_display->panel->vsc_sdp_supported) msm_dp_display->panel->vsc_sdp_supported) ||
msm_dp_wide_bus_available(dp))
mode_pclk_khz /= 2; mode_pclk_khz /= 2;
if (mode_pclk_khz > DP_MAX_PIXEL_CLK_KHZ)
return MODE_CLOCK_HIGH;
mode_bpp = dp->connector->display_info.bpc * num_components; mode_bpp = dp->connector->display_info.bpc * num_components;
if (!mode_bpp) if (!mode_bpp)
mode_bpp = default_bpp; mode_bpp = default_bpp;

View file

@ -257,7 +257,10 @@ static enum drm_mode_status msm_edp_bridge_mode_valid(struct drm_bridge *bridge,
return -EINVAL; return -EINVAL;
} }
if (mode->clock > DP_MAX_PIXEL_CLK_KHZ) if (msm_dp_wide_bus_available(dp))
mode_pclk_khz /= 2;
if (mode_pclk_khz > DP_MAX_PIXEL_CLK_KHZ)
return MODE_CLOCK_HIGH; return MODE_CLOCK_HIGH;
/* /*

View file

@ -83,6 +83,9 @@ struct dsi_pll_7nm {
/* protects REG_DSI_7nm_PHY_CMN_CLK_CFG0 register */ /* protects REG_DSI_7nm_PHY_CMN_CLK_CFG0 register */
spinlock_t postdiv_lock; spinlock_t postdiv_lock;
/* protects REG_DSI_7nm_PHY_CMN_CLK_CFG1 register */
spinlock_t pclk_mux_lock;
struct pll_7nm_cached_state cached_state; struct pll_7nm_cached_state cached_state;
struct dsi_pll_7nm *slave; struct dsi_pll_7nm *slave;
@ -372,22 +375,41 @@ static void dsi_pll_enable_pll_bias(struct dsi_pll_7nm *pll)
ndelay(250); ndelay(250);
} }
static void dsi_pll_disable_global_clk(struct dsi_pll_7nm *pll) static void dsi_pll_cmn_clk_cfg0_write(struct dsi_pll_7nm *pll, u32 val)
{ {
unsigned long flags;
spin_lock_irqsave(&pll->postdiv_lock, flags);
writel(val, pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG0);
spin_unlock_irqrestore(&pll->postdiv_lock, flags);
}
static void dsi_pll_cmn_clk_cfg1_update(struct dsi_pll_7nm *pll, u32 mask,
u32 val)
{
unsigned long flags;
u32 data; u32 data;
spin_lock_irqsave(&pll->pclk_mux_lock, flags);
data = readl(pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); data = readl(pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);
writel(data & ~BIT(5), pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); data &= ~mask;
data |= val & mask;
writel(data, pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);
spin_unlock_irqrestore(&pll->pclk_mux_lock, flags);
}
static void dsi_pll_disable_global_clk(struct dsi_pll_7nm *pll)
{
dsi_pll_cmn_clk_cfg1_update(pll, DSI_7nm_PHY_CMN_CLK_CFG1_CLK_EN, 0);
} }
static void dsi_pll_enable_global_clk(struct dsi_pll_7nm *pll) static void dsi_pll_enable_global_clk(struct dsi_pll_7nm *pll)
{ {
u32 data; u32 cfg_1 = DSI_7nm_PHY_CMN_CLK_CFG1_CLK_EN | DSI_7nm_PHY_CMN_CLK_CFG1_CLK_EN_SEL;
writel(0x04, pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_3); writel(0x04, pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_3);
dsi_pll_cmn_clk_cfg1_update(pll, cfg_1, cfg_1);
data = readl(pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);
writel(data | BIT(5) | BIT(4), pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);
} }
static void dsi_pll_phy_dig_reset(struct dsi_pll_7nm *pll) static void dsi_pll_phy_dig_reset(struct dsi_pll_7nm *pll)
@ -565,7 +587,6 @@ static int dsi_7nm_pll_restore_state(struct msm_dsi_phy *phy)
{ {
struct dsi_pll_7nm *pll_7nm = to_pll_7nm(phy->vco_hw); struct dsi_pll_7nm *pll_7nm = to_pll_7nm(phy->vco_hw);
struct pll_7nm_cached_state *cached = &pll_7nm->cached_state; struct pll_7nm_cached_state *cached = &pll_7nm->cached_state;
void __iomem *phy_base = pll_7nm->phy->base;
u32 val; u32 val;
int ret; int ret;
@ -574,13 +595,10 @@ static int dsi_7nm_pll_restore_state(struct msm_dsi_phy *phy)
val |= cached->pll_out_div; val |= cached->pll_out_div;
writel(val, pll_7nm->phy->pll_base + REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE); writel(val, pll_7nm->phy->pll_base + REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE);
writel(cached->bit_clk_div | (cached->pix_clk_div << 4), dsi_pll_cmn_clk_cfg0_write(pll_7nm,
phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG0); DSI_7nm_PHY_CMN_CLK_CFG0_DIV_CTRL_3_0(cached->bit_clk_div) |
DSI_7nm_PHY_CMN_CLK_CFG0_DIV_CTRL_7_4(cached->pix_clk_div));
val = readl(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); dsi_pll_cmn_clk_cfg1_update(pll_7nm, 0x3, cached->pll_mux);
val &= ~0x3;
val |= cached->pll_mux;
writel(val, phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);
ret = dsi_pll_7nm_vco_set_rate(phy->vco_hw, ret = dsi_pll_7nm_vco_set_rate(phy->vco_hw,
pll_7nm->vco_current_rate, pll_7nm->vco_current_rate,
@ -599,7 +617,6 @@ static int dsi_7nm_pll_restore_state(struct msm_dsi_phy *phy)
static int dsi_7nm_set_usecase(struct msm_dsi_phy *phy) static int dsi_7nm_set_usecase(struct msm_dsi_phy *phy)
{ {
struct dsi_pll_7nm *pll_7nm = to_pll_7nm(phy->vco_hw); struct dsi_pll_7nm *pll_7nm = to_pll_7nm(phy->vco_hw);
void __iomem *base = phy->base;
u32 data = 0x0; /* internal PLL */ u32 data = 0x0; /* internal PLL */
DBG("DSI PLL%d", pll_7nm->phy->id); DBG("DSI PLL%d", pll_7nm->phy->id);
@ -618,7 +635,8 @@ static int dsi_7nm_set_usecase(struct msm_dsi_phy *phy)
} }
/* set PLL src */ /* set PLL src */
writel(data << 2, base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); dsi_pll_cmn_clk_cfg1_update(pll_7nm, DSI_7nm_PHY_CMN_CLK_CFG1_BITCLK_SEL__MASK,
DSI_7nm_PHY_CMN_CLK_CFG1_BITCLK_SEL(data));
return 0; return 0;
} }
@ -733,7 +751,7 @@ static int pll_7nm_register(struct dsi_pll_7nm *pll_7nm, struct clk_hw **provide
pll_by_2_bit, pll_by_2_bit,
}), 2, 0, pll_7nm->phy->base + }), 2, 0, pll_7nm->phy->base +
REG_DSI_7nm_PHY_CMN_CLK_CFG1, REG_DSI_7nm_PHY_CMN_CLK_CFG1,
0, 1, 0, NULL); 0, 1, 0, &pll_7nm->pclk_mux_lock);
if (IS_ERR(hw)) { if (IS_ERR(hw)) {
ret = PTR_ERR(hw); ret = PTR_ERR(hw);
goto fail; goto fail;
@ -778,6 +796,7 @@ static int dsi_pll_7nm_init(struct msm_dsi_phy *phy)
pll_7nm_list[phy->id] = pll_7nm; pll_7nm_list[phy->id] = pll_7nm;
spin_lock_init(&pll_7nm->postdiv_lock); spin_lock_init(&pll_7nm->postdiv_lock);
spin_lock_init(&pll_7nm->pclk_mux_lock);
pll_7nm->phy = phy; pll_7nm->phy = phy;

View file

@ -537,15 +537,12 @@ static inline int align_pitch(int width, int bpp)
static inline unsigned long timeout_to_jiffies(const ktime_t *timeout) static inline unsigned long timeout_to_jiffies(const ktime_t *timeout)
{ {
ktime_t now = ktime_get(); ktime_t now = ktime_get();
s64 remaining_jiffies;
if (ktime_compare(*timeout, now) < 0) { if (ktime_compare(*timeout, now) <= 0)
remaining_jiffies = 0; return 0;
} else {
ktime_t rem = ktime_sub(*timeout, now);
remaining_jiffies = ktime_divns(rem, NSEC_PER_SEC / HZ);
}
ktime_t rem = ktime_sub(*timeout, now);
s64 remaining_jiffies = ktime_divns(rem, NSEC_PER_SEC / HZ);
return clamp(remaining_jiffies, 1LL, (s64)INT_MAX); return clamp(remaining_jiffies, 1LL, (s64)INT_MAX);
} }

View file

@ -9,8 +9,15 @@ xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
<reg32 offset="0x00004" name="REVISION_ID1"/> <reg32 offset="0x00004" name="REVISION_ID1"/>
<reg32 offset="0x00008" name="REVISION_ID2"/> <reg32 offset="0x00008" name="REVISION_ID2"/>
<reg32 offset="0x0000c" name="REVISION_ID3"/> <reg32 offset="0x0000c" name="REVISION_ID3"/>
<reg32 offset="0x00010" name="CLK_CFG0"/> <reg32 offset="0x00010" name="CLK_CFG0">
<reg32 offset="0x00014" name="CLK_CFG1"/> <bitfield name="DIV_CTRL_3_0" low="0" high="3" type="uint"/>
<bitfield name="DIV_CTRL_7_4" low="4" high="7" type="uint"/>
</reg32>
<reg32 offset="0x00014" name="CLK_CFG1">
<bitfield name="CLK_EN" pos="5" type="boolean"/>
<bitfield name="CLK_EN_SEL" pos="4" type="boolean"/>
<bitfield name="BITCLK_SEL" low="2" high="3" type="uint"/>
</reg32>
<reg32 offset="0x00018" name="GLBL_CTRL"/> <reg32 offset="0x00018" name="GLBL_CTRL"/>
<reg32 offset="0x0001c" name="RBUF_CTRL"/> <reg32 offset="0x0001c" name="RBUF_CTRL"/>
<reg32 offset="0x00020" name="VREG_CTRL_0"/> <reg32 offset="0x00020" name="VREG_CTRL_0"/>