drm/rockchip: vop2: change pixelclk calculation method for mipi

Both DP and MIPI get pixelclk from dclk_out as follow:
DP: dclkx_out(DIV)->dpn_pixelclk(MUX)
MIPI:dclkx_out(DIV)->mipi_clk_src(MUX)->mipi_pixelclk(DIV)

When a video port coonect DP, it will calculate dclk rate first,
then dclk out rate, finally dp pixelclk rate. When a video Port
connect to MIPI it will calculate mipi_pixelclk rate first.

The different calculation method may get different dclk rate or
divider ratio. When a video port connect to a DP and MIPI, DP
or MIPI may get the wrong pixel rate. So they need use the same
method to calculate pixelclk.

When A video port connect DP and MIPI, the mipi_pixelclk
is set first, and set the mipi_pixelclk divide value. Then
dp_pixelclk is set, which will modify dclk_out divide value
and cause the mipi_pixelclk change.

So when calculate the mipi_pixelclk, we calculate the dclk_out
first to avoid the mipi_pixelclk be modified when DP set
dp_pixelclk.

For uboot logo display, Depend on commit from u-boot(branch:
next-dev):
(I6037e12d8b6 drm/rockchip: vop2: change dclk calculate method
for mipi)

Signed-off-by: Zhang Yubing <yubing.zhang@rock-chips.com>
Change-Id: I53c3247ce1eb728dad7f480d86b65d3f922ab6d4
This commit is contained in:
Zhang Yubing
2022-03-02 15:51:00 +08:00
committed by Tao Huang
parent b8e104fa2d
commit a1da8104ca

View File

@@ -5789,14 +5789,13 @@ static int vop2_calc_if_clk(struct drm_crtc *crtc, const struct vop2_connector_i
dclk_out_rate = dclk_out_rate / K;
if_pixclk->rate = dclk_out_rate;
} else if (output_if_is_mipi(conn_id)) {
if (vcstate->dsc_enable) {
dclk_out_rate = dclk_core_rate / K;
if (vcstate->dsc_enable)
/* dsc output is 96bit, dsi input is 192 bit */
mipi_pixclk = vcstate->dsc_cds_clk_rate >> 1;
} else {
else
mipi_pixclk = dclk_core_rate / K;
}
dclk_out_rate = dclk_core_rate / K;
if_pixclk->rate = mipi_pixclk;
} else if (output_if_is_dpi(conn_id)) {
if_pixclk->rate = v_pixclk;
@@ -5835,7 +5834,7 @@ static int vop2_calc_if_clk(struct drm_crtc *crtc, const struct vop2_connector_i
* When used for HDMI, the input freq and v_pixclk must
* keep 1:1 for rgb/yuv444, 1:2 for yuv420
*/
if (output_if_is_hdmi(conn_id) || output_if_is_dp(conn_id)) {
if (output_if_is_hdmi(conn_id) || output_if_is_dp(conn_id) || output_if_is_mipi(conn_id)) {
snprintf(clk_name, sizeof(clk_name), "dclk%d", vp->id);
dclk = vop2_clk_get(vop2, clk_name);
if (v_pixclk <= (VOP2_MAX_DCLK_RATE * 1000)) {
@@ -5847,14 +5846,14 @@ static int vop2_calc_if_clk(struct drm_crtc *crtc, const struct vop2_connector_i
if (dclk_core_rate > if_pixclk->rate) {
clk_set_rate(dclk_core->hw.clk, dclk_core_rate);
if (output_if_is_mipi(conn_id) && vcstate->dsc_enable)
if (output_if_is_mipi(conn_id))
clk_set_rate(dclk_out->hw.clk, dclk_out_rate);
ret = vop2_cru_set_rate(if_pixclk, if_dclk);
} else {
if (output_if_is_mipi(conn_id))
clk_set_rate(dclk_out->hw.clk, dclk_out_rate);
ret = vop2_cru_set_rate(if_pixclk, if_dclk);
clk_set_rate(dclk_core->hw.clk, dclk_core_rate);
if (output_if_is_mipi(conn_id) && vcstate->dsc_enable)
clk_set_rate(dclk_out->hw.clk, dclk_out_rate);
}
if (!dsc_txp_clk_is_biggest && vcstate->dsc_enable) {