1 /*
2 * Allwinner SoCs display driver.
3 *
4 * Copyright (C) 2016 Allwinner.
5 *
6 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied.
9 */
10
11 #include "de/bsp_display.h"
12 #include "disp_sys_intf.h"
13 #include "asm/cacheflush.h"
14 // #include <linux/sunxi-gpio.h>
15 #include <linux/version.h>
16 #include <asm-generic/bug.h>
17 #include <linux/gpio/machine.h>
18 #include "dev_disp.h"
19
20 /* cache flush flags */
21 #define CACHE_FLUSH_I_CACHE_REGION 0
22 #define CACHE_FLUSH_D_CACHE_REGION 1
23 #define CACHE_FLUSH_CACHE_REGION 2
24 #define CACHE_CLEAN_D_CACHE_REGION 3
25 #define CACHE_CLEAN_FLUSH_D_CACHE_REGION 4
26 #define CACHE_CLEAN_FLUSH_CACHE_REGION 5
27
disp_sys_malloc(u32 size)28 void *disp_sys_malloc(u32 size)
29 {
30 return kmalloc(size, GFP_KERNEL | __GFP_ZERO);
31 }
32 /*
33 *******************************************************************************
34 * OSAL_CacheRangeFlush
35 *
36 * Description:
37 * Cache flush
38 *
39 * Parameters:
40 * address : start address to be flush
41 * length : size
42 * flags : flush flags
43 *
44 * Return value:
45 * void
46 *
47 * note:
48 * void
49 *
50 *******************************************************************************
51 */
disp_sys_cache_flush(void * address,u32 length,u32 flags)52 void disp_sys_cache_flush(void *address, u32 length, u32 flags)
53 {
54 if (address == NULL || length == 0)
55 return;
56
57 switch (flags) {
58 case CACHE_FLUSH_I_CACHE_REGION:
59 break;
60
61 case CACHE_FLUSH_D_CACHE_REGION:
62 break;
63
64 case CACHE_FLUSH_CACHE_REGION:
65 break;
66
67 case CACHE_CLEAN_D_CACHE_REGION:
68 break;
69
70 case CACHE_CLEAN_FLUSH_D_CACHE_REGION:
71 break;
72
73 case CACHE_CLEAN_FLUSH_CACHE_REGION:
74 break;
75
76 default:
77 break;
78 }
79 }
80
81 /*
82 *******************************************************************************
83 * disp_sys_register_irq
84 *
85 * Description:
86 * irq register
87 *
88 * Parameters:
89 * irqno ��input. irq no
90 * flags ��input.
91 * Handler ��input. isr handler
92 * pArg ��input. para
93 * DataSize ��input. len of para
94 * prio ��input. priority
95
96 *
97 * Return value:
98 *
99 *
100 * note:
101 * typedef s32 (*ISRCallback)( void *pArg)��
102 *
103 *******************************************************************************
104 */
disp_sys_register_irq(u32 IrqNo,u32 Flags,void * Handler,void * pArg,u32 DataSize,u32 Prio)105 int disp_sys_register_irq(u32 IrqNo, u32 Flags, void *Handler, void *pArg,
106 u32 DataSize, u32 Prio)
107 {
108 __inf("%s, irqNo=%d, Handler=0x%p, pArg=0x%p\n", __func__, IrqNo,
109 Handler, pArg);
110 return request_irq(IrqNo, (irq_handler_t) Handler, 0x0,
111 "dispaly", pArg);
112 }
113
114 /*
115 *******************************************************************************
116 * disp_sys_unregister_irq
117 *
118 * Description:
119 * irq unregister
120 *
121 * Parameters:
122 * irqno ��input. irq no
123 * handler ��input. isr handler
124 * Argment ��input. para
125 *
126 * Return value:
127 * void
128 *
129 * note:
130 * void
131 *
132 *******************************************************************************
133 */
disp_sys_unregister_irq(u32 IrqNo,void * Handler,void * pArg)134 void disp_sys_unregister_irq(u32 IrqNo, void *Handler, void *pArg)
135 {
136 free_irq(IrqNo, pArg);
137 }
138
139 /*
140 *******************************************************************************
141 * disp_sys_enable_irq
142 *
143 * Description:
144 * enable irq
145 *
146 * Parameters:
147 * irqno ��input. irq no
148 *
149 * Return value:
150 * void
151 *
152 * note:
153 * void
154 *
155 *******************************************************************************
156 */
disp_sys_enable_irq(u32 IrqNo)157 void disp_sys_enable_irq(u32 IrqNo)
158 {
159 /* enable_irq(IrqNo); */
160 }
161
162 /*
163 *******************************************************************************
164 * disp_sys_disable_irq
165 *
166 * Description:
167 * disable irq
168 *
169 * Parameters:
170 * irqno ��input. irq no
171 *
172 * Return value:
173 * void
174 *
175 * note:
176 * void
177 *
178 *******************************************************************************
179 */
disp_sys_disable_irq(u32 IrqNo)180 void disp_sys_disable_irq(u32 IrqNo)
181 {
182 /* disable_irq(IrqNo); */
183 }
184
185 /* type: 0:invalid, 1: int; 2:str, 3: gpio */
disp_sys_script_get_item(char * main_name,char * sub_name,int value[],int type)186 int disp_sys_script_get_item(char *main_name, char *sub_name, int value[],
187 int type)
188 {
189 char compat[32];
190 u32 len = 0;
191 struct device_node *node;
192 int ret = 0;
193 enum of_gpio_flags flags;
194
195 len = sprintf(compat, "allwinner,sunxi-%s", main_name);
196 if (len > 32)
197 __wrn("size of mian_name is out of range\n");
198
199 node = of_find_compatible_node(NULL, NULL, compat);
200 if (!node) {
201 __wrn("of_find_compatible_node %s fail\n", compat);
202 return ret;
203 }
204
205 g_disp_drv.node = node;
206
207 if (type == 1) {
208 if (of_property_read_u32_array(node, sub_name, value, 1))
209 __inf("of_property_read_u32_array %s.%s fail\n",
210 main_name, sub_name);
211 else
212 ret = type;
213 } else if (type == 2) {
214 const char *str;
215
216 if (of_property_read_string(node, sub_name, &str))
217 __inf("of_property_read_string %s.%s fail\n", main_name,
218 sub_name);
219 else {
220 ret = type;
221 memcpy((void *)value, str, strlen(str) + 1);
222 }
223 } else if (type == 3) {
224 int gpio;
225 struct disp_gpio_info *gpio_info = (struct disp_gpio_info *)value;
226
227 /* gpio is invalid by default */
228 gpio_info->gpio = -1;
229 gpio_info->name[0] = '\0';
230
231 gpio = of_get_named_gpio_flags(node, sub_name, 0, &flags);
232 if (!gpio_is_valid(gpio))
233 return -EINVAL;
234
235 gpio_info->gpio = gpio;
236 memcpy(gpio_info->name, sub_name, strlen(sub_name) + 1);
237 gpio_info->value = (flags == OF_GPIO_ACTIVE_LOW) ? 0 : 1;
238 __inf("%s.%s gpio=%d, value:%d\n", main_name, sub_name,
239 gpio_info->gpio, gpio_info->value);
240 }
241
242 return ret;
243 }
244 EXPORT_SYMBOL(disp_sys_script_get_item);
245
disp_sys_get_ic_ver(void)246 int disp_sys_get_ic_ver(void)
247 {
248 return 0;
249 }
250
disp_sys_gpio_request(struct disp_gpio_info * gpio_info)251 int disp_sys_gpio_request(struct disp_gpio_info *gpio_info)
252 {
253 int ret = 0;
254
255 if (!gpio_info) {
256 __wrn("%s: gpio_info is null\n", __func__);
257 return -1;
258 }
259
260 /* As some GPIOs are not essential, here return 0 to avoid error */
261 if (!strlen(gpio_info->name))
262 return 0;
263
264 if (!gpio_is_valid(gpio_info->gpio)) {
265 __wrn("%s: gpio (%d) is invalid\n", __func__, gpio_info->gpio);
266 return -1;
267 }
268
269 ret = gpio_direction_output(gpio_info->gpio, gpio_info->value);
270 if (ret) {
271 __wrn("%s failed, gpio_name=%s, gpio=%d, value=%d, ret=%d\n", __func__,
272 gpio_info->name, gpio_info->gpio, gpio_info->value, ret);
273 return -1;
274 }
275
276 __inf("%s, gpio_name=%s, gpio=%d, value=%d, ret=%d\n", __func__,
277 gpio_info->name, gpio_info->gpio, gpio_info->value, ret);
278
279 return ret;
280 }
281 EXPORT_SYMBOL(disp_sys_gpio_request);
282
disp_sys_gpio_release(struct disp_gpio_info * gpio_info)283 void disp_sys_gpio_release(struct disp_gpio_info *gpio_info)
284 {
285 if (!gpio_info) {
286 __wrn("%s: gpio_info is null\n", __func__);
287 return;
288 }
289
290 if (!strlen(gpio_info->name))
291 return;
292
293 if (!gpio_is_valid(gpio_info->gpio)) {
294 __wrn("%s: gpio(%d) is invalid\n", __func__, gpio_info->gpio);
295 return;
296 }
297
298 gpio_free(gpio_info->gpio);
299 }
300 EXPORT_SYMBOL(disp_sys_gpio_release);
301
302 /* direction: 0:input, 1:output */
disp_sys_gpio_set_direction(u32 p_handler,u32 direction,const char * gpio_name)303 int disp_sys_gpio_set_direction(u32 p_handler, u32 direction,
304 const char *gpio_name)
305 {
306 int ret = -1;
307
308 if (p_handler) {
309 if (direction) {
310 s32 value;
311
312 value = __gpio_get_value(p_handler);
313 ret = gpio_direction_output(p_handler, value);
314 if (ret != 0)
315 __wrn("gpio_direction_output fail!\n");
316 } else {
317 ret = gpio_direction_input(p_handler);
318 if (ret != 0)
319 __wrn("gpio_direction_input fail!\n");
320 }
321 } else {
322 __wrn("OSAL_GPIO_DevSetONEPIN_IO_STATUS, hdl is NULL\n");
323 ret = -1;
324 }
325 return ret;
326 }
327
disp_sys_gpio_get_value(u32 p_handler,const char * gpio_name)328 int disp_sys_gpio_get_value(u32 p_handler, const char *gpio_name)
329 {
330 if (p_handler)
331 return __gpio_get_value(p_handler);
332 __wrn("OSAL_GPIO_DevREAD_ONEPIN_DATA, hdl is NULL\n");
333
334 return -1;
335 }
336
disp_sys_gpio_set_value(u32 p_handler,u32 value_to_gpio,const char * gpio_name)337 int disp_sys_gpio_set_value(u32 p_handler, u32 value_to_gpio,
338 const char *gpio_name)
339 {
340 if (p_handler)
341 __gpio_set_value(p_handler, value_to_gpio);
342 else
343 __wrn("OSAL_GPIO_DevWRITE_ONEPIN_DATA, hdl is NULL\n");
344
345 return 0;
346 }
347
disp_sys_pin_set_state(char * dev_name,char * name)348 int disp_sys_pin_set_state(char *dev_name, char *name)
349 {
350 char compat[32];
351 u32 len = 0;
352 struct device_node *node;
353 struct platform_device *pdev;
354 struct pinctrl *pctl;
355 struct pinctrl_state *state;
356 int ret = -1;
357
358 len = sprintf(compat, "allwinner,sunxi-%s", dev_name);
359 if (len > 32)
360 __wrn("size of mian_name is out of range\n");
361
362 node = of_find_compatible_node(NULL, NULL, compat);
363 if (!node) {
364 __wrn("of_find_compatible_node %s fail\n", compat);
365 goto exit;
366 }
367
368 pdev = of_find_device_by_node(node);
369 if (!node) {
370 __wrn("of_find_device_by_node for %s fail\n", compat);
371 goto exit;
372 }
373
374 pctl = pinctrl_get(&pdev->dev);
375 if (IS_ERR(pctl)) {
376 /*not every lcd need pin config*/
377 __inf("pinctrl_get for %s fail\n", compat);
378 ret = PTR_ERR(pctl);
379 goto exit;
380 }
381
382 state = pinctrl_lookup_state(pctl, name);
383 if (IS_ERR(state)) {
384 __wrn("pinctrl_lookup_state for %s fail\n", compat);
385 ret = PTR_ERR(state);
386 goto exit;
387 }
388
389 ret = pinctrl_select_state(pctl, state);
390 if (ret < 0) {
391 __wrn("pinctrl_select_state(%s) for %s fail\n", name, compat);
392 goto exit;
393 }
394 ret = 0;
395 exit:
396 return ret;
397 }
398 EXPORT_SYMBOL(disp_sys_pin_set_state);
399
disp_sys_power_enable(struct regulator * regulator)400 int disp_sys_power_enable(struct regulator *regulator)
401 {
402 int ret = 0;
403
404 if (!regulator)
405 return 0;
406
407 ret = regulator_enable(regulator);
408 WARN(ret, "regulator_enable failed, ret=%d\n", ret);
409
410 return ret;
411 }
412
disp_sys_power_disable(struct regulator * regulator)413 int disp_sys_power_disable(struct regulator *regulator)
414 {
415 int ret = 0;
416
417 if (!regulator)
418 return 0;
419
420 ret = regulator_disable(regulator);
421 WARN(ret, "regulator_disable failed, ret=%d\n", ret);
422
423 return ret;
424 }
425
426 #if IS_ENABLED(CONFIG_PWM_SUNXI) || IS_ENABLED(CONFIG_PWM_SUNXI_NEW) || \
427 IS_ENABLED(CONFIG_PWM_SUNXI_GROUP) || IS_ENABLED(CONFIG_AW_PWM)
disp_sys_pwm_request(u32 pwm_id)428 uintptr_t disp_sys_pwm_request(u32 pwm_id)
429 {
430 uintptr_t ret = 0;
431
432 struct pwm_device *pwm_dev;
433
434 pwm_dev = pwm_request(pwm_id, "lcd");
435
436 if ((pwm_dev == NULL) || IS_ERR(pwm_dev)) {
437 __wrn("disp_sys_pwm_request pwm %d fail! %ld\n", pwm_id,
438 (long)pwm_dev);
439 pwm_dev = NULL;
440 } else
441 __inf("disp_sys_pwm_request pwm %d success!\n", pwm_id);
442 ret = (uintptr_t) pwm_dev;
443
444 return ret;
445 }
446
disp_sys_pwm_free(uintptr_t p_handler)447 int disp_sys_pwm_free(uintptr_t p_handler)
448 {
449 int ret = 0;
450 struct pwm_device *pwm_dev;
451
452 pwm_dev = (struct pwm_device *)p_handler;
453 if ((pwm_dev == NULL) || IS_ERR(pwm_dev)) {
454 __wrn("disp_sys_pwm_free, handle is NULL!\n");
455 ret = -1;
456 } else {
457 pwm_free(pwm_dev);
458 __inf("disp_sys_pwm_free pwm %d\n", pwm_dev->pwm);
459 }
460
461 return ret;
462 }
463
disp_sys_pwm_enable(uintptr_t p_handler)464 int disp_sys_pwm_enable(uintptr_t p_handler)
465 {
466 int ret = 0;
467 struct pwm_device *pwm_dev;
468
469 pwm_dev = (struct pwm_device *)p_handler;
470 if ((pwm_dev == NULL) || IS_ERR(pwm_dev)) {
471 __wrn("disp_sys_pwm_Enable, handle is NULL!\n");
472 ret = -1;
473 } else {
474 ret = pwm_enable(pwm_dev);
475 __inf("disp_sys_pwm_Enable pwm %d\n", pwm_dev->pwm);
476 }
477
478 return ret;
479 }
480
disp_sys_pwm_disable(uintptr_t p_handler)481 int disp_sys_pwm_disable(uintptr_t p_handler)
482 {
483 int ret = 0;
484 struct pwm_device *pwm_dev;
485
486 pwm_dev = (struct pwm_device *)p_handler;
487 if ((pwm_dev == NULL) || IS_ERR(pwm_dev)) {
488 __wrn("disp_sys_pwm_Disable, handle is NULL!\n");
489 ret = -1;
490 } else {
491 pwm_disable(pwm_dev);
492 __inf("disp_sys_pwm_Disable pwm %d\n", pwm_dev->pwm);
493 }
494
495 return ret;
496 }
497
disp_sys_pwm_config(uintptr_t p_handler,int duty_ns,int period_ns)498 int disp_sys_pwm_config(uintptr_t p_handler, int duty_ns, int period_ns)
499 {
500 int ret = 0;
501 struct pwm_device *pwm_dev;
502
503 pwm_dev = (struct pwm_device *)p_handler;
504 if ((pwm_dev == NULL) || IS_ERR(pwm_dev)) {
505 __wrn("disp_sys_pwm_Config, handle is NULL!\n");
506 ret = -1;
507 } else {
508 ret = pwm_config(pwm_dev, duty_ns, period_ns);
509 __debug("disp_sys_pwm_Config pwm %d, <%d / %d>\n",
510 pwm_dev->pwm, duty_ns, period_ns);
511 }
512
513 return ret;
514 }
515
disp_sys_pwm_set_polarity(uintptr_t p_handler,int polarity)516 int disp_sys_pwm_set_polarity(uintptr_t p_handler, int polarity)
517 {
518 int ret = 0;
519 struct pwm_state state;
520 struct pwm_device *pwm_dev;
521
522 pwm_dev = (struct pwm_device *)p_handler;
523 if ((pwm_dev == NULL) || IS_ERR(pwm_dev)) {
524 __wrn("disp_sys_pwm_Set_Polarity, handle is NULL!\n");
525 ret = -1;
526 } else {
527 memset(&state, 0, sizeof(struct pwm_state));
528 pwm_get_state(pwm_dev, &state);
529 state.polarity = polarity;
530 ret = pwm_apply_state(pwm_dev, &state);
531 __inf("disp_sys_pwm_Set_Polarity pwm %d, active %s\n",
532 pwm_dev->pwm, (polarity == 0) ? "high" : "low");
533 }
534
535 return ret;
536 }
537 #else
disp_sys_pwm_request(u32 pwm_id)538 uintptr_t disp_sys_pwm_request(u32 pwm_id)
539 {
540 uintptr_t ret = 0;
541
542 return ret;
543 }
544
disp_sys_pwm_free(uintptr_t p_handler)545 int disp_sys_pwm_free(uintptr_t p_handler)
546 {
547 int ret = 0;
548
549 return ret;
550 }
551
disp_sys_pwm_enable(uintptr_t p_handler)552 int disp_sys_pwm_enable(uintptr_t p_handler)
553 {
554 int ret = 0;
555
556 return ret;
557 }
558
disp_sys_pwm_disable(uintptr_t p_handler)559 int disp_sys_pwm_disable(uintptr_t p_handler)
560 {
561 int ret = 0;
562
563 return ret;
564 }
565
disp_sys_pwm_config(uintptr_t p_handler,int duty_ns,int period_ns)566 int disp_sys_pwm_config(uintptr_t p_handler, int duty_ns, int period_ns)
567 {
568 int ret = 0;
569
570 return ret;
571 }
572
disp_sys_pwm_set_polarity(uintptr_t p_handler,int polarity)573 int disp_sys_pwm_set_polarity(uintptr_t p_handler, int polarity)
574 {
575 int ret = 0;
576
577 return ret;
578 }
579
580 #endif
581