NanoPayload

Annotated stage2/lcd.c

161:7c00cd887cad
2016-04-24 Paul Boddie Separated the pixel-setting operations from the text pixel functions.
paul@15 1
/*
paul@15 2
 * Ben NanoNote LCD initialisation, based on uboot-xburst and xburst-tools.
paul@15 3
 *
paul@33 4
 * Copyright (C) 2001-2002 Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
paul@90 5
 * Copyright (C) 2015, 2016 Paul Boddie <paul@boddie.org.uk>
paul@15 6
 *
paul@63 7
 * This program is free software: you can redistribute it and/or modify
paul@63 8
 * it under the terms of the GNU General Public License as published by
paul@63 9
 * the Free Software Foundation, either version 3 of the License, or
paul@63 10
 * (at your option) any later version.
paul@15 11
 *
paul@63 12
 * This program is distributed in the hope that it will be useful,
paul@63 13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
paul@63 14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
paul@63 15
 * GNU General Public License for more details.
paul@15 16
 *
paul@63 17
 * You should have received a copy of the GNU General Public License
paul@63 18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
paul@15 19
 */
paul@15 20
paul@155 21
#include "board-display.h"
paul@34 22
paul@15 23
#include "xburst_types.h"
paul@33 24
#include "jzlcd.h"
paul@33 25
#include "sdram.h"
paul@33 26
#include "board.h"
paul@15 27
paul@40 28
extern vidinfo_t panel_info;
paul@95 29
static unsigned long lcd_base;
paul@68 30
paul@100 31
static unsigned int get_line_length()
paul@100 32
{
paul@100 33
	return ALIGN((panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8, sizeof(u32));
paul@100 34
}
paul@100 35
paul@100 36
static u32 *get_pixel32(unsigned short h, unsigned short v)
paul@68 37
{
paul@100 38
	return (u32 *) (lcd_base + v * get_line_length()) + h;
paul@100 39
}
paul@68 40
paul@100 41
static u16 *get_pixel16(unsigned short h, unsigned short v)
paul@100 42
{
paul@100 43
	return (u16 *) (lcd_base + v * get_line_length()) + h;
paul@100 44
}
paul@100 45
paul@101 46
static u8 *get_pixel8(unsigned short h, unsigned short v)
paul@101 47
{
paul@101 48
	return (u8 *) (lcd_base + v * get_line_length()) + h;
paul@101 49
}
paul@101 50
paul@103 51
static u8 *get_pixel4(unsigned short h, unsigned short v)
paul@103 52
{
paul@103 53
	return (u8 *) (lcd_base + v * get_line_length()) + h / 2;
paul@103 54
}
paul@103 55
paul@103 56
static inline unsigned short div(unsigned short num, unsigned short denom, unsigned short scale)
paul@103 57
{
paul@103 58
	return (scale * num) / denom;
paul@103 59
}
paul@103 60
paul@161 61
static u32 pixel(u8 r, u8 g, u8 b, u8 rmax, u8 gmax, u8 bmax, u8 rshift, u8 gshift, u8 bshift)
paul@104 62
{
paul@104 63
	return (div(r, 255, rmax) << rshift) | (div(g, 255, gmax) << gshift) | (div(b, 255, bmax) << bshift);
paul@104 64
}
paul@104 65
paul@138 66
static void get_colour(unsigned short h, unsigned short v, u8 rgb[], unsigned short pixel_type)
paul@100 67
{
paul@100 68
	unsigned short v_max = panel_info.vl_row;
paul@100 69
	unsigned short h_max = panel_info.vl_col;
paul@100 70
paul@138 71
	rgb[(pixel_type - 1) % 3] = div(h, h_max, 255);
paul@138 72
	rgb[pixel_type % 3] = div(v, v_max, 255);
paul@138 73
	rgb[(pixel_type + 1) % 3] = (rgb[0] + rgb[1]) / 2;
paul@101 74
}
paul@101 75
paul@161 76
static void set_pixel32(unsigned short h, unsigned short v, u32 value)
paul@161 77
{
paul@161 78
	u32 *pix = get_pixel32(h, v);
paul@161 79
	*pix = value;
paul@161 80
}
paul@161 81
paul@161 82
static void set_pixel16_565(unsigned short h, unsigned short v, u32 value)
paul@161 83
{
paul@161 84
	u16 *pix = get_pixel16(h, v);
paul@161 85
	*pix = (u16) value;
paul@161 86
}
paul@161 87
paul@161 88
static void set_pixel8(unsigned short h, unsigned short v, u32 value)
paul@161 89
{
paul@161 90
	u8 *pix = get_pixel8(h, v);
paul@161 91
	*pix = (u8) value;
paul@161 92
}
paul@161 93
paul@161 94
static void set_pixel4(unsigned short h, unsigned short v, u32 value)
paul@161 95
{
paul@161 96
	u8 *pix = get_pixel4(h, v);
paul@161 97
	u8 mask = h & 1 ? 0xf0 : 0x0f;
paul@161 98
	*pix = (*pix & mask) | ((u8) value);
paul@161 99
}
paul@161 100
paul@161 101
void set_pixel(unsigned short h, unsigned short v, u32 value)
paul@161 102
{
paul@161 103
	switch (panel_info.vl_bpix)
paul@161 104
	{
paul@161 105
		case LCD_COLOR32:
paul@161 106
		set_pixel32(h, v, value);
paul@161 107
		break;
paul@161 108
paul@161 109
		case LCD_COLOR8:
paul@161 110
		set_pixel8(h, v, value);
paul@161 111
		break;
paul@161 112
paul@161 113
		case LCD_COLOR4:
paul@161 114
		set_pixel4(h, v, value);
paul@161 115
		break;
paul@161 116
paul@161 117
		case LCD_COLOR16:
paul@161 118
		default:
paul@161 119
		set_pixel16_565(h, v, value);
paul@161 120
		break;
paul@161 121
	}
paul@161 122
}
paul@138 123
static void test_pixel32(unsigned short h, unsigned short v, unsigned short pixel_type)
paul@101 124
{
paul@104 125
	u8 rgb[3];
paul@104 126
paul@138 127
	get_colour(h, v, rgb, pixel_type);
paul@161 128
	set_pixel32(h, v, pixel(rgb[0], rgb[1], rgb[2], 255, 255, 255, 16, 8, 0));
paul@100 129
}
paul@100 130
paul@138 131
static void test_pixel16_565(unsigned short h, unsigned short v, unsigned short pixel_type)
paul@100 132
{
paul@104 133
	u8 rgb[3];
paul@104 134
paul@138 135
	get_colour(h, v, rgb, pixel_type);
paul@161 136
	set_pixel16_565(h, v, pixel(rgb[0], rgb[1], rgb[2], 31, 63, 31, 11, 5, 0));
paul@101 137
}
paul@100 138
paul@138 139
static void test_pixel8(unsigned short h, unsigned short v, unsigned short pixel_type)
paul@101 140
{
paul@104 141
	u8 rgb[3];
paul@104 142
paul@138 143
	get_colour(h, v, rgb, pixel_type);
paul@161 144
	set_pixel8(h, v, pixel(rgb[0], rgb[1], rgb[2], 7, 7, 3, 5, 2, 0));
paul@100 145
}
paul@100 146
paul@138 147
static void test_pixel4(unsigned short h, unsigned short v, unsigned short pixel_type)
paul@103 148
{
paul@104 149
	u8 rgb[3];
paul@104 150
paul@138 151
	get_colour(h, v, rgb, pixel_type);
paul@161 152
	set_pixel4(h, v, pixel(rgb[0], rgb[1], rgb[2], 1, 2, 1, 3, 1, 0));
paul@103 153
}
paul@103 154
paul@138 155
void test_pixel(unsigned short h, unsigned short v, unsigned short pixel_type)
paul@100 156
{
paul@100 157
	switch (panel_info.vl_bpix)
paul@100 158
	{
paul@100 159
		case LCD_COLOR32:
paul@138 160
		test_pixel32(h, v, pixel_type);
paul@100 161
		break;
paul@100 162
paul@101 163
		case LCD_COLOR8:
paul@138 164
		test_pixel8(h, v, pixel_type);
paul@101 165
		break;
paul@101 166
paul@103 167
		case LCD_COLOR4:
paul@138 168
		test_pixel4(h, v, pixel_type);
paul@103 169
		break;
paul@103 170
paul@101 171
		case LCD_COLOR16:
paul@100 172
		default:
paul@138 173
		test_pixel16_565(h, v, pixel_type);
paul@100 174
		break;
paul@100 175
	}
paul@100 176
}
paul@100 177
paul@100 178
void clear_pixel32(unsigned short h, unsigned short v)
paul@100 179
{
paul@100 180
	u32 *pix = get_pixel32(h, v);
paul@100 181
	*pix = 0;
paul@100 182
}
paul@100 183
paul@100 184
void clear_pixel16(unsigned short h, unsigned short v)
paul@100 185
{
paul@100 186
	u16 *pix = get_pixel16(h, v);
paul@100 187
	*pix = 0;
paul@68 188
}
paul@68 189
paul@101 190
void clear_pixel8(unsigned short h, unsigned short v)
paul@101 191
{
paul@101 192
	u8 *pix = get_pixel8(h, v);
paul@101 193
	*pix = 0;
paul@101 194
}
paul@101 195
paul@103 196
void clear_pixel4(unsigned short h, unsigned short v)
paul@103 197
{
paul@103 198
	u8 *pix = get_pixel4(h, v);
paul@103 199
	u8 mask = h & 1 ? 0xf0 : 0x0f;
paul@103 200
	*pix = *pix & mask;
paul@103 201
}
paul@103 202
paul@68 203
void clear_pixel(unsigned short h, unsigned short v)
paul@68 204
{
paul@100 205
	switch (panel_info.vl_bpix)
paul@100 206
	{
paul@100 207
		case LCD_COLOR32:
paul@100 208
		clear_pixel32(h, v);
paul@100 209
		break;
paul@68 210
paul@101 211
		case LCD_COLOR8:
paul@101 212
		clear_pixel8(h, v);
paul@101 213
		break;
paul@101 214
paul@103 215
		case LCD_COLOR4:
paul@103 216
		clear_pixel4(h, v);
paul@103 217
		break;
paul@103 218
paul@101 219
		case LCD_COLOR16:
paul@100 220
		default:
paul@100 221
		clear_pixel16(h, v);
paul@100 222
		break;
paul@100 223
	}
paul@68 224
}
paul@40 225
paul@100 226
void test_pattern()
paul@15 227
{
paul@15 228
	unsigned short v_max  = panel_info.vl_row;
paul@15 229
	unsigned short h_max  = panel_info.vl_col;
paul@15 230
	unsigned short v, h;
paul@68 231
paul@68 232
	for (v = 0; v < v_max; v += 1) {
paul@68 233
		for (h = 0; h < h_max; h += 1) {
paul@138 234
			test_pixel(h, v, 1);
paul@68 235
		}
paul@68 236
	}
paul@68 237
}
paul@68 238
paul@97 239
void lcd_clear(unsigned long lcd_base)
paul@68 240
{
paul@68 241
	unsigned short v_max  = panel_info.vl_row;
paul@68 242
	unsigned short h_max  = panel_info.vl_col;
paul@68 243
	unsigned short v, h;
paul@95 244
	unsigned long *pix = (unsigned long *)lcd_base;
paul@15 245
paul@22 246
	for (v = 0; v < v_max; v += 1) {
paul@22 247
		for (h = 0; h < h_max; h += 1) {
paul@68 248
			*pix++ = 0;
paul@15 249
		}
paul@15 250
	}
paul@15 251
}
paul@15 252
paul@15 253
/* LCD initialisation. */
paul@15 254
paul@15 255
void lcd_init(void)
paul@15 256
{
paul@20 257
	__lcd_display_pin_init();
paul@20 258
	__lcd_display_on();
paul@20 259
paul@97 260
	lcd_base = lcd_ctrl_init();
paul@15 261
	lcd_clear(lcd_base);
paul@15 262
	lcd_enable();
paul@15 263
}