aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArchit Taneja <architt@codeaurora.org>2017-01-16 00:55:38 -0500
committerRob Clark <robdclark@gmail.com>2017-02-06 11:28:43 -0500
commitb3a94705a0362fad1b25d559c3e0dd4433038f9e (patch)
treea82e0e0c83ac268856234f3eac12945db83f5d3b
parentdf8a71d2b22ffcecf4df6c07486a8baa5a49870a (diff)
drm/msm/mdp5: Create single encoder per interface (INTF)
For the DSI interfaces, the mdp5_kms core creates 2 encoders for video and command modes. Create only a single encoder per interface. When creating the encoder, set the interface type to MDP5_INTF_MODE_NONE. It's the bridge (DSI/HDMI/eDP) driver's responsibility to set a different interface type. It can use the the kms func op set_encoder_mode to change the mode of operation, which in turn would configure the interface type for the INTF. In mdp5_cmd_encoder.c, we remove the redundant code, and make the commmand mode funcs as helpers that are used in mdp5_encoder.c Signed-off-by: Archit Taneja <architt@codeaurora.org> Signed-off-by: Rob Clark <robdclark@gmail.com>
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c135
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c35
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c20
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h32
4 files changed, 66 insertions, 156 deletions
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c
index c627ab6d0061..df1c8adec3f3 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c
@@ -16,16 +16,6 @@
16#include "drm_crtc.h" 16#include "drm_crtc.h"
17#include "drm_crtc_helper.h" 17#include "drm_crtc_helper.h"
18 18
19struct mdp5_cmd_encoder {
20 struct drm_encoder base;
21 struct mdp5_interface intf;
22 bool enabled;
23 uint32_t bsc;
24
25 struct mdp5_ctl *ctl;
26};
27#define to_mdp5_cmd_encoder(x) container_of(x, struct mdp5_cmd_encoder, base)
28
29static struct mdp5_kms *get_kms(struct drm_encoder *encoder) 19static struct mdp5_kms *get_kms(struct drm_encoder *encoder)
30{ 20{
31 struct msm_drm_private *priv = encoder->dev->dev_private; 21 struct msm_drm_private *priv = encoder->dev->dev_private;
@@ -36,47 +26,8 @@ static struct mdp5_kms *get_kms(struct drm_encoder *encoder)
36#include <mach/board.h> 26#include <mach/board.h>
37#include <linux/msm-bus.h> 27#include <linux/msm-bus.h>
38#include <linux/msm-bus-board.h> 28#include <linux/msm-bus-board.h>
39#define MDP_BUS_VECTOR_ENTRY(ab_val, ib_val) \
40 { \
41 .src = MSM_BUS_MASTER_MDP_PORT0, \
42 .dst = MSM_BUS_SLAVE_EBI_CH0, \
43 .ab = (ab_val), \
44 .ib = (ib_val), \
45 }
46
47static struct msm_bus_vectors mdp_bus_vectors[] = {
48 MDP_BUS_VECTOR_ENTRY(0, 0),
49 MDP_BUS_VECTOR_ENTRY(2000000000, 2000000000),
50};
51static struct msm_bus_paths mdp_bus_usecases[] = { {
52 .num_paths = 1,
53 .vectors = &mdp_bus_vectors[0],
54}, {
55 .num_paths = 1,
56 .vectors = &mdp_bus_vectors[1],
57} };
58static struct msm_bus_scale_pdata mdp_bus_scale_table = {
59 .usecase = mdp_bus_usecases,
60 .num_usecases = ARRAY_SIZE(mdp_bus_usecases),
61 .name = "mdss_mdp",
62};
63
64static void bs_init(struct mdp5_cmd_encoder *mdp5_cmd_enc)
65{
66 mdp5_cmd_enc->bsc = msm_bus_scale_register_client(
67 &mdp_bus_scale_table);
68 DBG("bus scale client: %08x", mdp5_cmd_enc->bsc);
69}
70
71static void bs_fini(struct mdp5_cmd_encoder *mdp5_cmd_enc)
72{
73 if (mdp5_cmd_enc->bsc) {
74 msm_bus_scale_unregister_client(mdp5_cmd_enc->bsc);
75 mdp5_cmd_enc->bsc = 0;
76 }
77}
78 29
79static void bs_set(struct mdp5_cmd_encoder *mdp5_cmd_enc, int idx) 30static void bs_set(struct mdp5_encoder *mdp5_cmd_enc, int idx)
80{ 31{
81 if (mdp5_cmd_enc->bsc) { 32 if (mdp5_cmd_enc->bsc) {
82 DBG("set bus scaling: %d", idx); 33 DBG("set bus scaling: %d", idx);
@@ -89,14 +40,12 @@ static void bs_set(struct mdp5_cmd_encoder *mdp5_cmd_enc, int idx)
89 } 40 }
90} 41}
91#else 42#else
92static void bs_init(struct mdp5_cmd_encoder *mdp5_cmd_enc) {} 43static void bs_set(struct mdp5_encoder *mdp5_cmd_enc, int idx) {}
93static void bs_fini(struct mdp5_cmd_encoder *mdp5_cmd_enc) {}
94static void bs_set(struct mdp5_cmd_encoder *mdp5_cmd_enc, int idx) {}
95#endif 44#endif
96 45
97#define VSYNC_CLK_RATE 19200000 46#define VSYNC_CLK_RATE 19200000
98static int pingpong_tearcheck_setup(struct drm_encoder *encoder, 47static int pingpong_tearcheck_setup(struct drm_encoder *encoder,
99 struct drm_display_mode *mode) 48 struct drm_display_mode *mode)
100{ 49{
101 struct mdp5_kms *mdp5_kms = get_kms(encoder); 50 struct mdp5_kms *mdp5_kms = get_kms(encoder);
102 struct device *dev = encoder->dev->dev; 51 struct device *dev = encoder->dev->dev;
@@ -176,23 +125,11 @@ static void pingpong_tearcheck_disable(struct drm_encoder *encoder)
176 clk_disable_unprepare(mdp5_kms->vsync_clk); 125 clk_disable_unprepare(mdp5_kms->vsync_clk);
177} 126}
178 127
179static void mdp5_cmd_encoder_destroy(struct drm_encoder *encoder) 128void mdp5_cmd_encoder_mode_set(struct drm_encoder *encoder,
180{ 129 struct drm_display_mode *mode,
181 struct mdp5_cmd_encoder *mdp5_cmd_enc = to_mdp5_cmd_encoder(encoder); 130 struct drm_display_mode *adjusted_mode)
182 bs_fini(mdp5_cmd_enc);
183 drm_encoder_cleanup(encoder);
184 kfree(mdp5_cmd_enc);
185}
186
187static const struct drm_encoder_funcs mdp5_cmd_encoder_funcs = {
188 .destroy = mdp5_cmd_encoder_destroy,
189};
190
191static void mdp5_cmd_encoder_mode_set(struct drm_encoder *encoder,
192 struct drm_display_mode *mode,
193 struct drm_display_mode *adjusted_mode)
194{ 131{
195 struct mdp5_cmd_encoder *mdp5_cmd_enc = to_mdp5_cmd_encoder(encoder); 132 struct mdp5_encoder *mdp5_cmd_enc = to_mdp5_encoder(encoder);
196 133
197 mode = adjusted_mode; 134 mode = adjusted_mode;
198 135
@@ -209,9 +146,9 @@ static void mdp5_cmd_encoder_mode_set(struct drm_encoder *encoder,
209 mdp5_cmd_enc->ctl); 146 mdp5_cmd_enc->ctl);
210} 147}
211 148
212static void mdp5_cmd_encoder_disable(struct drm_encoder *encoder) 149void mdp5_cmd_encoder_disable(struct drm_encoder *encoder)
213{ 150{
214 struct mdp5_cmd_encoder *mdp5_cmd_enc = to_mdp5_cmd_encoder(encoder); 151 struct mdp5_encoder *mdp5_cmd_enc = to_mdp5_encoder(encoder);
215 struct mdp5_ctl *ctl = mdp5_cmd_enc->ctl; 152 struct mdp5_ctl *ctl = mdp5_cmd_enc->ctl;
216 struct mdp5_interface *intf = &mdp5_cmd_enc->intf; 153 struct mdp5_interface *intf = &mdp5_cmd_enc->intf;
217 154
@@ -228,9 +165,9 @@ static void mdp5_cmd_encoder_disable(struct drm_encoder *encoder)
228 mdp5_cmd_enc->enabled = false; 165 mdp5_cmd_enc->enabled = false;
229} 166}
230 167
231static void mdp5_cmd_encoder_enable(struct drm_encoder *encoder) 168void mdp5_cmd_encoder_enable(struct drm_encoder *encoder)
232{ 169{
233 struct mdp5_cmd_encoder *mdp5_cmd_enc = to_mdp5_cmd_encoder(encoder); 170 struct mdp5_encoder *mdp5_cmd_enc = to_mdp5_encoder(encoder);
234 struct mdp5_ctl *ctl = mdp5_cmd_enc->ctl; 171 struct mdp5_ctl *ctl = mdp5_cmd_enc->ctl;
235 struct mdp5_interface *intf = &mdp5_cmd_enc->intf; 172 struct mdp5_interface *intf = &mdp5_cmd_enc->intf;
236 173
@@ -248,16 +185,10 @@ static void mdp5_cmd_encoder_enable(struct drm_encoder *encoder)
248 mdp5_cmd_enc->enabled = true; 185 mdp5_cmd_enc->enabled = true;
249} 186}
250 187
251static const struct drm_encoder_helper_funcs mdp5_cmd_encoder_helper_funcs = {
252 .mode_set = mdp5_cmd_encoder_mode_set,
253 .disable = mdp5_cmd_encoder_disable,
254 .enable = mdp5_cmd_encoder_enable,
255};
256
257int mdp5_cmd_encoder_set_split_display(struct drm_encoder *encoder, 188int mdp5_cmd_encoder_set_split_display(struct drm_encoder *encoder,
258 struct drm_encoder *slave_encoder) 189 struct drm_encoder *slave_encoder)
259{ 190{
260 struct mdp5_cmd_encoder *mdp5_cmd_enc = to_mdp5_cmd_encoder(encoder); 191 struct mdp5_encoder *mdp5_cmd_enc = to_mdp5_encoder(encoder);
261 struct mdp5_kms *mdp5_kms; 192 struct mdp5_kms *mdp5_kms;
262 int intf_num; 193 int intf_num;
263 u32 data = 0; 194 u32 data = 0;
@@ -292,43 +223,3 @@ int mdp5_cmd_encoder_set_split_display(struct drm_encoder *encoder,
292 223
293 return 0; 224 return 0;
294} 225}
295
296/* initialize command mode encoder */
297struct drm_encoder *mdp5_cmd_encoder_init(struct drm_device *dev,
298 struct mdp5_interface *intf, struct mdp5_ctl *ctl)
299{
300 struct drm_encoder *encoder = NULL;
301 struct mdp5_cmd_encoder *mdp5_cmd_enc;
302 int ret;
303
304 if (WARN_ON((intf->type != INTF_DSI) &&
305 (intf->mode != MDP5_INTF_DSI_MODE_COMMAND))) {
306 ret = -EINVAL;
307 goto fail;
308 }
309
310 mdp5_cmd_enc = kzalloc(sizeof(*mdp5_cmd_enc), GFP_KERNEL);
311 if (!mdp5_cmd_enc) {
312 ret = -ENOMEM;
313 goto fail;
314 }
315
316 memcpy(&mdp5_cmd_enc->intf, intf, sizeof(mdp5_cmd_enc->intf));
317 encoder = &mdp5_cmd_enc->base;
318 mdp5_cmd_enc->ctl = ctl;
319
320 drm_encoder_init(dev, encoder, &mdp5_cmd_encoder_funcs,
321 DRM_MODE_ENCODER_DSI, NULL);
322
323 drm_encoder_helper_add(encoder, &mdp5_cmd_encoder_helper_funcs);
324
325 bs_init(mdp5_cmd_enc);
326
327 return encoder;
328
329fail:
330 if (encoder)
331 mdp5_cmd_encoder_destroy(encoder);
332
333 return ERR_PTR(ret);
334}
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c
index 63f4135c9b5e..80fa482ae8ed 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c
@@ -21,17 +21,6 @@
21#include "drm_crtc.h" 21#include "drm_crtc.h"
22#include "drm_crtc_helper.h" 22#include "drm_crtc_helper.h"
23 23
24struct mdp5_encoder {
25 struct drm_encoder base;
26 struct mdp5_interface intf;
27 spinlock_t intf_lock; /* protect REG_MDP5_INTF_* registers */
28 bool enabled;
29 uint32_t bsc;
30
31 struct mdp5_ctl *ctl;
32};
33#define to_mdp5_encoder(x) container_of(x, struct mdp5_encoder, base)
34
35static struct mdp5_kms *get_kms(struct drm_encoder *encoder) 24static struct mdp5_kms *get_kms(struct drm_encoder *encoder)
36{ 25{
37 struct msm_drm_private *priv = encoder->dev->dev_private; 26 struct msm_drm_private *priv = encoder->dev->dev_private;
@@ -283,17 +272,35 @@ static void mdp5_encoder_mode_set(struct drm_encoder *encoder,
283 struct drm_display_mode *mode, 272 struct drm_display_mode *mode,
284 struct drm_display_mode *adjusted_mode) 273 struct drm_display_mode *adjusted_mode)
285{ 274{
286 mdp5_vid_encoder_mode_set(encoder, mode, adjusted_mode); 275 struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
276 struct mdp5_interface *intf = &mdp5_encoder->intf;
277
278 if (intf->mode == MDP5_INTF_DSI_MODE_COMMAND)
279 mdp5_cmd_encoder_mode_set(encoder, mode, adjusted_mode);
280 else
281 mdp5_vid_encoder_mode_set(encoder, mode, adjusted_mode);
287} 282}
288 283
289static void mdp5_encoder_disable(struct drm_encoder *encoder) 284static void mdp5_encoder_disable(struct drm_encoder *encoder)
290{ 285{
291 mdp5_vid_encoder_disable(encoder); 286 struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
287 struct mdp5_interface *intf = &mdp5_encoder->intf;
288
289 if (intf->mode == MDP5_INTF_DSI_MODE_COMMAND)
290 mdp5_cmd_encoder_disable(encoder);
291 else
292 mdp5_vid_encoder_disable(encoder);
292} 293}
293 294
294static void mdp5_encoder_enable(struct drm_encoder *encoder) 295static void mdp5_encoder_enable(struct drm_encoder *encoder)
295{ 296{
296 mdp5_vid_encoder_enable(encoder); 297 struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
298 struct mdp5_interface *intf = &mdp5_encoder->intf;
299
300 if (intf->mode == MDP5_INTF_DSI_MODE_COMMAND)
301 mdp5_cmd_encoder_disable(encoder);
302 else
303 mdp5_vid_encoder_enable(encoder);
297} 304}
298 305
299static const struct drm_encoder_helper_funcs mdp5_encoder_helper_funcs = { 306static const struct drm_encoder_helper_funcs mdp5_encoder_helper_funcs = {
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
index b85af0f1c79c..9794cad131cd 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
@@ -276,7 +276,7 @@ int mdp5_enable(struct mdp5_kms *mdp5_kms)
276 276
277static struct drm_encoder *construct_encoder(struct mdp5_kms *mdp5_kms, 277static struct drm_encoder *construct_encoder(struct mdp5_kms *mdp5_kms,
278 enum mdp5_intf_type intf_type, int intf_num, 278 enum mdp5_intf_type intf_type, int intf_num,
279 enum mdp5_intf_mode intf_mode, struct mdp5_ctl *ctl) 279 struct mdp5_ctl *ctl)
280{ 280{
281 struct drm_device *dev = mdp5_kms->dev; 281 struct drm_device *dev = mdp5_kms->dev;
282 struct msm_drm_private *priv = dev->dev_private; 282 struct msm_drm_private *priv = dev->dev_private;
@@ -284,15 +284,10 @@ static struct drm_encoder *construct_encoder(struct mdp5_kms *mdp5_kms,
284 struct mdp5_interface intf = { 284 struct mdp5_interface intf = {
285 .num = intf_num, 285 .num = intf_num,
286 .type = intf_type, 286 .type = intf_type,
287 .mode = intf_mode, 287 .mode = MDP5_INTF_MODE_NONE,
288 }; 288 };
289 289
290 if ((intf_type == INTF_DSI) && 290 encoder = mdp5_encoder_init(dev, &intf, ctl);
291 (intf_mode == MDP5_INTF_DSI_MODE_COMMAND))
292 encoder = mdp5_cmd_encoder_init(dev, &intf, ctl);
293 else
294 encoder = mdp5_encoder_init(dev, &intf, ctl);
295
296 if (IS_ERR(encoder)) { 291 if (IS_ERR(encoder)) {
297 dev_err(dev->dev, "failed to construct encoder\n"); 292 dev_err(dev->dev, "failed to construct encoder\n");
298 return encoder; 293 return encoder;
@@ -347,8 +342,7 @@ static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num)
347 break; 342 break;
348 } 343 }
349 344
350 encoder = construct_encoder(mdp5_kms, INTF_eDP, intf_num, 345 encoder = construct_encoder(mdp5_kms, INTF_eDP, intf_num, ctl);
351 MDP5_INTF_MODE_NONE, ctl);
352 if (IS_ERR(encoder)) { 346 if (IS_ERR(encoder)) {
353 ret = PTR_ERR(encoder); 347 ret = PTR_ERR(encoder);
354 break; 348 break;
@@ -366,8 +360,7 @@ static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num)
366 break; 360 break;
367 } 361 }
368 362
369 encoder = construct_encoder(mdp5_kms, INTF_HDMI, intf_num, 363 encoder = construct_encoder(mdp5_kms, INTF_HDMI, intf_num, ctl);
370 MDP5_INTF_MODE_NONE, ctl);
371 if (IS_ERR(encoder)) { 364 if (IS_ERR(encoder)) {
372 ret = PTR_ERR(encoder); 365 ret = PTR_ERR(encoder);
373 break; 366 break;
@@ -395,8 +388,7 @@ static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num)
395 break; 388 break;
396 } 389 }
397 390
398 encoder = construct_encoder(mdp5_kms, INTF_DSI, intf_num, 391 encoder = construct_encoder(mdp5_kms, INTF_DSI, intf_num, ctl);
399 MDP5_INTF_DSI_MODE_VIDEO, ctl);
400 if (IS_ERR(encoder)) { 392 if (IS_ERR(encoder)) {
401 ret = PTR_ERR(encoder); 393 ret = PTR_ERR(encoder);
402 break; 394 break;
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
index f2419666c43e..40ebc5c50875 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
@@ -126,6 +126,17 @@ struct mdp5_interface {
126 enum mdp5_intf_mode mode; 126 enum mdp5_intf_mode mode;
127}; 127};
128 128
129struct mdp5_encoder {
130 struct drm_encoder base;
131 struct mdp5_interface intf;
132 spinlock_t intf_lock; /* protect REG_MDP5_INTF_* registers */
133 bool enabled;
134 uint32_t bsc;
135
136 struct mdp5_ctl *ctl;
137};
138#define to_mdp5_encoder(x) container_of(x, struct mdp5_encoder, base)
139
129static inline void mdp5_write(struct mdp5_kms *mdp5_kms, u32 reg, u32 data) 140static inline void mdp5_write(struct mdp5_kms *mdp5_kms, u32 reg, u32 data)
130{ 141{
131 msm_writel(data, mdp5_kms->mmio + reg); 142 msm_writel(data, mdp5_kms->mmio + reg);
@@ -251,15 +262,24 @@ int mdp5_encoder_get_linecount(struct drm_encoder *encoder);
251u32 mdp5_encoder_get_framecount(struct drm_encoder *encoder); 262u32 mdp5_encoder_get_framecount(struct drm_encoder *encoder);
252 263
253#ifdef CONFIG_DRM_MSM_DSI 264#ifdef CONFIG_DRM_MSM_DSI
254struct drm_encoder *mdp5_cmd_encoder_init(struct drm_device *dev, 265void mdp5_cmd_encoder_mode_set(struct drm_encoder *encoder,
255 struct mdp5_interface *intf, struct mdp5_ctl *ctl); 266 struct drm_display_mode *mode,
267 struct drm_display_mode *adjusted_mode);
268void mdp5_cmd_encoder_disable(struct drm_encoder *encoder);
269void mdp5_cmd_encoder_enable(struct drm_encoder *encoder);
256int mdp5_cmd_encoder_set_split_display(struct drm_encoder *encoder, 270int mdp5_cmd_encoder_set_split_display(struct drm_encoder *encoder,
257 struct drm_encoder *slave_encoder); 271 struct drm_encoder *slave_encoder);
258#else 272#else
259static inline struct drm_encoder *mdp5_cmd_encoder_init(struct drm_device *dev, 273static inline void mdp5_cmd_encoder_mode_set(struct drm_encoder *encoder,
260 struct mdp5_interface *intf, struct mdp5_ctl *ctl) 274 struct drm_display_mode *mode,
275 struct drm_display_mode *adjusted_mode)
276{
277}
278static inline void mdp5_cmd_encoder_disable(struct drm_encoder *encoder)
279{
280}
281static inline void mdp5_cmd_encoder_enable(struct drm_encoder *encoder)
261{ 282{
262 return ERR_PTR(-EINVAL);
263} 283}
264static inline int mdp5_cmd_encoder_set_split_display( 284static inline int mdp5_cmd_encoder_set_split_display(
265 struct drm_encoder *encoder, struct drm_encoder *slave_encoder) 285 struct drm_encoder *encoder, struct drm_encoder *slave_encoder)