• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_eink.h"
12 
13 #define EE_CTL               (0x000)
14 #define EE_IRQ               (0x004)
15 #define EE_IDX_GEN           (0x008)
16 #define EE_IMG_SIZE          (0x00c)
17 #define EE_LAST_IMG_ADDR     (0x010)
18 #define EE_LAST_IMG_PITCH    (0x014)
19 #define EE_CURR_IMG_ADDR     (0x018)
20 #define EE_CURR_IMG_PITCH    (0x01c)
21 #define EE_LAST_IDX_ADDR     (0x020)
22 #define EE_IDX_WIN0          (0x024)
23 #define EE_IDX_WIN1          (0x028)
24 #define EE_NEW_IDX_ADDR      (0x02c)
25 
26 #define EE_PIPE_EN           (0x040)
27 #define EE_PIPE_WIN0         (0x044)
28 #define EE_PIPE_WIN1         (0x048)
29 #define EE_WAV_FILE_ADDR     (0x04c)
30 
31 #define EE_DEC_CTL           (0x150)
32 #define EE_DEC_IDX_ADDR      (0x154)
33 #define EE_DEC_WAV_ADDR      (0x158)
34 #define EE_DEC_WAV_PITCH     (0x15c)
35 
36 #define EDMA_GLB_CTL         (0x400)
37 #define EDMA_CTL             (0x404)
38 #define EDMA_WAV_ADDR        (0x408)
39 #define EDMA_WAV_PITCH       (0x40c)
40 #define EDMA_WAV_SIZE        (0x410)
41 #define EDMA_IMG_COOR        (0x414)
42 #define EDMA_IMG_SIZE        (0x418)
43 #define EDMA_PIXEL_VALUE     (0x41c)
44 
45 #define EDMA_WB_ADDR         (0x440)
46 #define EDMA_WB_STS          (0x444)
47 
48 static unsigned long ee_base;
49 
50 /* #define ee_writel writel */
51 /* #define ee_readl readl */
52 #define EINK_RUINT32(offset)          (*((volatile u32 *)((offset))))
53 #define EINK_WUINT32(value, offset)   (*((volatile u32 *)((offset))) = (value))
54 
55 
56 extern s32 disp_delay_us(u32 us);
57 extern s32 disp_delay_ms(u32 ms);
58 
eink_set_base(unsigned long reg_base)59 int eink_set_base(unsigned long reg_base)
60 {
61 	ee_base = reg_base;
62 
63 	return 0;
64 }
65 /*
66 *int eink_set_mode(unsigned char in_mode, unsigned char out_mode)
67 *{
68 *	unsigned int tmp;
69 *
70 *	tmp = ((out_mode&0x1)<<4)|(in_mode&0x3);
71 *	EINK_WUINT32(tmp,ee_base + EE_CTL);
72 *
73 *	return 0;
74 *
75 *}
76 */
eink_config(unsigned char in_mode,unsigned int out_mode)77 s32 eink_config(unsigned char in_mode, unsigned int out_mode)
78 {
79 	unsigned int tmp;
80 
81 	tmp = ((out_mode&0x1)<<4)|(in_mode&0x3);
82 	EINK_WUINT32(tmp, ee_base + EE_CTL);
83 
84 	return 0;
85 }
86 
eink_irq_enable(void)87 int eink_irq_enable(void)
88 {
89 	EINK_WUINT32(1<<4, ee_base + EE_IRQ);
90 
91 /*	unsigned int tmp;
92  *	tmp = EINK_RUINT32(ee_base + EE_IRQ);
93  *	pr_info("eink_irq_en 0x%x\n", tmp);
94  */
95 	return 0;
96 }
97 
eink_irq_disable(void)98 int eink_irq_disable(void)
99 {
100 	EINK_WUINT32(0, ee_base + EE_IRQ);
101 
102 	return 0;
103 }
104 
eink_irq_query(void)105 int eink_irq_query(void)
106 {
107 	unsigned int idx_irq, dec_irq;
108 	unsigned reg_val = 0;
109 
110 	reg_val = EINK_RUINT32(ee_base + EE_IRQ);
111 	dec_irq = reg_val&0x1;
112 	idx_irq = reg_val&0x2;
113 
114 	if (dec_irq == 0x1) {
115 		EINK_WUINT32(reg_val&0x1d, ee_base + EE_IRQ);
116 		return 0;
117 	}
118 	if (idx_irq == 0x2) {
119 		EINK_WUINT32(reg_val&0x1e, ee_base + EE_IRQ);
120 		return 1;
121 	}
122 	return -1;
123 }
124 
eink_irq_query_index(void)125 int eink_irq_query_index(void)
126 {
127 	unsigned int idx_irq;
128 	unsigned reg_val = 0;
129 
130 	reg_val = EINK_RUINT32(ee_base + EE_IRQ);
131 	idx_irq = reg_val&0x2;
132 
133 	if (idx_irq == 0x2) {
134 		EINK_WUINT32(reg_val&0x1e, ee_base + EE_IRQ);
135 		return 1;
136 	}
137 	return -1;
138 
139 }
140 
141 /*
142 int eink_start_idx (u32 disp, u32 old_index_data_paddr,
143 			u32 new_index_data_paddr, struct ee_img* last_image,
144 			struct ee_img* current_image, unsigned char flash_mode,
145 			unsigned char win_en, struct area_info* area)
146 {
147 	return 0;
148 
149 }
150 */
151 
eink_start_idx(struct ee_img * last_img,struct ee_img * curr_img,unsigned char flash_mode,unsigned char win_en,unsigned long last_idx_addr,unsigned long curr_idx_addr,struct area_info * info)152 int eink_start_idx(struct ee_img *last_img, struct ee_img *curr_img,
153 		unsigned char flash_mode, unsigned char win_en,
154 		unsigned long last_idx_addr, unsigned long curr_idx_addr,
155 		struct area_info *info)
156 {
157 	unsigned int tmp, w, h;
158 	unsigned int x, y;
159 
160 	x = 0;
161 	y = 0;
162 	w = last_img->w?(last_img->w-1)&0xfff:0;
163 	h = last_img->h?(last_img->h-1)&0xfff:0;
164 	tmp = ((h<<16)|w);
165 	EINK_WUINT32(tmp, ee_base + EE_IMG_SIZE);
166 	/* tmp = last_img->y*last_img->pitch + last_img->x + last_img->addr; */
167 	tmp = y*last_img->pitch + x + last_img->addr;
168 	EINK_WUINT32(tmp, ee_base + EE_LAST_IMG_ADDR);
169 	EINK_WUINT32(last_img->pitch, ee_base + EE_LAST_IMG_PITCH);
170 
171 	/* tmp = curr_img->y*curr_img->pitch + curr_img->x + curr_img->addr; */
172 
173 	tmp = y*curr_img->pitch + x + curr_img->addr;
174 	EINK_WUINT32(tmp, ee_base + EE_CURR_IMG_ADDR);
175 	EINK_WUINT32(curr_img->pitch, ee_base + EE_CURR_IMG_PITCH);
176 
177 	if (!win_en) {
178 		tmp = ((info->y_top&0xfff)<<16)|(info->x_top&0xfff);
179 		EINK_WUINT32(tmp, ee_base + EE_IDX_WIN0);
180 		tmp = ((info->y_bottom&0xfff)<<16)|(info->x_bottom&0xfff);
181 		EINK_WUINT32(tmp, ee_base + EE_IDX_WIN1);
182 	}
183 
184 	EINK_WUINT32(last_idx_addr, ee_base + EE_LAST_IDX_ADDR);
185 	EINK_WUINT32(curr_idx_addr, ee_base + EE_NEW_IDX_ADDR);
186 
187 	tmp = (flash_mode&0x3)<<8;
188 	tmp |= (win_en&0x1)<<4;
189 	tmp |= 0x1;
190 	EINK_WUINT32(tmp, ee_base + EE_IDX_GEN);
191 
192 	return 0;
193 }
194 
eink_index_finish(void)195 int eink_index_finish(void)
196 {
197 	unsigned int reg_val;
198 
199 	reg_val = EINK_RUINT32(ee_base + EE_IRQ)&0x2;
200 	if (reg_val == 0x2)
201 		return 1;
202 	else
203 		return 0;
204 }
205 
eink_get_updata_area(struct area_info * info)206 int eink_get_updata_area(struct area_info *info)
207 {
208 	unsigned int reg_val;
209 
210 	reg_val = EINK_RUINT32(ee_base + EE_IDX_WIN0);
211 	info->x_top = reg_val & 0xfff;
212 	info->y_top = (reg_val >> 16) & 0xfff;
213 
214 	reg_val = EINK_RUINT32(ee_base + EE_IDX_WIN1);
215 	info->x_bottom = reg_val & 0xfff;
216 	info->y_bottom = (reg_val >> 16) & 0xfff;
217 
218 	return 0;
219 }
220 
eink_pipe_enable(unsigned int pipe_no)221 int eink_pipe_enable(unsigned int pipe_no)
222 {
223 	unsigned int pipe_base;
224 	unsigned int reg_val;
225 
226 	pipe_base = ee_base + EE_PIPE_EN + (pipe_no << 4);
227 	EINK_WUINT32(0x1, pipe_base);
228 
229 	reg_val = EINK_RUINT32(pipe_base);
230 	return 0;
231 }
232 
eink_pipe_disable(unsigned int pipe_no)233 int eink_pipe_disable(unsigned int pipe_no)
234 {
235 	unsigned int pipe_base;
236 
237 	pipe_base = ee_base + EE_PIPE_EN + (pipe_no << 4);
238 	EINK_WUINT32(0x0, pipe_base);
239 
240 	return 0;
241 }
242 
eink_pipe_config(struct area_info * info,unsigned int pipe_no)243 int  eink_pipe_config(struct area_info *info, unsigned int pipe_no)
244 {
245 	unsigned int pipe_base, tmp;
246 
247 	tmp = ((info->y_top & 0xfff) << 16)|(info->x_top & 0xfff);
248 	pipe_base = ee_base + EE_PIPE_WIN0 + (pipe_no << 4);
249 	EINK_WUINT32(tmp, pipe_base);
250 
251 	tmp = ((info->y_bottom & 0xfff) << 16)|(info->x_bottom & 0xfff);
252 	pipe_base = ee_base + EE_PIPE_WIN1 + (pipe_no << 4);
253 	EINK_WUINT32(tmp, pipe_base);
254 /*
255 *	pipe_base = ee_base + EE_WAV_FILE_ADDR + (pipe_no<<4);
256 *	EINK_WUINT32(wav_file_addr,pipe_base);
257 */
258 	return 0;
259 }
260 
eink_pipe_config_wavefile(unsigned long wav_file_addr,unsigned int pipe_no)261 int eink_pipe_config_wavefile(unsigned long wav_file_addr, unsigned int pipe_no)
262 {
263 	unsigned int pipe_base;
264 
265 	pipe_base = ee_base + EE_WAV_FILE_ADDR + (pipe_no << 4);
266 	EINK_WUINT32(wav_file_addr, pipe_base);
267 
268 
269 	return 0;
270 }
271 
eink_decoder_start(unsigned long new_idx_addr,unsigned long wav_data_addr,struct eink_init_param * para)272 int eink_decoder_start(unsigned long new_idx_addr, unsigned long wav_data_addr,
273 						struct eink_init_param *para)
274 {
275 	unsigned int w, h, tmp;
276 
277 	w = para->timing.width ? (para->timing.width - 1) & 0xfff : 0;
278 	h = para->timing.height ? (para->timing.height - 1) & 0xfff : 0;
279 	tmp = ((h << 16) | w);
280 	EINK_WUINT32(tmp, ee_base + EE_IMG_SIZE);
281 
282 	tmp = para->eink_mode ? (((para->timing.lbl + para->timing.lsl +
283 					para->timing.lel) << 2) +
284 					(para->timing.width >> 1)) :
285 					(((para->timing.lbl + para->timing.lsl +
286 					   para->timing.lel) << 1) +
287 					 (para->timing.width >> 1));
288 	EINK_WUINT32(tmp, ee_base + EE_DEC_WAV_PITCH);
289 	EINK_WUINT32(new_idx_addr, ee_base + EE_DEC_IDX_ADDR);
290 
291 	tmp = para->eink_mode ? ((para->timing.fbl + para->timing.fsl) * tmp +
292 				((para->timing.lbl + para->timing.lsl) << 2)) :
293 				 ((para->timing.fbl + para->timing.fsl) * tmp +
294 				  ((para->timing.lbl + para->timing.lsl) << 1));
295 
296 	tmp += wav_data_addr;
297 	EINK_WUINT32(tmp, ee_base + EE_DEC_WAV_ADDR);
298 
299 	EINK_WUINT32(0x1, ee_base + EE_DEC_CTL);
300 
301 	return 0;
302 }
303 
eink_edma_init(unsigned char mode)304 int eink_edma_init(unsigned char mode)
305 {
306 	unsigned int tmp;
307 
308 	tmp = 0x1<<31;
309 	tmp |= (mode<<4);
310 	tmp |= 0x1;
311 	EINK_WUINT32(tmp, ee_base + EDMA_CTL);
312 
313 	tmp = 0x1<<31;
314 
315 
316 /*	tmp |= (0x1<<16); */
317 	EINK_WUINT32(tmp, ee_base + EDMA_GLB_CTL);
318 /*	tmp = EINK_RUINT32(ee_base + EDMA_GLB_CTL);*/
319 /*	eink_dbuf_rdy(); */
320 	return 0;
321 }
322 
eink_edma_cfg(unsigned long wav_addr,struct eink_init_param * para)323 int eink_edma_cfg(unsigned long wav_addr, struct eink_init_param *para)
324 {
325 	unsigned int tmp, w, h, hsync, vsync;
326 
327 	EINK_WUINT32(wav_addr, ee_base + EDMA_WAV_ADDR);
328 	hsync = para->timing.lbl + para->timing.lsl + para->timing.lel;
329 	vsync = para->timing.fbl + para->timing.fsl + para->timing.fel;
330 
331 	tmp = para->eink_mode ? (hsync << 3) : (hsync << 2);
332 	EINK_WUINT32(((para->timing.width + tmp) >> 1),
333 					ee_base + EDMA_WAV_PITCH);
334 	w = para->timing.width + tmp;
335 	w = w ? (w - 1) : 0;
336 	h = para->timing.height + vsync;
337 	h = h ? (h-1) : 0;
338 	tmp = (h << 16) | w;
339 	EINK_WUINT32(tmp, ee_base + EDMA_WAV_SIZE);
340 
341 	tmp = (para->timing.lbl + para->timing.lsl);
342 	tmp = para->eink_mode ? (tmp << 3) : (tmp << 2);
343 	tmp = ((para->timing.fbl + para->timing.fsl) << 16) | tmp;
344 	EINK_WUINT32(tmp, ee_base + EDMA_IMG_COOR);
345 	w = para->timing.width ? (para->timing.width - 1) : 0;
346 	h = para->timing.height ? (para->timing.height - 1) : 0;
347 	tmp = (h << 16) | w;
348 	EINK_WUINT32(tmp, ee_base + EDMA_IMG_SIZE);
349 
350 	return 0;
351 }
352 
eink_edma_cfg_addr(unsigned long wav_addr)353 int eink_edma_cfg_addr(unsigned long wav_addr)
354 {
355 
356 	EINK_WUINT32(wav_addr, ee_base + EDMA_WAV_ADDR);
357 /*
358 *	tmp = 0x1<<31;
359 *	tmp |= (0x1<<16);
360 *	tmp |= 0x1;
361 *	EINK_WUINT32(tmp,ee_base + EDMA_GLB_CTL);
362 */
363 	return 0;
364 }
365 
366 
eink_edma_en(unsigned char en)367 int eink_edma_en(unsigned char en)
368 {
369 	unsigned int tmp;
370 
371 	tmp = EINK_RUINT32(ee_base + EDMA_CTL);
372 	tmp |= en & 0x1;
373 	EINK_WUINT32(tmp, ee_base + EDMA_CTL);
374 
375 	return 0;
376 }
377 
eink_dbuf_rdy(void)378 int eink_dbuf_rdy(void)
379 {
380 	unsigned int tmp;
381 
382 	tmp = 0x1 << 31;
383 	tmp |= (0x1 << 16);
384 	tmp |= 0x1;
385 	EINK_WUINT32(tmp, ee_base + EDMA_GLB_CTL);
386 
387 	return 0;
388 }
389 
390 /* wb_en: default :0, enablen write back for debug */
eink_set_wb(unsigned char wb_en,unsigned long wb_addr)391 int  eink_set_wb(unsigned char wb_en, unsigned long wb_addr)
392 {
393 	unsigned int tmp;
394 
395 	tmp = 0x1 << 31;
396 	tmp |= (0x1 << 16);
397 	tmp |= wb_en ? (0x3 << 8) : 0x0;
398 	tmp |= 0x1;
399 	EINK_WUINT32(tmp, ee_base + EDMA_GLB_CTL);
400 	EINK_WUINT32(wb_addr, ee_base + EDMA_WB_ADDR);
401 
402 	return 0;
403 }
404 
405 
406