summaryrefslogtreecommitdiff
path: root/bsp/AE210P/driver/lcd/lcd.c
blob: 022a2838dd2c4094d7885ae6bcb6ce8940ba683f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include "hal.h"
#include "lcd/lcd.h"
#include "lcd-info.h"

#ifdef CONFIG_PLAT_AG101P_16MB
	#define LCD_BASE		0x00e10000
#else
	#define LCD_BASE		0x90600000
#endif

#define LCD_TIME0_OFFSET	0x00
#define LCD_TIME1_OFFSET	0x04
#define LCD_TIME2_OFFSET	0x08
#define LCD_BASE_OFFSET		0x10
#define LCD_INT_EN_OFFSET	0x18
#define LCD_CTRL_OFFSET		0x1C
#define LCD_INT_CLR_OFFSET	0x20
#define LCD_INT_MSK_OFFSET	0x24

static pixel_t _drv_lcd_fb[ LCD_PANEL_WIDTH * LCD_PANEL_HEIGHT] __attribute__((aligned (64)));
static pixel_t _drv_lcd_bg[ LCD_PANEL_WIDTH * LCD_PANEL_HEIGHT] __attribute__((aligned (64)));

static pixel_t *drv_lcd_fb = _drv_lcd_fb;
static pixel_t *drv_lcd_bg = _drv_lcd_bg;
extern void nds32_dcache_flush();

void drv_lcd_flip(void)
{
	pixel_t *tmp = drv_lcd_fb;

	drv_lcd_fb = drv_lcd_bg;
	drv_lcd_bg = tmp;

	OUT32(LCD_BASE + LCD_BASE_OFFSET, drv_lcd_fb);
}

pixel_t *drv_lcd_get_fb(void)
{
	return drv_lcd_fb;
}

pixel_t *drv_lcd_get_bg(void)
{
	return drv_lcd_bg;
}

void drv_lcd_get_param(int *width, int *height, int *bpp)
{
	if (width)
		*width = LCD_PANEL_WIDTH;

	if (height)
		*height = LCD_PANEL_HEIGHT;

	if (bpp)
		*bpp = LCD_PANEL_BPP;
}

void drv_lcd_fill_bg(void)
{
	pixel_t *base = drv_lcd_bg;

	int i, j;
	for (i = j = 0; j < LCD_PANEL_HEIGHT; j++) {
		for (i = 0; i < LCD_PANEL_WIDTH; i++) {
#if defined(CONFIG_COLOR_DEPTH16)
			if (i == 0 || i == (LCD_PANEL_WIDTH - 1) || j == 0 || j == (LCD_PANEL_HEIGHT - 1))
				*base++ = 0xFFFFu;
			else
				*base++ = 0x0000u;
#elif defined(CONFIG_COLOR_DEPTH24)
			if (i == 0 || i == (LCD_PANEL_WIDTH - 1) || j == 0 || j == (LCD_PANEL_HEIGHT - 1))
				*base++ = 0x00FFFFFFu;
			else
				*base++ = 0x00000000u;
#else
#error "COLOR DEPTH not supported!"
#endif
		}
	}
}

void drv_lcd_draw_bg(void)
{
	pixel_t *src = drv_lcd_bg;
	pixel_t *dst = drv_lcd_fb;

	int i = 0;
	while (i++ < LCD_PANEL_WIDTH * LCD_PANEL_HEIGHT)
		*dst++ = *src++;
}

static void _drv_lcd_init(void)
{
	OUT32(LCD_BASE + LCD_TIME0_OFFSET, LCD_TIME0);
	OUT32(LCD_BASE + LCD_TIME1_OFFSET, LCD_TIME1);
	OUT32(LCD_BASE + LCD_TIME2_OFFSET, LCD_TIME2);
	OUT32(LCD_BASE + LCD_CTRL_OFFSET, LCD_CTRL);

	OUT32(LCD_BASE + LCD_BASE_OFFSET, drv_lcd_fb);
}

void drv_lcd_draw_rect(int x, int w, int y, int h, int r, int g, int b)
{
	pixel_t *base = drv_lcd_fb;

	int i, j;
	for (i = y; i < y + h; i++)
		for (j = x; j < x + w; j++)
#if defined(CONFIG_COLOR_DEPTH16)
			base[ i * LCD_PANEL_WIDTH + j] = (pixel_t)(((r >> 3)  << 11) | ((g >> 2) << 5) | ((b >> 3)  << 0));
#elif defined(CONFIG_COLOR_DEPTH24)
			base[ i * LCD_PANEL_WIDTH + j] = (pixel_t)((r << 16) | (g << 8) | b);
#endif
	nds32_dcache_flush(); /* undefine CONFIG_CPU_DCACHE_WRITETHROUGH ,flush DCACHE for lcd screen */
}

void drv_lcd_erase_rect(int x, int w, int y, int h)
{
	pixel_t *base = drv_lcd_fb;

	int i, j;
	for (i = y; i < y + h; i++)
		for (j = x; j < x + w; j++)
			base[ i * LCD_PANEL_WIDTH + j] = drv_lcd_bg[ i * LCD_PANEL_WIDTH + j];
}

void draw_blk(int x, int y, int sz, int border, int r, int g, int b)
{
	drv_lcd_draw_rect(x, sz, y, sz, r, g, b);
	drv_lcd_draw_rect(x + border, sz - 2 * border, y + border, sz - 2 * border, r ^ 0xff, g ^ 0xff, b ^ 0xff);
}

int drv_lcd_init(void)
{
	_drv_lcd_init();
	drv_lcd_fill_bg();
	drv_lcd_draw_bg();
	drv_lcd_flip();

	return 0;
}