1 /*
2 * Copyright (C) 2019 Allwinnertech Co.Ltd
3 * Authors: zhengwanyu
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 */
11 #ifndef _SUNXI_LCD_H_
12 #define _SUNXI_LCD_H_
13
14 #include <linux/clk.h>
15 #include "de/include.h"
16 #include "sunxi_common.h"
17 #include "de/disp_lcd.h"
18 #include "lcd_panel/panels.h"
19 #include "de_dsi.h"
20
21 #define LCD_NUM_MAX 4
22
23 /*NOTE:
24 * if sunxi lcd driver should support more than 3 lcd at the same time,
25 * this enum should be extended
26 */
27 enum sunxi_lcd_connector {
28 SUNXI_LVDS0 = 0,
29 SUNXI_LVDS1,
30
31 SUNXI_RGB0,
32 SUNXI_RGB1,
33
34 SUNXI_CPU0,
35 SUNXI_CPU1,
36
37 SUNXI_DSI0,
38 SUNXI_DSI1,
39
40 SUNXI_VDPO0,
41 SUNXI_VDPO1,
42
43 SUNXI_LCD_CON_NUM,
44 };
45
46 /*RGB*/
47 enum hv_if_type {
48 PARALLEL_RGB = 0,
49 SERIAL_RGB = 8,
50 DUMMY_RGB = 10,
51 RGB_DUMMY = 11,
52 SERIAL_YUV = 12,/*CCIR656*/
53 };
54
55 /*CPU*/
56 enum cpu_if_type {
57 RGB666_18_1 = 0, /*18bit/1cycle*/
58 RGB565_16_1 = 4,
59 RGB666_18_3 = 6,
60 RGB565_16_2 = 8,
61 RGB666_9_1 = 10,
62 RGB666_8_3 = 12,
63 RGB565_8_2 = 14,
64 };
65
66 enum lvds_if_type {
67 SINGLE_LINK = 0,
68 DUAL_LINK = 1,
69 };
70
71 /*dsi working mode*/
72 enum dsi_if_type {
73 VIDEO_MODE = 0,
74 COMMAND_MODE = 1,
75 VIDEO_BURST_MODE = 2,
76 };
77
78 struct sunxi_lcd_resource {
79 uintptr_t reg_base[SUNXI_LCD_CON_NUM];
80 struct clk *mclk[SUNXI_LCD_CON_NUM];
81 struct clk *mclk_bus[SUNXI_LCD_CON_NUM];
82 unsigned int irq_no[SUNXI_LCD_CON_NUM];
83 struct reset_control *rst_bus_lvds;
84 };
85
86 struct sunxi_lcd_funcs {
87 unsigned int (*get_type)(unsigned int lcd_id);
88 struct disp_panel_para *(*get_panel_para)(unsigned int lcd_id);
89 bool (*is_use_irq)(unsigned int lcd_id);
90 unsigned int (*get_irq_no)(unsigned int lcd_id);
91 int (*enable)(unsigned int lcd_id);
92 int (*sw_enable)(unsigned int lcd_id);
93 void (*disable)(unsigned int lcd_id);
94 };
95
96 struct sunxi_lcd {
97 struct platform_device *pdev;
98
99 int id;
100 bool is_used;
101 bool is_enabled;
102
103 /*register base*/
104 uintptr_t reg_base;
105
106 enum disp_lcd_if type;
107
108 /*
109 *for example, typde_id = 2, type = LCD_IF_LVDS,
110 * it means that this sunxi_lcd is LVDS2
111 */
112 unsigned int type_id;
113
114 /*clock resource*/
115 struct clk *mclk;/*module clk*/
116 struct clk *mclk_bus;/*module bus clk*/
117 struct clk *parent_clk;
118
119 /*interrupt resource*/
120 bool irq_used;
121 bool irq_enabled;
122 unsigned int irq_no;
123
124 /*###################################*/
125 struct disp_lcd_cfg lcd_cfg;
126 struct panel_extend_para extend_para;
127
128 /*this member indicate the info of a lcd panel,
129 NOT info of lcd connector*/
130 struct disp_panel_para panel_para;
131 struct __lcd_panel *panel;
132
133 /*indicate if this lcd use backlight*/
134 unsigned char use_bl;
135
136 struct sunxi_lcd_funcs *funcs;
137 };
138
139 struct sunxi_lcd_drv {
140 /*linux system relative*/
141 struct drv_model_info drv_model;
142
143 /*collect all of lcd resources, including reg_base/irq/clk,
144 * and then dispatch them to the relative lcd connectors
145 * after lcd0/1/2/3 init.
146 * we need to do that, because we only know there is lcd0/1/2/3,
147 * but we don't know who is DSI, who is lvds, who is cpu,
148 * before lcd0/1/2/3 init. So we collect all of lcd resources here and
149 * dispatch them to the LCD connector they belongs to after lcd0/1/2/3
150 * init
151 */
152 struct sunxi_lcd_resource res;
153
154 unsigned int lcd_cnt;
155 unsigned int lvds_cnt;
156 unsigned int rgb_cnt;
157 unsigned int cpu_cnt;
158 unsigned int dsi_cnt;
159 unsigned int edp_cnt;
160 struct sunxi_lcd hwlcd[LCD_NUM_MAX];
161 };
162
163 int sunxi_lcd_gpio_set_value(unsigned int lcd_id, unsigned int io_index, unsigned int data);
164 int sunxi_lcd_pin_cfg(unsigned int lcd_id, unsigned char enable);
165 int sunxi_lcd_power_enable(unsigned int lcd_id, u32 power_id);
166 int sunxi_lcd_power_disable(unsigned int lcd_id, u32 power_id);
167 unsigned int sunxi_lcd_get_tcon_id(unsigned int lcd_id);
168 unsigned int sunxi_lcd_get_type_id(unsigned int lcd_id);
169 struct panel_extend_para *sunxi_lcd_get_panel_ext_para(unsigned int lcd_id);
170
171
172 unsigned int sunxi_lcd_get_type(unsigned int lcd_id);
173 struct disp_panel_para *sunxi_lcd_get_panel_para(unsigned int lcd_id);
174
175
176 unsigned int sunxi_lcd_get_dclk(unsigned int lcd_id);
177 unsigned int sunxi_lcd_get_lcd_if(unsigned int lcd_id);
178 unsigned int sunxi_lcd_get_usec_per_line(unsigned int lcd_id);
179
180
181 bool sunxi_lcd_is_use_irq(unsigned int lcd_id);
182 unsigned int sunxi_lcd_get_irq_no(unsigned int lcd_id);
183
184 struct sunxi_lcd_funcs *sunxi_lcd_get_hw_funcs(int lcd_id);
185
186 int sunxi_lcd_module_init(void);
187 void sunxi_lcd_module_exit(void);
188
189 #ifndef CONFIG_AW_DRM_BACKLIGHT
sunxi_backlight_enable(unsigned int lcd_id)190 static inline int sunxi_backlight_enable(unsigned int lcd_id) { return 0; }
191
sunxi_backlight_disable(unsigned int lcd_id)192 static inline int sunxi_backlight_disable(unsigned int lcd_id) { return 0; }
193 #endif
194
195 #endif
196