GNU Linux-libre 4.4.299-gnu1
[releases.git] / drivers / gpu / drm / msm / mdp / mdp5 / mdp5_cmd_encoder.c
1 /*
2  * Copyright (c) 2015, The Linux Foundation. All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 and
6  * only version 2 as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  */
13
14 #include "mdp5_kms.h"
15
16 #include "drm_crtc.h"
17 #include "drm_crtc_helper.h"
18
19 struct 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
29 static struct mdp5_kms *get_kms(struct drm_encoder *encoder)
30 {
31         struct msm_drm_private *priv = encoder->dev->dev_private;
32         return to_mdp5_kms(to_mdp_kms(priv->kms));
33 }
34
35 #ifdef DOWNSTREAM_CONFIG_MSM_BUS_SCALING
36 #include <mach/board.h>
37 #include <linux/msm-bus.h>
38 #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
47 static struct msm_bus_vectors mdp_bus_vectors[] = {
48         MDP_BUS_VECTOR_ENTRY(0, 0),
49         MDP_BUS_VECTOR_ENTRY(2000000000, 2000000000),
50 };
51 static 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 } };
58 static 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
64 static 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
71 static 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
79 static void bs_set(struct mdp5_cmd_encoder *mdp5_cmd_enc, int idx)
80 {
81         if (mdp5_cmd_enc->bsc) {
82                 DBG("set bus scaling: %d", idx);
83                 /* HACK: scaling down, and then immediately back up
84                  * seems to leave things broken (underflow).. so
85                  * never disable:
86                  */
87                 idx = 1;
88                 msm_bus_scale_client_update_request(mdp5_cmd_enc->bsc, idx);
89         }
90 }
91 #else
92 static void bs_init(struct mdp5_cmd_encoder *mdp5_cmd_enc) {}
93 static void bs_fini(struct mdp5_cmd_encoder *mdp5_cmd_enc) {}
94 static void bs_set(struct mdp5_cmd_encoder *mdp5_cmd_enc, int idx) {}
95 #endif
96
97 #define VSYNC_CLK_RATE 19200000
98 static int pingpong_tearcheck_setup(struct drm_encoder *encoder,
99                                         struct drm_display_mode *mode)
100 {
101         struct mdp5_kms *mdp5_kms = get_kms(encoder);
102         struct device *dev = encoder->dev->dev;
103         u32 total_lines_x100, vclks_line, cfg;
104         long vsync_clk_speed;
105         int pp_id = GET_PING_PONG_ID(mdp5_crtc_get_lm(encoder->crtc));
106
107         if (IS_ERR_OR_NULL(mdp5_kms->vsync_clk)) {
108                 dev_err(dev, "vsync_clk is not initialized\n");
109                 return -EINVAL;
110         }
111
112         total_lines_x100 = mode->vtotal * mode->vrefresh;
113         if (!total_lines_x100) {
114                 dev_err(dev, "%s: vtotal(%d) or vrefresh(%d) is 0\n",
115                                 __func__, mode->vtotal, mode->vrefresh);
116                 return -EINVAL;
117         }
118
119         vsync_clk_speed = clk_round_rate(mdp5_kms->vsync_clk, VSYNC_CLK_RATE);
120         if (vsync_clk_speed <= 0) {
121                 dev_err(dev, "vsync_clk round rate failed %ld\n",
122                                                         vsync_clk_speed);
123                 return -EINVAL;
124         }
125         vclks_line = vsync_clk_speed * 100 / total_lines_x100;
126
127         cfg = MDP5_PP_SYNC_CONFIG_VSYNC_COUNTER_EN
128                 | MDP5_PP_SYNC_CONFIG_VSYNC_IN_EN;
129         cfg |= MDP5_PP_SYNC_CONFIG_VSYNC_COUNT(vclks_line);
130
131         /*
132          * Tearcheck emits a blanking signal every vclks_line * vtotal * 2 ticks on
133          * the vsync_clk equating to roughly half the desired panel refresh rate.
134          * This is only necessary as stability fallback if interrupts from the
135          * panel arrive too late or not at all, but is currently used by default
136          * because these panel interrupts are not wired up yet.
137          */
138         mdp5_write(mdp5_kms, REG_MDP5_PP_SYNC_CONFIG_VSYNC(pp_id), cfg);
139         mdp5_write(mdp5_kms,
140                 REG_MDP5_PP_SYNC_CONFIG_HEIGHT(pp_id), (2 * mode->vtotal));
141
142         mdp5_write(mdp5_kms,
143                 REG_MDP5_PP_VSYNC_INIT_VAL(pp_id), mode->vdisplay);
144         mdp5_write(mdp5_kms, REG_MDP5_PP_RD_PTR_IRQ(pp_id), mode->vdisplay + 1);
145         mdp5_write(mdp5_kms, REG_MDP5_PP_START_POS(pp_id), mode->vdisplay);
146         mdp5_write(mdp5_kms, REG_MDP5_PP_SYNC_THRESH(pp_id),
147                         MDP5_PP_SYNC_THRESH_START(4) |
148                         MDP5_PP_SYNC_THRESH_CONTINUE(4));
149
150         return 0;
151 }
152
153 static int pingpong_tearcheck_enable(struct drm_encoder *encoder)
154 {
155         struct mdp5_kms *mdp5_kms = get_kms(encoder);
156         int pp_id = GET_PING_PONG_ID(mdp5_crtc_get_lm(encoder->crtc));
157         int ret;
158
159         ret = clk_set_rate(mdp5_kms->vsync_clk,
160                 clk_round_rate(mdp5_kms->vsync_clk, VSYNC_CLK_RATE));
161         if (ret) {
162                 dev_err(encoder->dev->dev,
163                         "vsync_clk clk_set_rate failed, %d\n", ret);
164                 return ret;
165         }
166         ret = clk_prepare_enable(mdp5_kms->vsync_clk);
167         if (ret) {
168                 dev_err(encoder->dev->dev,
169                         "vsync_clk clk_prepare_enable failed, %d\n", ret);
170                 return ret;
171         }
172
173         mdp5_write(mdp5_kms, REG_MDP5_PP_TEAR_CHECK_EN(pp_id), 1);
174
175         return 0;
176 }
177
178 static void pingpong_tearcheck_disable(struct drm_encoder *encoder)
179 {
180         struct mdp5_kms *mdp5_kms = get_kms(encoder);
181         int pp_id = GET_PING_PONG_ID(mdp5_crtc_get_lm(encoder->crtc));
182
183         mdp5_write(mdp5_kms, REG_MDP5_PP_TEAR_CHECK_EN(pp_id), 0);
184         clk_disable_unprepare(mdp5_kms->vsync_clk);
185 }
186
187 static void mdp5_cmd_encoder_destroy(struct drm_encoder *encoder)
188 {
189         struct mdp5_cmd_encoder *mdp5_cmd_enc = to_mdp5_cmd_encoder(encoder);
190         bs_fini(mdp5_cmd_enc);
191         drm_encoder_cleanup(encoder);
192         kfree(mdp5_cmd_enc);
193 }
194
195 static const struct drm_encoder_funcs mdp5_cmd_encoder_funcs = {
196         .destroy = mdp5_cmd_encoder_destroy,
197 };
198
199 static bool mdp5_cmd_encoder_mode_fixup(struct drm_encoder *encoder,
200                 const struct drm_display_mode *mode,
201                 struct drm_display_mode *adjusted_mode)
202 {
203         return true;
204 }
205
206 static void mdp5_cmd_encoder_mode_set(struct drm_encoder *encoder,
207                 struct drm_display_mode *mode,
208                 struct drm_display_mode *adjusted_mode)
209 {
210         struct mdp5_cmd_encoder *mdp5_cmd_enc = to_mdp5_cmd_encoder(encoder);
211
212         mode = adjusted_mode;
213
214         DBG("set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x",
215                         mode->base.id, mode->name,
216                         mode->vrefresh, mode->clock,
217                         mode->hdisplay, mode->hsync_start,
218                         mode->hsync_end, mode->htotal,
219                         mode->vdisplay, mode->vsync_start,
220                         mode->vsync_end, mode->vtotal,
221                         mode->type, mode->flags);
222         pingpong_tearcheck_setup(encoder, mode);
223         mdp5_crtc_set_pipeline(encoder->crtc, &mdp5_cmd_enc->intf,
224                                 mdp5_cmd_enc->ctl);
225 }
226
227 static void mdp5_cmd_encoder_disable(struct drm_encoder *encoder)
228 {
229         struct mdp5_cmd_encoder *mdp5_cmd_enc = to_mdp5_cmd_encoder(encoder);
230         struct mdp5_ctl *ctl = mdp5_cmd_enc->ctl;
231         struct mdp5_interface *intf = &mdp5_cmd_enc->intf;
232
233         if (WARN_ON(!mdp5_cmd_enc->enabled))
234                 return;
235
236         pingpong_tearcheck_disable(encoder);
237
238         mdp5_ctl_set_encoder_state(ctl, false);
239         mdp5_ctl_commit(ctl, mdp_ctl_flush_mask_encoder(intf));
240
241         bs_set(mdp5_cmd_enc, 0);
242
243         mdp5_cmd_enc->enabled = false;
244 }
245
246 static void mdp5_cmd_encoder_enable(struct drm_encoder *encoder)
247 {
248         struct mdp5_cmd_encoder *mdp5_cmd_enc = to_mdp5_cmd_encoder(encoder);
249         struct mdp5_ctl *ctl = mdp5_cmd_enc->ctl;
250         struct mdp5_interface *intf = &mdp5_cmd_enc->intf;
251
252         if (WARN_ON(mdp5_cmd_enc->enabled))
253                 return;
254
255         bs_set(mdp5_cmd_enc, 1);
256         if (pingpong_tearcheck_enable(encoder))
257                 return;
258
259         mdp5_ctl_commit(ctl, mdp_ctl_flush_mask_encoder(intf));
260
261         mdp5_ctl_set_encoder_state(ctl, true);
262
263         mdp5_cmd_enc->enabled = true;
264 }
265
266 static const struct drm_encoder_helper_funcs mdp5_cmd_encoder_helper_funcs = {
267         .mode_fixup = mdp5_cmd_encoder_mode_fixup,
268         .mode_set = mdp5_cmd_encoder_mode_set,
269         .disable = mdp5_cmd_encoder_disable,
270         .enable = mdp5_cmd_encoder_enable,
271 };
272
273 int mdp5_cmd_encoder_set_split_display(struct drm_encoder *encoder,
274                                         struct drm_encoder *slave_encoder)
275 {
276         struct mdp5_cmd_encoder *mdp5_cmd_enc = to_mdp5_cmd_encoder(encoder);
277         struct mdp5_kms *mdp5_kms;
278         int intf_num;
279         u32 data = 0;
280
281         if (!encoder || !slave_encoder)
282                 return -EINVAL;
283
284         mdp5_kms = get_kms(encoder);
285         intf_num = mdp5_cmd_enc->intf.num;
286
287         /* Switch slave encoder's trigger MUX, to use the master's
288          * start signal for the slave encoder
289          */
290         if (intf_num == 1)
291                 data |= MDP5_MDP_SPLIT_DPL_UPPER_INTF2_SW_TRG_MUX;
292         else if (intf_num == 2)
293                 data |= MDP5_MDP_SPLIT_DPL_UPPER_INTF1_SW_TRG_MUX;
294         else
295                 return -EINVAL;
296
297         /* Smart Panel, Sync mode */
298         data |= MDP5_MDP_SPLIT_DPL_UPPER_SMART_PANEL;
299
300         /* Make sure clocks are on when connectors calling this function. */
301         mdp5_enable(mdp5_kms);
302         mdp5_write(mdp5_kms, REG_MDP5_MDP_SPLIT_DPL_UPPER(0), data);
303
304         mdp5_write(mdp5_kms, REG_MDP5_MDP_SPLIT_DPL_LOWER(0),
305                         MDP5_MDP_SPLIT_DPL_LOWER_SMART_PANEL);
306         mdp5_write(mdp5_kms, REG_MDP5_MDP_SPLIT_DPL_EN(0), 1);
307         mdp5_disable(mdp5_kms);
308
309         return 0;
310 }
311
312 /* initialize command mode encoder */
313 struct drm_encoder *mdp5_cmd_encoder_init(struct drm_device *dev,
314                         struct mdp5_interface *intf, struct mdp5_ctl *ctl)
315 {
316         struct drm_encoder *encoder = NULL;
317         struct mdp5_cmd_encoder *mdp5_cmd_enc;
318         int ret;
319
320         if (WARN_ON((intf->type != INTF_DSI) &&
321                 (intf->mode != MDP5_INTF_DSI_MODE_COMMAND))) {
322                 ret = -EINVAL;
323                 goto fail;
324         }
325
326         mdp5_cmd_enc = kzalloc(sizeof(*mdp5_cmd_enc), GFP_KERNEL);
327         if (!mdp5_cmd_enc) {
328                 ret = -ENOMEM;
329                 goto fail;
330         }
331
332         memcpy(&mdp5_cmd_enc->intf, intf, sizeof(mdp5_cmd_enc->intf));
333         encoder = &mdp5_cmd_enc->base;
334         mdp5_cmd_enc->ctl = ctl;
335
336         drm_encoder_init(dev, encoder, &mdp5_cmd_encoder_funcs,
337                         DRM_MODE_ENCODER_DSI);
338
339         drm_encoder_helper_add(encoder, &mdp5_cmd_encoder_helper_funcs);
340
341         bs_init(mdp5_cmd_enc);
342
343         return encoder;
344
345 fail:
346         if (encoder)
347                 mdp5_cmd_encoder_destroy(encoder);
348
349         return ERR_PTR(ret);
350 }
351