1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
6 #include <drm/drm_crtc.h>
7 #include <drm/drm_probe_helper.h>
11 static struct mdp5_kms
*get_kms(struct drm_encoder
*encoder
)
13 struct msm_drm_private
*priv
= encoder
->dev
->dev_private
;
14 return to_mdp5_kms(to_mdp_kms(priv
->kms
));
17 #ifdef DOWNSTREAM_CONFIG_MSM_BUS_SCALING
18 #include <mach/board.h>
19 #include <linux/msm-bus.h>
20 #include <linux/msm-bus-board.h>
22 static void bs_set(struct mdp5_encoder
*mdp5_cmd_enc
, int idx
)
24 if (mdp5_cmd_enc
->bsc
) {
25 DBG("set bus scaling: %d", idx
);
26 /* HACK: scaling down, and then immediately back up
27 * seems to leave things broken (underflow).. so
31 msm_bus_scale_client_update_request(mdp5_cmd_enc
->bsc
, idx
);
35 static void bs_set(struct mdp5_encoder
*mdp5_cmd_enc
, int idx
) {}
38 #define VSYNC_CLK_RATE 19200000
39 static int pingpong_tearcheck_setup(struct drm_encoder
*encoder
,
40 struct drm_display_mode
*mode
)
42 struct mdp5_kms
*mdp5_kms
= get_kms(encoder
);
43 struct device
*dev
= encoder
->dev
->dev
;
44 u32 total_lines_x100
, vclks_line
, cfg
;
46 struct mdp5_hw_mixer
*mixer
= mdp5_crtc_get_mixer(encoder
->crtc
);
47 int pp_id
= mixer
->pp
;
49 if (IS_ERR_OR_NULL(mdp5_kms
->vsync_clk
)) {
50 DRM_DEV_ERROR(dev
, "vsync_clk is not initialized\n");
54 total_lines_x100
= mode
->vtotal
* drm_mode_vrefresh(mode
);
55 if (!total_lines_x100
) {
56 DRM_DEV_ERROR(dev
, "%s: vtotal(%d) or vrefresh(%d) is 0\n",
57 __func__
, mode
->vtotal
, drm_mode_vrefresh(mode
));
61 vsync_clk_speed
= clk_round_rate(mdp5_kms
->vsync_clk
, VSYNC_CLK_RATE
);
62 if (vsync_clk_speed
<= 0) {
63 DRM_DEV_ERROR(dev
, "vsync_clk round rate failed %ld\n",
67 vclks_line
= vsync_clk_speed
* 100 / total_lines_x100
;
69 cfg
= MDP5_PP_SYNC_CONFIG_VSYNC_COUNTER_EN
70 | MDP5_PP_SYNC_CONFIG_VSYNC_IN_EN
;
71 cfg
|= MDP5_PP_SYNC_CONFIG_VSYNC_COUNT(vclks_line
);
73 mdp5_write(mdp5_kms
, REG_MDP5_PP_SYNC_CONFIG_VSYNC(pp_id
), cfg
);
75 REG_MDP5_PP_SYNC_CONFIG_HEIGHT(pp_id
), 0xfff0);
77 REG_MDP5_PP_VSYNC_INIT_VAL(pp_id
), mode
->vdisplay
);
78 mdp5_write(mdp5_kms
, REG_MDP5_PP_RD_PTR_IRQ(pp_id
), mode
->vdisplay
+ 1);
79 mdp5_write(mdp5_kms
, REG_MDP5_PP_START_POS(pp_id
), mode
->vdisplay
);
80 mdp5_write(mdp5_kms
, REG_MDP5_PP_SYNC_THRESH(pp_id
),
81 MDP5_PP_SYNC_THRESH_START(4) |
82 MDP5_PP_SYNC_THRESH_CONTINUE(4));
87 static int pingpong_tearcheck_enable(struct drm_encoder
*encoder
)
89 struct mdp5_kms
*mdp5_kms
= get_kms(encoder
);
90 struct mdp5_hw_mixer
*mixer
= mdp5_crtc_get_mixer(encoder
->crtc
);
91 int pp_id
= mixer
->pp
;
94 ret
= clk_set_rate(mdp5_kms
->vsync_clk
,
95 clk_round_rate(mdp5_kms
->vsync_clk
, VSYNC_CLK_RATE
));
97 DRM_DEV_ERROR(encoder
->dev
->dev
,
98 "vsync_clk clk_set_rate failed, %d\n", ret
);
101 ret
= clk_prepare_enable(mdp5_kms
->vsync_clk
);
103 DRM_DEV_ERROR(encoder
->dev
->dev
,
104 "vsync_clk clk_prepare_enable failed, %d\n", ret
);
108 mdp5_write(mdp5_kms
, REG_MDP5_PP_TEAR_CHECK_EN(pp_id
), 1);
113 static void pingpong_tearcheck_disable(struct drm_encoder
*encoder
)
115 struct mdp5_kms
*mdp5_kms
= get_kms(encoder
);
116 struct mdp5_hw_mixer
*mixer
= mdp5_crtc_get_mixer(encoder
->crtc
);
117 int pp_id
= mixer
->pp
;
119 mdp5_write(mdp5_kms
, REG_MDP5_PP_TEAR_CHECK_EN(pp_id
), 0);
120 clk_disable_unprepare(mdp5_kms
->vsync_clk
);
123 void mdp5_cmd_encoder_mode_set(struct drm_encoder
*encoder
,
124 struct drm_display_mode
*mode
,
125 struct drm_display_mode
*adjusted_mode
)
127 mode
= adjusted_mode
;
129 DBG("set mode: " DRM_MODE_FMT
, DRM_MODE_ARG(mode
));
130 pingpong_tearcheck_setup(encoder
, mode
);
131 mdp5_crtc_set_pipeline(encoder
->crtc
);
134 void mdp5_cmd_encoder_disable(struct drm_encoder
*encoder
)
136 struct mdp5_encoder
*mdp5_cmd_enc
= to_mdp5_encoder(encoder
);
137 struct mdp5_ctl
*ctl
= mdp5_cmd_enc
->ctl
;
138 struct mdp5_interface
*intf
= mdp5_cmd_enc
->intf
;
139 struct mdp5_pipeline
*pipeline
= mdp5_crtc_get_pipeline(encoder
->crtc
);
141 if (WARN_ON(!mdp5_cmd_enc
->enabled
))
144 pingpong_tearcheck_disable(encoder
);
146 mdp5_ctl_set_encoder_state(ctl
, pipeline
, false);
147 mdp5_ctl_commit(ctl
, pipeline
, mdp_ctl_flush_mask_encoder(intf
), true);
149 bs_set(mdp5_cmd_enc
, 0);
151 mdp5_cmd_enc
->enabled
= false;
154 void mdp5_cmd_encoder_enable(struct drm_encoder
*encoder
)
156 struct mdp5_encoder
*mdp5_cmd_enc
= to_mdp5_encoder(encoder
);
157 struct mdp5_ctl
*ctl
= mdp5_cmd_enc
->ctl
;
158 struct mdp5_interface
*intf
= mdp5_cmd_enc
->intf
;
159 struct mdp5_pipeline
*pipeline
= mdp5_crtc_get_pipeline(encoder
->crtc
);
161 if (WARN_ON(mdp5_cmd_enc
->enabled
))
164 bs_set(mdp5_cmd_enc
, 1);
165 if (pingpong_tearcheck_enable(encoder
))
168 mdp5_ctl_commit(ctl
, pipeline
, mdp_ctl_flush_mask_encoder(intf
), true);
170 mdp5_ctl_set_encoder_state(ctl
, pipeline
, true);
172 mdp5_cmd_enc
->enabled
= true;
175 int mdp5_cmd_encoder_set_split_display(struct drm_encoder
*encoder
,
176 struct drm_encoder
*slave_encoder
)
178 struct mdp5_encoder
*mdp5_cmd_enc
= to_mdp5_encoder(encoder
);
179 struct mdp5_kms
*mdp5_kms
;
184 if (!encoder
|| !slave_encoder
)
187 mdp5_kms
= get_kms(encoder
);
188 intf_num
= mdp5_cmd_enc
->intf
->num
;
190 /* Switch slave encoder's trigger MUX, to use the master's
191 * start signal for the slave encoder
194 data
|= MDP5_SPLIT_DPL_UPPER_INTF2_SW_TRG_MUX
;
195 else if (intf_num
== 2)
196 data
|= MDP5_SPLIT_DPL_UPPER_INTF1_SW_TRG_MUX
;
200 /* Smart Panel, Sync mode */
201 data
|= MDP5_SPLIT_DPL_UPPER_SMART_PANEL
;
203 dev
= &mdp5_kms
->pdev
->dev
;
205 /* Make sure clocks are on when connectors calling this function. */
206 pm_runtime_get_sync(dev
);
207 mdp5_write(mdp5_kms
, REG_MDP5_SPLIT_DPL_UPPER
, data
);
209 mdp5_write(mdp5_kms
, REG_MDP5_SPLIT_DPL_LOWER
,
210 MDP5_SPLIT_DPL_LOWER_SMART_PANEL
);
211 mdp5_write(mdp5_kms
, REG_MDP5_SPLIT_DPL_EN
, 1);
212 pm_runtime_put_sync(dev
);