OSDN Git Service

Merge android-4.4.143 (7bbfac1) into msm-4.4
[sagit-ice-cold/kernel_xiaomi_msm8998.git] / drivers / gpu / drm / msm / sde_io_util.c
1 /* Copyright (c) 2012-2015, 2017, 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 #include <linux/clk.h>
14 #include <linux/err.h>
15 #include <linux/io.h>
16 #include <linux/regulator/consumer.h>
17 #include <linux/delay.h>
18 #include <linux/sde_io_util.h>
19
20 #define MAX_I2C_CMDS  16
21 void dss_reg_w(struct dss_io_data *io, u32 offset, u32 value, u32 debug)
22 {
23         u32 in_val;
24
25         if (!io || !io->base) {
26                 DEV_ERR("%pS->%s: invalid input\n",
27                         __builtin_return_address(0), __func__);
28                 return;
29         }
30
31         if (offset > io->len) {
32                 DEV_ERR("%pS->%s: offset out of range\n",
33                         __builtin_return_address(0), __func__);
34                 return;
35         }
36
37         writel_relaxed(value, io->base + offset);
38         if (debug) {
39                 in_val = readl_relaxed(io->base + offset);
40                 DEV_DBG("[%08x] => %08x [%08x]\n",
41                         (u32)(unsigned long)(io->base + offset),
42                         value, in_val);
43         }
44 } /* dss_reg_w */
45 EXPORT_SYMBOL(dss_reg_w);
46
47 u32 dss_reg_r(struct dss_io_data *io, u32 offset, u32 debug)
48 {
49         u32 value;
50
51         if (!io || !io->base) {
52                 DEV_ERR("%pS->%s: invalid input\n",
53                         __builtin_return_address(0), __func__);
54                 return -EINVAL;
55         }
56
57         if (offset > io->len) {
58                 DEV_ERR("%pS->%s: offset out of range\n",
59                         __builtin_return_address(0), __func__);
60                 return -EINVAL;
61         }
62
63         value = readl_relaxed(io->base + offset);
64         if (debug)
65                 DEV_DBG("[%08x] <= %08x\n",
66                         (u32)(unsigned long)(io->base + offset), value);
67
68         return value;
69 } /* dss_reg_r */
70 EXPORT_SYMBOL(dss_reg_r);
71
72 void dss_reg_dump(void __iomem *base, u32 length, const char *prefix,
73         u32 debug)
74 {
75         if (debug)
76                 print_hex_dump(KERN_INFO, prefix, DUMP_PREFIX_OFFSET, 32, 4,
77                         (void *)base, length, false);
78 } /* dss_reg_dump */
79 EXPORT_SYMBOL(dss_reg_dump);
80
81 static struct resource *msm_dss_get_res_byname(struct platform_device *pdev,
82         unsigned int type, const char *name)
83 {
84         struct resource *res = NULL;
85
86         res = platform_get_resource_byname(pdev, type, name);
87         if (!res)
88                 DEV_ERR("%s: '%s' resource not found\n", __func__, name);
89
90         return res;
91 } /* msm_dss_get_res_byname */
92 EXPORT_SYMBOL(msm_dss_get_res_byname);
93
94 int msm_dss_ioremap_byname(struct platform_device *pdev,
95         struct dss_io_data *io_data, const char *name)
96 {
97         struct resource *res = NULL;
98
99         if (!pdev || !io_data) {
100                 DEV_ERR("%pS->%s: invalid input\n",
101                         __builtin_return_address(0), __func__);
102                 return -EINVAL;
103         }
104
105         res = msm_dss_get_res_byname(pdev, IORESOURCE_MEM, name);
106         if (!res) {
107                 DEV_ERR("%pS->%s: '%s' msm_dss_get_res_byname failed\n",
108                         __builtin_return_address(0), __func__, name);
109                 return -ENODEV;
110         }
111
112         io_data->len = (u32)resource_size(res);
113         io_data->base = ioremap(res->start, io_data->len);
114         if (!io_data->base) {
115                 DEV_ERR("%pS->%s: '%s' ioremap failed\n",
116                         __builtin_return_address(0), __func__, name);
117                 return -EIO;
118         }
119
120         return 0;
121 } /* msm_dss_ioremap_byname */
122 EXPORT_SYMBOL(msm_dss_ioremap_byname);
123
124 void msm_dss_iounmap(struct dss_io_data *io_data)
125 {
126         if (!io_data) {
127                 DEV_ERR("%pS->%s: invalid input\n",
128                         __builtin_return_address(0), __func__);
129                 return;
130         }
131
132         if (io_data->base) {
133                 iounmap(io_data->base);
134                 io_data->base = NULL;
135         }
136         io_data->len = 0;
137 } /* msm_dss_iounmap */
138 EXPORT_SYMBOL(msm_dss_iounmap);
139
140 int msm_dss_config_vreg(struct device *dev, struct dss_vreg *in_vreg,
141         int num_vreg, int config)
142 {
143         int i = 0, rc = 0;
144         struct dss_vreg *curr_vreg = NULL;
145         enum dss_vreg_type type;
146
147         if (!in_vreg || !num_vreg)
148                 return rc;
149
150         if (config) {
151                 for (i = 0; i < num_vreg; i++) {
152                         curr_vreg = &in_vreg[i];
153                         curr_vreg->vreg = regulator_get(dev,
154                                 curr_vreg->vreg_name);
155                         rc = PTR_RET(curr_vreg->vreg);
156                         if (rc) {
157                                 DEV_ERR("%pS->%s: %s get failed. rc=%d\n",
158                                          __builtin_return_address(0), __func__,
159                                          curr_vreg->vreg_name, rc);
160                                 curr_vreg->vreg = NULL;
161                                 goto vreg_get_fail;
162                         }
163                         type = (regulator_count_voltages(curr_vreg->vreg) > 0)
164                                         ? DSS_REG_LDO : DSS_REG_VS;
165                         if (type == DSS_REG_LDO) {
166                                 rc = regulator_set_voltage(
167                                         curr_vreg->vreg,
168                                         curr_vreg->min_voltage,
169                                         curr_vreg->max_voltage);
170                                 if (rc < 0) {
171                                         DEV_ERR("%pS->%s: %s set vltg fail\n",
172                                                 __builtin_return_address(0),
173                                                 __func__,
174                                                 curr_vreg->vreg_name);
175                                         goto vreg_set_voltage_fail;
176                                 }
177                         }
178                 }
179         } else {
180                 for (i = num_vreg-1; i >= 0; i--) {
181                         curr_vreg = &in_vreg[i];
182                         if (curr_vreg->vreg) {
183                                 type = (regulator_count_voltages(
184                                         curr_vreg->vreg) > 0)
185                                         ? DSS_REG_LDO : DSS_REG_VS;
186                                 if (type == DSS_REG_LDO) {
187                                         regulator_set_voltage(curr_vreg->vreg,
188                                                 0, curr_vreg->max_voltage);
189                                 }
190                                 regulator_put(curr_vreg->vreg);
191                                 curr_vreg->vreg = NULL;
192                         }
193                 }
194         }
195         return 0;
196
197 vreg_unconfig:
198 if (type == DSS_REG_LDO)
199         regulator_set_load(curr_vreg->vreg, 0);
200
201 vreg_set_voltage_fail:
202         regulator_put(curr_vreg->vreg);
203         curr_vreg->vreg = NULL;
204
205 vreg_get_fail:
206         for (i--; i >= 0; i--) {
207                 curr_vreg = &in_vreg[i];
208                 type = (regulator_count_voltages(curr_vreg->vreg) > 0)
209                         ? DSS_REG_LDO : DSS_REG_VS;
210                 goto vreg_unconfig;
211         }
212         return rc;
213 } /* msm_dss_config_vreg */
214 EXPORT_SYMBOL(msm_dss_config_vreg);
215
216 int msm_dss_enable_vreg(struct dss_vreg *in_vreg, int num_vreg, int enable)
217 {
218         int i = 0, rc = 0;
219         bool need_sleep;
220
221         if (enable) {
222                 for (i = 0; i < num_vreg; i++) {
223                         rc = PTR_RET(in_vreg[i].vreg);
224                         if (rc) {
225                                 DEV_ERR("%pS->%s: %s regulator error. rc=%d\n",
226                                         __builtin_return_address(0), __func__,
227                                         in_vreg[i].vreg_name, rc);
228                                 goto vreg_set_opt_mode_fail;
229                         }
230                         need_sleep = !regulator_is_enabled(in_vreg[i].vreg);
231                         if (in_vreg[i].pre_on_sleep && need_sleep)
232                                 usleep_range(in_vreg[i].pre_on_sleep * 1000,
233                                         in_vreg[i].pre_on_sleep * 1000);
234                         rc = regulator_set_load(in_vreg[i].vreg,
235                                 in_vreg[i].enable_load);
236                         if (rc < 0) {
237                                 DEV_ERR("%pS->%s: %s set opt m fail\n",
238                                         __builtin_return_address(0), __func__,
239                                         in_vreg[i].vreg_name);
240                                 goto vreg_set_opt_mode_fail;
241                         }
242                         rc = regulator_enable(in_vreg[i].vreg);
243                         if (in_vreg[i].post_on_sleep && need_sleep)
244                                 usleep_range(in_vreg[i].post_on_sleep * 1000,
245                                         in_vreg[i].post_on_sleep * 1000);
246                         if (rc < 0) {
247                                 DEV_ERR("%pS->%s: %s enable failed\n",
248                                         __builtin_return_address(0), __func__,
249                                         in_vreg[i].vreg_name);
250                                 goto disable_vreg;
251                         }
252                 }
253         } else {
254                 for (i = num_vreg-1; i >= 0; i--) {
255                         if (in_vreg[i].pre_off_sleep)
256                                 usleep_range(in_vreg[i].pre_off_sleep * 1000,
257                                         in_vreg[i].pre_off_sleep * 1000);
258                         regulator_set_load(in_vreg[i].vreg,
259                                 in_vreg[i].disable_load);
260                         regulator_disable(in_vreg[i].vreg);
261                         if (in_vreg[i].post_off_sleep)
262                                 usleep_range(in_vreg[i].post_off_sleep * 1000,
263                                         in_vreg[i].post_off_sleep * 1000);
264                 }
265         }
266         return rc;
267
268 disable_vreg:
269         regulator_set_load(in_vreg[i].vreg, in_vreg[i].disable_load);
270
271 vreg_set_opt_mode_fail:
272         for (i--; i >= 0; i--) {
273                 if (in_vreg[i].pre_off_sleep)
274                         usleep_range(in_vreg[i].pre_off_sleep * 1000,
275                                 in_vreg[i].pre_off_sleep * 1000);
276                 regulator_set_load(in_vreg[i].vreg,
277                         in_vreg[i].disable_load);
278                 regulator_disable(in_vreg[i].vreg);
279                 if (in_vreg[i].post_off_sleep)
280                         usleep_range(in_vreg[i].post_off_sleep * 1000,
281                                 in_vreg[i].post_off_sleep * 1000);
282         }
283
284         return rc;
285 } /* msm_dss_enable_vreg */
286 EXPORT_SYMBOL(msm_dss_enable_vreg);
287
288 int msm_dss_enable_gpio(struct dss_gpio *in_gpio, int num_gpio, int enable)
289 {
290         int i = 0, rc = 0;
291
292         if (enable) {
293                 for (i = 0; i < num_gpio; i++) {
294                         DEV_DBG("%pS->%s: %s enable\n",
295                                 __builtin_return_address(0), __func__,
296                                 in_gpio[i].gpio_name);
297
298                         rc = gpio_request(in_gpio[i].gpio,
299                                 in_gpio[i].gpio_name);
300                         if (rc < 0) {
301                                 DEV_ERR("%pS->%s: %s enable failed\n",
302                                         __builtin_return_address(0), __func__,
303                                         in_gpio[i].gpio_name);
304                                 goto disable_gpio;
305                         }
306                         gpio_set_value(in_gpio[i].gpio, in_gpio[i].value);
307                 }
308         } else {
309                 for (i = num_gpio-1; i >= 0; i--) {
310                         DEV_DBG("%pS->%s: %s disable\n",
311                                 __builtin_return_address(0), __func__,
312                                 in_gpio[i].gpio_name);
313                         if (in_gpio[i].gpio)
314                                 gpio_free(in_gpio[i].gpio);
315                 }
316         }
317         return rc;
318
319 disable_gpio:
320         for (i--; i >= 0; i--)
321                 if (in_gpio[i].gpio)
322                         gpio_free(in_gpio[i].gpio);
323
324         return rc;
325 } /* msm_dss_enable_gpio */
326 EXPORT_SYMBOL(msm_dss_enable_gpio);
327
328 void msm_dss_put_clk(struct dss_clk *clk_arry, int num_clk)
329 {
330         int i;
331
332         for (i = num_clk - 1; i >= 0; i--) {
333                 if (clk_arry[i].clk)
334                         clk_put(clk_arry[i].clk);
335                 clk_arry[i].clk = NULL;
336         }
337 } /* msm_dss_put_clk */
338 EXPORT_SYMBOL(msm_dss_put_clk);
339
340 int msm_dss_get_clk(struct device *dev, struct dss_clk *clk_arry, int num_clk)
341 {
342         int i, rc = 0;
343
344         for (i = 0; i < num_clk; i++) {
345                 clk_arry[i].clk = clk_get(dev, clk_arry[i].clk_name);
346                 rc = PTR_RET(clk_arry[i].clk);
347                 if (rc) {
348                         DEV_ERR("%pS->%s: '%s' get failed. rc=%d\n",
349                                 __builtin_return_address(0), __func__,
350                                 clk_arry[i].clk_name, rc);
351                         goto error;
352                 }
353         }
354
355         return rc;
356
357 error:
358         msm_dss_put_clk(clk_arry, num_clk);
359
360         return rc;
361 } /* msm_dss_get_clk */
362 EXPORT_SYMBOL(msm_dss_get_clk);
363
364 int msm_dss_clk_set_rate(struct dss_clk *clk_arry, int num_clk)
365 {
366         int i, rc = 0;
367
368         for (i = 0; i < num_clk; i++) {
369                 if (clk_arry[i].clk) {
370                         if (clk_arry[i].type != DSS_CLK_AHB) {
371                                 DEV_DBG("%pS->%s: '%s' rate %ld\n",
372                                         __builtin_return_address(0), __func__,
373                                         clk_arry[i].clk_name,
374                                         clk_arry[i].rate);
375                                 rc = clk_set_rate(clk_arry[i].clk,
376                                         clk_arry[i].rate);
377                                 if (rc) {
378                                         DEV_ERR("%pS->%s: %s failed. rc=%d\n",
379                                                 __builtin_return_address(0),
380                                                 __func__,
381                                                 clk_arry[i].clk_name, rc);
382                                         break;
383                                 }
384                         }
385                 } else {
386                         DEV_ERR("%pS->%s: '%s' is not available\n",
387                                 __builtin_return_address(0), __func__,
388                                 clk_arry[i].clk_name);
389                         rc = -EPERM;
390                         break;
391                 }
392         }
393
394         return rc;
395 } /* msm_dss_clk_set_rate */
396 EXPORT_SYMBOL(msm_dss_clk_set_rate);
397
398 int msm_dss_enable_clk(struct dss_clk *clk_arry, int num_clk, int enable)
399 {
400         int i, rc = 0;
401
402         if (enable) {
403                 for (i = 0; i < num_clk; i++) {
404                         DEV_DBG("%pS->%s: enable '%s'\n",
405                                 __builtin_return_address(0), __func__,
406                                 clk_arry[i].clk_name);
407                         if (clk_arry[i].clk) {
408                                 rc = clk_prepare_enable(clk_arry[i].clk);
409                                 if (rc)
410                                         DEV_ERR("%pS->%s: %s en fail. rc=%d\n",
411                                                 __builtin_return_address(0),
412                                                 __func__,
413                                                 clk_arry[i].clk_name, rc);
414                         } else {
415                                 DEV_ERR("%pS->%s: '%s' is not available\n",
416                                         __builtin_return_address(0), __func__,
417                                         clk_arry[i].clk_name);
418                                 rc = -EPERM;
419                         }
420
421                         if (rc) {
422                                 msm_dss_enable_clk(&clk_arry[i],
423                                         i, false);
424                                 break;
425                         }
426                 }
427         } else {
428                 for (i = num_clk - 1; i >= 0; i--) {
429                         DEV_DBG("%pS->%s: disable '%s'\n",
430                                 __builtin_return_address(0), __func__,
431                                 clk_arry[i].clk_name);
432
433                         if (clk_arry[i].clk)
434                                 clk_disable_unprepare(clk_arry[i].clk);
435                         else
436                                 DEV_ERR("%pS->%s: '%s' is not available\n",
437                                         __builtin_return_address(0), __func__,
438                                         clk_arry[i].clk_name);
439                 }
440         }
441
442         return rc;
443 } /* msm_dss_enable_clk */
444 EXPORT_SYMBOL(msm_dss_enable_clk);
445
446
447 int sde_i2c_byte_read(struct i2c_client *client, uint8_t slave_addr,
448                         uint8_t reg_offset, uint8_t *read_buf)
449 {
450         struct i2c_msg msgs[2];
451         int ret = -1;
452
453         pr_debug("%s: reading from slave_addr=[%x] and offset=[%x]\n",
454                  __func__, slave_addr, reg_offset);
455
456         msgs[0].addr = slave_addr >> 1;
457         msgs[0].flags = 0;
458         msgs[0].buf = &reg_offset;
459         msgs[0].len = 1;
460
461         msgs[1].addr = slave_addr >> 1;
462         msgs[1].flags = I2C_M_RD;
463         msgs[1].buf = read_buf;
464         msgs[1].len = 1;
465
466         ret = i2c_transfer(client->adapter, msgs, 2);
467         if (ret < 1) {
468                 pr_err("%s: I2C READ FAILED=[%d]\n", __func__, ret);
469                 return -EACCES;
470         }
471         pr_debug("%s: i2c buf is [%x]\n", __func__, *read_buf);
472         return 0;
473 }
474 EXPORT_SYMBOL(sde_i2c_byte_read);
475
476 int sde_i2c_byte_write(struct i2c_client *client, uint8_t slave_addr,
477                         uint8_t reg_offset, uint8_t *value)
478 {
479         struct i2c_msg msgs[1];
480         uint8_t data[2];
481         int status = -EACCES;
482
483         pr_debug("%s: writing from slave_addr=[%x] and offset=[%x]\n",
484                  __func__, slave_addr, reg_offset);
485
486         data[0] = reg_offset;
487         data[1] = *value;
488
489         msgs[0].addr = slave_addr >> 1;
490         msgs[0].flags = 0;
491         msgs[0].len = 2;
492         msgs[0].buf = data;
493
494         status = i2c_transfer(client->adapter, msgs, 1);
495         if (status < 1) {
496                 pr_err("I2C WRITE FAILED=[%d]\n", status);
497                 return -EACCES;
498         }
499         pr_debug("%s: I2C write status=%x\n", __func__, status);
500         return status;
501 }
502 EXPORT_SYMBOL(sde_i2c_byte_write);