blob: 68d09c60907c2210fc4f30ea37ac719e5363421b [file] [log] [blame]
Adrian Salido-Moreno5c150382016-04-06 09:29:37 -07001/* Copyright (c) 2012, 2015-2016, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13#define pr_fmt(fmt) "%s: " fmt, __func__
14
15#include <linux/errno.h>
16#include <linux/file.h>
17#include <linux/spinlock.h>
18#include <linux/types.h>
19#include <linux/major.h>
20#include <linux/debugfs.h>
21#include <linux/clk.h>
22#include <linux/slab.h>
23#include <linux/io.h>
24#include <linux/iopoll.h>
25#include <linux/msm-bus.h>
26#include <linux/msm-bus-board.h>
27#include <linux/regulator/consumer.h>
28
29#define CREATE_TRACE_POINTS
30#include "sde_rotator_base.h"
31#include "sde_rotator_util.h"
32#include "sde_rotator_trace.h"
33
34static inline u64 fudge_factor(u64 val, u32 numer, u32 denom)
35{
36 u64 result = (val * (u64)numer);
37
38 do_div(result, denom);
39 return result;
40}
41
42static inline u64 apply_fudge_factor(u64 val,
43 struct sde_mult_factor *factor)
44{
45 return fudge_factor(val, factor->numer, factor->denom);
46}
47
48static inline u64 apply_inverse_fudge_factor(u64 val,
49 struct sde_mult_factor *factor)
50{
51 return fudge_factor(val, factor->denom, factor->numer);
52}
53
54static inline bool validate_comp_ratio(struct sde_mult_factor *factor)
55{
56 return factor->numer && factor->denom;
57}
58
59u32 sde_apply_comp_ratio_factor(u32 quota,
60 struct sde_mdp_format_params *fmt,
61 struct sde_mult_factor *factor)
62{
63 struct sde_rot_data_type *mdata = sde_rot_get_mdata();
64
65 if (!mdata || !test_bit(SDE_QOS_OVERHEAD_FACTOR,
66 mdata->sde_qos_map))
67 return quota;
68
69 /* apply compression ratio, only for compressed formats */
70 if (sde_mdp_is_ubwc_format(fmt) &&
71 validate_comp_ratio(factor))
72 quota = apply_inverse_fudge_factor(quota, factor);
73
74 return quota;
75}
76
77#define RES_1080p (1088*1920)
78#define RES_UHD (3840*2160)
79#define XIN_HALT_TIMEOUT_US 0x4000
80
81static int sde_mdp_wait_for_xin_halt(u32 xin_id)
82{
83 void __iomem *vbif_base;
84 u32 status;
85 struct sde_rot_data_type *mdata = sde_rot_get_mdata();
86 u32 idle_mask = BIT(xin_id);
87 int rc;
88
89 vbif_base = mdata->vbif_nrt_io.base;
90
91 rc = readl_poll_timeout(vbif_base + MMSS_VBIF_XIN_HALT_CTRL1,
92 status, (status & idle_mask),
93 1000, XIN_HALT_TIMEOUT_US);
94 if (rc == -ETIMEDOUT) {
95 SDEROT_ERR("VBIF client %d not halting. TIMEDOUT.\n",
96 xin_id);
97 } else {
98 SDEROT_DBG("VBIF client %d is halted\n", xin_id);
99 }
100
101 return rc;
102}
103
104/**
105 * force_on_xin_clk() - enable/disable the force-on for the pipe clock
106 * @bit_off: offset of the bit to enable/disable the force-on.
107 * @reg_off: register offset for the clock control.
108 * @enable: boolean to indicate if the force-on of the clock needs to be
109 * enabled or disabled.
110 *
111 * This function returns:
112 * true - if the clock is forced-on by this function
113 * false - if the clock was already forced on
114 * It is the caller responsibility to check if this function is forcing
115 * the clock on; if so, it will need to remove the force of the clock,
116 * otherwise it should avoid to remove the force-on.
117 * Clocks must be on when calling this function.
118 */
119static bool force_on_xin_clk(u32 bit_off, u32 clk_ctl_reg_off, bool enable)
120{
121 u32 val;
122 u32 force_on_mask;
123 struct sde_rot_data_type *mdata = sde_rot_get_mdata();
124 bool clk_forced_on = false;
125
126 force_on_mask = BIT(bit_off);
127 val = readl_relaxed(mdata->mdp_base + clk_ctl_reg_off);
128
129 clk_forced_on = !(force_on_mask & val);
130
131 if (true == enable)
132 val |= force_on_mask;
133 else
134 val &= ~force_on_mask;
135
136 writel_relaxed(val, mdata->mdp_base + clk_ctl_reg_off);
137
138 return clk_forced_on;
139}
140
Alan Kwongeffb5ee2016-03-12 19:47:45 -0500141u32 sde_mdp_get_ot_limit(u32 width, u32 height, u32 pixfmt, u32 fps, u32 is_rd)
Adrian Salido-Moreno5c150382016-04-06 09:29:37 -0700142{
143 struct sde_rot_data_type *mdata = sde_rot_get_mdata();
Alan Kwongeffb5ee2016-03-12 19:47:45 -0500144 struct sde_mdp_format_params *fmt;
145 u32 ot_lim;
146 u32 is_yuv;
Adrian Salido-Moreno5c150382016-04-06 09:29:37 -0700147 u32 res;
148
Alan Kwongeffb5ee2016-03-12 19:47:45 -0500149 ot_lim = (is_rd) ? mdata->default_ot_rd_limit :
150 mdata->default_ot_wr_limit;
Adrian Salido-Moreno5c150382016-04-06 09:29:37 -0700151
152 /*
153 * If default ot is not set from dt,
154 * then do not configure it.
155 */
156 if (ot_lim == 0)
157 goto exit;
158
159 /* Modify the limits if the target and the use case requires it */
Alan Kwongeffb5ee2016-03-12 19:47:45 -0500160 if (false == test_bit(SDE_QOS_OTLIM, mdata->sde_qos_map))
161 goto exit;
162
163 res = width * height;
164
165 fmt = sde_get_format_params(pixfmt);
166
167 if (!fmt) {
168 SDEROT_WARN("invalid format %8.8x\n", pixfmt);
169 goto exit;
170 }
171
172 is_yuv = sde_mdp_is_yuv_format(fmt);
173
174 SDEROT_DBG("w:%d h:%d fps:%d pixfmt:%8.8x yuv:%d res:%d rd:%d\n",
175 width, height, fps, pixfmt, is_yuv, res, is_rd);
176
177 if (!is_yuv)
178 goto exit;
179
180 if ((res <= RES_1080p) && (fps <= 30))
181 ot_lim = 2;
182 else if ((res <= RES_1080p) && (fps <= 60))
183 ot_lim = 4;
184 else if ((res <= RES_UHD) && (fps <= 30))
185 ot_lim = 8;
186
187exit:
188 SDEROT_DBG("ot_lim=%d\n", ot_lim);
189 return ot_lim;
190}
191
192static u32 get_ot_limit(u32 reg_off, u32 bit_off,
193 struct sde_mdp_set_ot_params *params)
194{
195 struct sde_rot_data_type *mdata = sde_rot_get_mdata();
196 u32 ot_lim;
197 u32 val;
198
199 ot_lim = sde_mdp_get_ot_limit(
200 params->width, params->height,
201 params->fmt, params->fps,
202 params->reg_off_vbif_lim_conf == MMSS_VBIF_RD_LIM_CONF);
203
204 /*
205 * If default ot is not set from dt,
206 * then do not configure it.
207 */
208 if (ot_lim == 0)
209 goto exit;
Adrian Salido-Moreno5c150382016-04-06 09:29:37 -0700210
211 val = SDE_VBIF_READ(mdata, reg_off);
212 val &= (0xFF << bit_off);
213 val = val >> bit_off;
214
215 if (val == ot_lim)
216 ot_lim = 0;
217
218exit:
219 SDEROT_DBG("ot_lim=%d\n", ot_lim);
220 return ot_lim;
221}
222
223void sde_mdp_set_ot_limit(struct sde_mdp_set_ot_params *params)
224{
225 struct sde_rot_data_type *mdata = sde_rot_get_mdata();
226 u32 ot_lim;
227 u32 reg_off_vbif_lim_conf = (params->xin_id / 4) * 4 +
228 params->reg_off_vbif_lim_conf;
229 u32 bit_off_vbif_lim_conf = (params->xin_id % 4) * 8;
230 u32 reg_val;
231 bool forced_on;
232
233 ot_lim = get_ot_limit(
234 reg_off_vbif_lim_conf,
235 bit_off_vbif_lim_conf,
236 params) & 0xFF;
237
238 if (ot_lim == 0)
239 goto exit;
240
241 trace_rot_perf_set_ot(params->num, params->xin_id, ot_lim);
242
243 forced_on = force_on_xin_clk(params->bit_off_mdp_clk_ctrl,
244 params->reg_off_mdp_clk_ctrl, true);
245
246 reg_val = SDE_VBIF_READ(mdata, reg_off_vbif_lim_conf);
247 reg_val &= ~(0xFF << bit_off_vbif_lim_conf);
248 reg_val |= (ot_lim) << bit_off_vbif_lim_conf;
249 SDE_VBIF_WRITE(mdata, reg_off_vbif_lim_conf, reg_val);
250
251 reg_val = SDE_VBIF_READ(mdata, MMSS_VBIF_XIN_HALT_CTRL0);
252 SDE_VBIF_WRITE(mdata, MMSS_VBIF_XIN_HALT_CTRL0,
253 reg_val | BIT(params->xin_id));
254
255 /* this is a polling operation */
256 sde_mdp_wait_for_xin_halt(params->xin_id);
257
258 reg_val = SDE_VBIF_READ(mdata, MMSS_VBIF_XIN_HALT_CTRL0);
259 SDE_VBIF_WRITE(mdata, MMSS_VBIF_XIN_HALT_CTRL0,
260 reg_val & ~BIT(params->xin_id));
261
262 if (forced_on)
263 force_on_xin_clk(params->bit_off_mdp_clk_ctrl,
264 params->reg_off_mdp_clk_ctrl, false);
265
266exit:
267 return;
268}
269
270struct reg_bus_client *sde_reg_bus_vote_client_create(char *client_name)
271{
272 struct reg_bus_client *client;
273 struct sde_rot_data_type *sde_res = sde_rot_get_mdata();
274 static u32 id;
275
276 if (client_name == NULL) {
277 SDEROT_ERR("client name is null\n");
278 return ERR_PTR(-EINVAL);
279 }
280
281 client = kzalloc(sizeof(struct reg_bus_client), GFP_KERNEL);
282 if (!client)
283 return ERR_PTR(-ENOMEM);
284
285 mutex_lock(&sde_res->reg_bus_lock);
286 strlcpy(client->name, client_name, MAX_CLIENT_NAME_LEN);
287 client->usecase_ndx = VOTE_INDEX_DISABLE;
288 client->id = id;
289 SDEROT_DBG("bus vote client %s created:%p id :%d\n", client_name,
290 client, id);
291 id++;
292 list_add(&client->list, &sde_res->reg_bus_clist);
293 mutex_unlock(&sde_res->reg_bus_lock);
294
295 return client;
296}
297
298void sde_reg_bus_vote_client_destroy(struct reg_bus_client *client)
299{
300 struct sde_rot_data_type *sde_res = sde_rot_get_mdata();
301
302 if (!client) {
303 SDEROT_ERR("reg bus vote: invalid client handle\n");
304 } else {
305 SDEROT_DBG("bus vote client %s destroyed:%p id:%u\n",
306 client->name, client, client->id);
307 mutex_lock(&sde_res->reg_bus_lock);
308 list_del_init(&client->list);
309 mutex_unlock(&sde_res->reg_bus_lock);
310 kfree(client);
311 }
312}
313
314int sde_update_reg_bus_vote(struct reg_bus_client *bus_client, u32 usecase_ndx)
315{
316 int ret = 0;
317 bool changed = false;
318 u32 max_usecase_ndx = VOTE_INDEX_DISABLE;
319 struct reg_bus_client *client, *temp_client;
320 struct sde_rot_data_type *sde_res = sde_rot_get_mdata();
321
322 if (!sde_res || !sde_res->reg_bus_hdl || !bus_client)
323 return 0;
324
325 mutex_lock(&sde_res->reg_bus_lock);
326 bus_client->usecase_ndx = usecase_ndx;
327 list_for_each_entry_safe(client, temp_client, &sde_res->reg_bus_clist,
328 list) {
329
330 if (client->usecase_ndx < VOTE_INDEX_MAX &&
331 client->usecase_ndx > max_usecase_ndx)
332 max_usecase_ndx = client->usecase_ndx;
333 }
334
335 if (sde_res->reg_bus_usecase_ndx != max_usecase_ndx) {
336 changed = true;
337 sde_res->reg_bus_usecase_ndx = max_usecase_ndx;
338 }
339
340 SDEROT_DBG(
341 "%pS: changed=%d current idx=%d request client %s id:%u idx:%d\n",
342 __builtin_return_address(0), changed, max_usecase_ndx,
343 bus_client->name, bus_client->id, usecase_ndx);
344 if (changed)
345 ret = msm_bus_scale_client_update_request(sde_res->reg_bus_hdl,
346 max_usecase_ndx);
347
348 mutex_unlock(&sde_res->reg_bus_lock);
349 return ret;
350}
351
352static int sde_mdp_parse_dt_handler(struct platform_device *pdev,
353 char *prop_name, u32 *offsets, int len)
354{
355 int rc;
356
357 rc = of_property_read_u32_array(pdev->dev.of_node, prop_name,
358 offsets, len);
359 if (rc) {
360 SDEROT_ERR("Error from prop %s : u32 array read\n", prop_name);
361 return -EINVAL;
362 }
363
364 return 0;
365}
366
367static int sde_mdp_parse_dt_prop_len(struct platform_device *pdev,
368 char *prop_name)
369{
370 int len = 0;
371
372 of_find_property(pdev->dev.of_node, prop_name, &len);
373
374 if (len < 1) {
375 SDEROT_INFO("prop %s : doesn't exist in device tree\n",
376 prop_name);
377 return 0;
378 }
379
380 len = len/sizeof(u32);
381
382 return len;
383}
384
385static void sde_mdp_parse_vbif_qos(struct platform_device *pdev,
386 struct sde_rot_data_type *mdata)
387{
388 int rc;
389
390 mdata->vbif_rt_qos = NULL;
391
392 mdata->npriority_lvl = sde_mdp_parse_dt_prop_len(pdev,
393 "qcom,mdss-rot-vbif-qos-setting");
394 mdata->vbif_nrt_qos = kzalloc(sizeof(u32) *
395 mdata->npriority_lvl, GFP_KERNEL);
396 if (!mdata->vbif_nrt_qos)
397 return;
398
399 rc = sde_mdp_parse_dt_handler(pdev,
400 "qcom,mdss-rot-vbif-qos-setting", mdata->vbif_nrt_qos,
401 mdata->npriority_lvl);
402 if (rc) {
403 SDEROT_DBG("vbif setting not found\n");
404 return;
405 }
406}
407
408static int sde_mdp_parse_dt_misc(struct platform_device *pdev,
409 struct sde_rot_data_type *mdata)
410{
411 int rc;
412 u32 data;
413
414 rc = of_property_read_u32(pdev->dev.of_node, "qcom,mdss-rot-block-size",
415 &data);
416 mdata->rot_block_size = (!rc ? data : 128);
417
418 rc = of_property_read_u32(pdev->dev.of_node,
419 "qcom,mdss-default-ot-rd-limit", &data);
420 mdata->default_ot_rd_limit = (!rc ? data : 0);
421
422 rc = of_property_read_u32(pdev->dev.of_node,
423 "qcom,mdss-default-ot-wr-limit", &data);
424 mdata->default_ot_wr_limit = (!rc ? data : 0);
425
426 rc = of_property_read_u32(pdev->dev.of_node,
427 "qcom,mdss-highest-bank-bit", &(mdata->highest_bank_bit));
428 if (rc)
429 SDEROT_DBG(
430 "Could not read optional property: highest bank bit\n");
431
432 sde_mdp_parse_vbif_qos(pdev, mdata);
433
434 mdata->mdp_base = mdata->sde_io.base + SDE_MDP_OFFSET;
435
436 return 0;
437}
438
439#define MDP_REG_BUS_VECTOR_ENTRY(ab_val, ib_val) \
440 { \
441 .src = MSM_BUS_MASTER_AMPSS_M0, \
442 .dst = MSM_BUS_SLAVE_DISPLAY_CFG, \
443 .ab = (ab_val), \
444 .ib = (ib_val), \
445 }
446
447#define BUS_VOTE_19_MHZ 153600000
448#define BUS_VOTE_40_MHZ 320000000
449#define BUS_VOTE_80_MHZ 640000000
450
451static struct msm_bus_vectors mdp_reg_bus_vectors[] = {
452 MDP_REG_BUS_VECTOR_ENTRY(0, 0),
453 MDP_REG_BUS_VECTOR_ENTRY(0, BUS_VOTE_19_MHZ),
454 MDP_REG_BUS_VECTOR_ENTRY(0, BUS_VOTE_40_MHZ),
455 MDP_REG_BUS_VECTOR_ENTRY(0, BUS_VOTE_80_MHZ),
456};
457static struct msm_bus_paths mdp_reg_bus_usecases[ARRAY_SIZE(
458 mdp_reg_bus_vectors)];
459static struct msm_bus_scale_pdata mdp_reg_bus_scale_table = {
460 .usecase = mdp_reg_bus_usecases,
461 .num_usecases = ARRAY_SIZE(mdp_reg_bus_usecases),
462 .name = "sde_reg",
463 .active_only = true,
464};
465
466static int sde_mdp_bus_scale_register(struct sde_rot_data_type *mdata)
467{
468 struct msm_bus_scale_pdata *reg_bus_pdata;
469 int i;
470
471 if (!mdata->reg_bus_hdl) {
472 reg_bus_pdata = &mdp_reg_bus_scale_table;
473 for (i = 0; i < reg_bus_pdata->num_usecases; i++) {
474 mdp_reg_bus_usecases[i].num_paths = 1;
475 mdp_reg_bus_usecases[i].vectors =
476 &mdp_reg_bus_vectors[i];
477 }
478
479 mdata->reg_bus_hdl =
480 msm_bus_scale_register_client(reg_bus_pdata);
481 if (!mdata->reg_bus_hdl) {
482 /* Continue without reg_bus scaling */
483 SDEROT_WARN("reg_bus_client register failed\n");
484 } else
485 SDEROT_DBG("register reg_bus_hdl=%x\n",
486 mdata->reg_bus_hdl);
487 }
488
489 return 0;
490}
491
492static void sde_mdp_bus_scale_unregister(struct sde_rot_data_type *mdata)
493{
494 SDEROT_DBG("unregister reg_bus_hdl=%x\n", mdata->reg_bus_hdl);
495
496 if (mdata->reg_bus_hdl) {
497 msm_bus_scale_unregister_client(mdata->reg_bus_hdl);
498 mdata->reg_bus_hdl = 0;
499 }
500}
501
502static struct sde_rot_data_type *sde_rot_res;
503
504struct sde_rot_data_type *sde_rot_get_mdata(void)
505{
506 return sde_rot_res;
507}
508
509/*
510 * sde_rotator_base_init - initialize base rotator data/resource
511 */
512int sde_rotator_base_init(struct sde_rot_data_type **pmdata,
513 struct platform_device *pdev,
514 const void *drvdata)
515{
516 int rc;
517 struct sde_rot_data_type *mdata;
518
519 mdata = devm_kzalloc(&pdev->dev, sizeof(*mdata), GFP_KERNEL);
520 if (mdata == NULL)
521 return -ENOMEM;
522
523 mdata->pdev = pdev;
524 sde_rot_res = mdata;
525 mutex_init(&mdata->reg_bus_lock);
526 INIT_LIST_HEAD(&mdata->reg_bus_clist);
527
528 rc = sde_rot_ioremap_byname(pdev, &mdata->sde_io, "mdp_phys");
529 if (rc) {
530 SDEROT_ERR("unable to map SDE base\n");
531 goto probe_done;
532 }
533 SDEROT_DBG("SDE ROT HW Base addr=0x%x len=0x%x\n",
534 (int) (unsigned long) mdata->sde_io.base,
535 mdata->sde_io.len);
536
537 rc = sde_rot_ioremap_byname(pdev, &mdata->vbif_nrt_io, "rot_vbif_phys");
538 if (rc) {
539 SDEROT_ERR("unable to map SDE ROT VBIF base\n");
540 goto probe_done;
541 }
542 SDEROT_DBG("SDE ROT VBIF HW Base addr=%p len=0x%x\n",
543 mdata->vbif_nrt_io.base, mdata->vbif_nrt_io.len);
544
545 rc = sde_mdp_parse_dt_misc(pdev, mdata);
546 if (rc) {
547 SDEROT_ERR("Error in device tree : misc\n");
548 goto probe_done;
549 }
550
551 rc = sde_mdp_bus_scale_register(mdata);
552 if (rc) {
553 SDEROT_ERR("unable to register bus scaling\n");
554 goto probe_done;
555 }
556
557 rc = sde_smmu_init(&pdev->dev);
558 if (rc) {
559 SDEROT_ERR("sde smmu init failed %d\n", rc);
560 goto probe_done;
561 }
562
Abhijit Kulkarni298c8232016-09-26 22:32:10 -0700563 mdata->iclient = msm_ion_client_create(mdata->pdev->name);
564 if (IS_ERR_OR_NULL(mdata->iclient)) {
565 SDEROT_ERR("msm_ion_client_create() return error (%pK)\n",
566 mdata->iclient);
567 mdata->iclient = NULL;
568 rc = -EFAULT;
569 goto probe_done;
570 }
571
Adrian Salido-Moreno5c150382016-04-06 09:29:37 -0700572 *pmdata = mdata;
573
574 return 0;
575probe_done:
576 return rc;
577}
578
579/*
580 * sde_rotator_base_destroy - clean up base rotator data/resource
581 */
582void sde_rotator_base_destroy(struct sde_rot_data_type *mdata)
583{
584 struct platform_device *pdev;
585
586 if (!mdata || !mdata->pdev)
587 return;
588
589 pdev = mdata->pdev;
590
591 sde_rot_res = NULL;
592 sde_mdp_bus_scale_unregister(mdata);
593 sde_rot_iounmap(&mdata->vbif_nrt_io);
594 sde_rot_iounmap(&mdata->sde_io);
595 devm_kfree(&pdev->dev, mdata);
596}