• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Allwinner SoCs display driver.
3  *
4  * Copyright (C) 2019 Allwinner.
5  *
6  * Author:zhengwanyu  <zhengwanyu@allwinnertech.com>
7  *
8  * This file is licensed under the terms of the GNU General Public
9  * License version 2.  This program is licensed "as is" without any
10  * warranty of any kind, whether express or implied.
11  */
12 
13 #include "sunxi_dsi.h"
14 
15 /**
16  * dsi module mode switch
17  * @id         :dsi id
18  * @param[IN]  :cmd_en: command mode enable
19  * @param[IN]  :lp_en: lower power mode enable
20  * @return     :0 if success
21  */
sunxi_dsi_mode_switch(struct sunxi_dsi * dsi,u32 cmd_en,u32 lp_en)22 s32 sunxi_dsi_mode_switch(struct sunxi_dsi *dsi, u32 cmd_en, u32 lp_en)
23 {
24 	s32 ret = -1;
25 
26 	if (dsi->tcon_mode == DISP_TCON_SLAVE_MODE)
27 		goto OUT;
28 
29 	ret = dsi_mode_switch(dsi->id, cmd_en, lp_en);
30 	if (dsi->tcon_mode == DISP_TCON_DUAL_DSI
31 		&& (dsi->id + 1) < DEVICE_DSI_NUM)
32 		ret = dsi_mode_switch(dsi->id + 1, cmd_en, lp_en);
33 	else if (dsi->tcon_mode != DISP_TCON_NORMAL_MODE
34 			&& dsi->tcon_mode != DISP_TCON_DUAL_DSI)
35 		ret = dsi_mode_switch(dsi->slave_tcon_num, cmd_en, lp_en);
36 
37 OUT:
38 	return ret;
39 }
40 
41 
sunxi_dsi_clk_en(struct sunxi_dsi * dsi,u32 en)42 static s32 sunxi_dsi_clk_en(struct sunxi_dsi *dsi, u32 en)
43 {
44 	s32 ret = -1;
45 
46 
47 	if (dsi->tcon_mode == DISP_TCON_SLAVE_MODE)
48 		goto OUT;
49 
50 	ret = dsi_clk_enable(dsi->id, en);
51 	if (dsi->tcon_mode == DISP_TCON_DUAL_DSI &&
52 	    dsi->id + 1 < DEVICE_DSI_NUM)
53 		ret = dsi_clk_enable(dsi->id + 1, en);
54 	else if (dsi->tcon_mode != DISP_TCON_NORMAL_MODE &&
55 		 dsi->tcon_mode != DISP_TCON_DUAL_DSI)
56 		ret = dsi_clk_enable(dsi->slave_tcon_num, en);
57 OUT:
58 	return ret;
59 }
60 
sunxi_dsi_clk_enable(struct sunxi_dsi * dsi)61 s32 sunxi_dsi_clk_enable(struct sunxi_dsi *dsi)
62 {
63 	return sunxi_dsi_clk_en(dsi, 1);
64 }
65 
sunxi_dsi_clk_disable(struct sunxi_dsi * dsi)66 s32 sunxi_dsi_clk_disable(struct sunxi_dsi *dsi)
67 {
68 	return sunxi_dsi_clk_en(dsi, 0);
69 }
70 
sunxi_dsi_dcs_wr(struct sunxi_dsi * dsi,u8 command,u8 * para,u32 para_num)71 static s32 sunxi_dsi_dcs_wr(struct sunxi_dsi *dsi, u8 command, u8 *para,
72 						u32 para_num)
73 {
74 	s32 ret = -1;
75 
76 
77 	if (dsi->tcon_mode == DISP_TCON_SLAVE_MODE)
78 		goto OUT;
79 
80 	ret = dsi_dcs_wr(dsi->id, command, para, para_num);
81 	if (dsi->tcon_mode == DISP_TCON_DUAL_DSI
82 		&& (dsi->id + 1) < DEVICE_DSI_NUM
83 		&& dsi->port_num == DISP_LCD_DSI_SINGLE_PORT)
84 		ret = dsi_dcs_wr(dsi->id + 1, command, para, para_num);
85 	else if (dsi->tcon_mode != DISP_TCON_NORMAL_MODE &&
86 		 dsi->tcon_mode != DISP_TCON_DUAL_DSI)
87 		ret = dsi_dcs_wr(dsi->slave_tcon_num, command, para,
88 				 para_num);
89 OUT:
90 	return ret;
91 }
92 
93 /**
94  * sunxi_dsi_dcs_wr - write command and para to mipi panel.
95  * @dsi: The index of screen.
96  * @command: Command to be transfer.
97  */
sunxi_dsi_dcs_write_0para(struct sunxi_dsi * dsi,u8 command)98 s32 sunxi_dsi_dcs_write_0para(struct sunxi_dsi *dsi, u8 command)
99 {
100 	u8 tmp[5];
101 
102 	sunxi_dsi_dcs_wr(dsi, command, tmp, 0);
103 
104 	return -1;
105 }
106 
107 /**
108  * sunxi_dsi_dcs_write_1para - write command and para to mipi panel.
109  * @dsi: The index of screen.
110  * @command: Command to be transfer.
111  * @paran: Para to be transfer.
112  */
sunxi_dsi_dcs_write_1para(struct sunxi_dsi * dsi,u8 command,u8 para1)113 s32 sunxi_dsi_dcs_write_1para(struct sunxi_dsi *dsi, u8 command, u8 para1)
114 {
115 	u8 tmp[5];
116 
117 	tmp[0] = para1;
118 	sunxi_dsi_dcs_wr(dsi, command, tmp, 1);
119 
120 	return -1;
121 }
122 
sunxi_dsi_dcs_write_2para(struct sunxi_dsi * dsi,u8 command,u8 para1,u8 para2)123 s32 sunxi_dsi_dcs_write_2para(struct sunxi_dsi *dsi, u8 command, u8 para1,
124 			u8 para2)
125 {
126 	u8 tmp[5];
127 
128 	tmp[0] = para1;
129 	tmp[1] = para2;
130 	sunxi_dsi_dcs_wr(dsi, command, tmp, 2);
131 
132 	return -1;
133 }
134 
sunxi_dsi_dcs_write_3para(struct sunxi_dsi * dsi,u8 command,u8 para1,u8 para2,u8 para3)135 s32 sunxi_dsi_dcs_write_3para(struct sunxi_dsi *dsi, u8 command, u8 para1,
136 			u8 para2, u8 para3)
137 {
138 	u8 tmp[5];
139 
140 	tmp[0] = para1;
141 	tmp[1] = para2;
142 	tmp[2] = para3;
143 	sunxi_dsi_dcs_wr(dsi, command, tmp, 3);
144 
145 	return -1;
146 }
147 
sunxi_dsi_dcs_write_4para(struct sunxi_dsi * dsi,u8 command,u8 para1,u8 para2,u8 para3,u8 para4)148 s32 sunxi_dsi_dcs_write_4para(struct sunxi_dsi *dsi, u8 command, u8 para1,
149 		u8 para2, u8 para3, u8 para4)
150 {
151 	u8 tmp[5];
152 
153 	tmp[0] = para1;
154 	tmp[1] = para2;
155 	tmp[2] = para3;
156 	tmp[3] = para4;
157 	sunxi_dsi_dcs_wr(dsi, command, tmp, 4);
158 
159 	return -1;
160 }
161 
sunxi_dsi_dcs_write_5para(struct sunxi_dsi * dsi,u8 command,u8 para1,u8 para2,u8 para3,u8 para4,u8 para5)162 s32 sunxi_dsi_dcs_write_5para(struct sunxi_dsi *dsi, u8 command, u8 para1,
163 		u8 para2, u8 para3, u8 para4, u8 para5)
164 {
165 	u8 tmp[5];
166 
167 	tmp[0] = para1;
168 	tmp[1] = para2;
169 	tmp[2] = para3;
170 	tmp[3] = para4;
171 	tmp[4] = para5;
172 	sunxi_dsi_dcs_wr(dsi, command, tmp, 5);
173 
174 	return -1;
175 }
176 
sunxi_dsi_dcs_write_6para(struct sunxi_dsi * dsi,u8 command,u8 para1,u8 para2,u8 para3,u8 para4,u8 para5,u8 para6)177 s32 sunxi_dsi_dcs_write_6para(struct sunxi_dsi *dsi, u8 command, u8 para1,
178 		u8 para2,  u8 para3, u8 para4, u8 para5, u8 para6)
179 {
180 	u8 tmp[6];
181 
182 	tmp[0] = para1;
183 	tmp[1] = para2;
184 	tmp[2] = para3;
185 	tmp[3] = para4;
186 	tmp[4] = para5;
187 	tmp[5] = para6;
188 	sunxi_dsi_dcs_wr(dsi, command, tmp, 6);
189 
190 	return -1;
191 }
192 
193 
sunxi_dsi_gen_wr(struct sunxi_dsi * dsi,u8 command,u8 * para,u32 para_num)194 s32 sunxi_dsi_gen_wr(struct sunxi_dsi *dsi,
195 			u8 command, u8 *para, u32 para_num)
196 {
197 	s32 ret = -1;
198 
199 	if (dsi->tcon_mode == DISP_TCON_SLAVE_MODE)
200 		goto OUT;
201 
202 	ret = dsi_gen_wr(dsi->id, command, para, para_num);
203 	if (dsi->tcon_mode == DISP_TCON_DUAL_DSI &&
204 		(dsi->id + 1) < DEVICE_DSI_NUM &&
205 			dsi->port_num == DISP_LCD_DSI_SINGLE_PORT)
206 		ret = dsi_gen_wr(dsi->id + 1, command, para, para_num);
207 	else if (dsi->tcon_mode != DISP_TCON_NORMAL_MODE &&
208 		 dsi->tcon_mode != DISP_TCON_DUAL_DSI)
209 		ret = dsi_gen_wr(dsi->slave_tcon_num, command, para,
210 				 para_num);
211 OUT:
212 	return ret;
213 }
214 
sunxi_dsi_gen_short_read(u32 id,u8 * para_p,u8 para_num,u8 * result)215 s32 sunxi_dsi_gen_short_read(u32 id, u8 *para_p, u8 para_num,
216 				    u8 *result)
217 {
218 	s32 ret = -1;
219 
220 	if (!result || !para_p || para_num > 2) {
221 		pr_err("[sunxi-dsi]error: wrong para\n");
222 		goto OUT;
223 	}
224 
225 	ret = dsi_gen_short_rd(id, para_p, para_num, result);
226 OUT:
227 	return ret;
228 }
229 
sunxi_dsi_dcs_read(u32 id,u8 cmd,u8 * result,u32 * num_p)230 s32 sunxi_dsi_dcs_read(u32 id, u8 cmd, u8 *result, u32 *num_p)
231 {
232 	s32 ret = -1;
233 
234 	if (!result || !num_p) {
235 		pr_err("[sunxi-dsi]error: wrong para\n");
236 		goto OUT;
237 	}
238 	ret = dsi_dcs_rd(id, cmd, result, num_p);
239 OUT:
240 	return ret;
241 }
242 
sunxi_set_max_ret_size(u32 id,u32 size)243 s32 sunxi_set_max_ret_size(u32 id, u32 size)
244 {
245 	return dsi_set_max_ret_size(id, size);
246 }
247 
sunxi_dsi_turn_on_peripheral_command(struct sunxi_dsi * dsi)248 s32 sunxi_dsi_turn_on_peripheral_command(struct sunxi_dsi *dsi)
249 {
250 #ifdef CONFIG_ARCH_SUN20IW1
251 	return 0;
252 #else
253 	return dsi_turn_on_peripheral_command(dsi->id);
254 #endif
255 }
256