NanoPayload

Annotated stage2/lcd.c

162:584ab53c6850
2016-04-24 Paul Boddie Added simple value display, merging the pixel type with the pattern to show the pixel type value in the test pattern.
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@162 66
u32 get_bitmap_value(unsigned short x, u32 value)
paul@162 67
{
paul@162 68
	return (value >> (((panel_info.vl_col - 1 - x) * 32) / panel_info.vl_col)) % 2 ? 0xffffffff : 0;
paul@162 69
}
paul@162 70
paul@138 71
static void get_colour(unsigned short h, unsigned short v, u8 rgb[], unsigned short pixel_type)
paul@100 72
{
paul@100 73
	unsigned short v_max = panel_info.vl_row;
paul@100 74
	unsigned short h_max = panel_info.vl_col;
paul@100 75
paul@138 76
	rgb[(pixel_type - 1) % 3] = div(h, h_max, 255);
paul@138 77
	rgb[pixel_type % 3] = div(v, v_max, 255);
paul@138 78
	rgb[(pixel_type + 1) % 3] = (rgb[0] + rgb[1]) / 2;
paul@101 79
}
paul@101 80
paul@161 81
static void set_pixel32(unsigned short h, unsigned short v, u32 value)
paul@161 82
{
paul@161 83
	u32 *pix = get_pixel32(h, v);
paul@161 84
	*pix = value;
paul@161 85
}
paul@161 86
paul@161 87
static void set_pixel16_565(unsigned short h, unsigned short v, u32 value)
paul@161 88
{
paul@161 89
	u16 *pix = get_pixel16(h, v);
paul@161 90
	*pix = (u16) value;
paul@161 91
}
paul@161 92
paul@161 93
static void set_pixel8(unsigned short h, unsigned short v, u32 value)
paul@161 94
{
paul@161 95
	u8 *pix = get_pixel8(h, v);
paul@161 96
	*pix = (u8) value;
paul@161 97
}
paul@161 98
paul@161 99
static void set_pixel4(unsigned short h, unsigned short v, u32 value)
paul@161 100
{
paul@161 101
	u8 *pix = get_pixel4(h, v);
paul@161 102
	u8 mask = h & 1 ? 0xf0 : 0x0f;
paul@161 103
	*pix = (*pix & mask) | ((u8) value);
paul@161 104
}
paul@161 105
paul@161 106
void set_pixel(unsigned short h, unsigned short v, u32 value)
paul@161 107
{
paul@161 108
	switch (panel_info.vl_bpix)
paul@161 109
	{
paul@161 110
		case LCD_COLOR32:
paul@161 111
		set_pixel32(h, v, value);
paul@161 112
		break;
paul@161 113
paul@161 114
		case LCD_COLOR8:
paul@161 115
		set_pixel8(h, v, value);
paul@161 116
		break;
paul@161 117
paul@161 118
		case LCD_COLOR4:
paul@161 119
		set_pixel4(h, v, value);
paul@161 120
		break;
paul@161 121
paul@161 122
		case LCD_COLOR16:
paul@161 123
		default:
paul@161 124
		set_pixel16_565(h, v, value);
paul@161 125
		break;
paul@161 126
	}
paul@161 127
}
paul@138 128
static void test_pixel32(unsigned short h, unsigned short v, unsigned short pixel_type)
paul@101 129
{
paul@104 130
	u8 rgb[3];
paul@104 131
paul@138 132
	get_colour(h, v, rgb, pixel_type);
paul@162 133
	set_pixel32(h, v, pixel(rgb[0], rgb[1], rgb[2], 255, 255, 255, 16, 8, 0) | get_bitmap_value(h, pixel_type));
paul@100 134
}
paul@100 135
paul@138 136
static void test_pixel16_565(unsigned short h, unsigned short v, unsigned short pixel_type)
paul@100 137
{
paul@104 138
	u8 rgb[3];
paul@104 139
paul@138 140
	get_colour(h, v, rgb, pixel_type);
paul@162 141
	set_pixel16_565(h, v, pixel(rgb[0], rgb[1], rgb[2], 31, 63, 31, 11, 5, 0) | get_bitmap_value(h, pixel_type));
paul@101 142
}
paul@100 143
paul@138 144
static void test_pixel8(unsigned short h, unsigned short v, unsigned short pixel_type)
paul@101 145
{
paul@104 146
	u8 rgb[3];
paul@104 147
paul@138 148
	get_colour(h, v, rgb, pixel_type);
paul@162 149
	set_pixel8(h, v, pixel(rgb[0], rgb[1], rgb[2], 7, 7, 3, 5, 2, 0) | get_bitmap_value(h, pixel_type));
paul@100 150
}
paul@100 151
paul@138 152
static void test_pixel4(unsigned short h, unsigned short v, unsigned short pixel_type)
paul@103 153
{
paul@104 154
	u8 rgb[3];
paul@104 155
paul@138 156
	get_colour(h, v, rgb, pixel_type);
paul@162 157
	set_pixel4(h, v, pixel(rgb[0], rgb[1], rgb[2], 1, 2, 1, 3, 1, 0) | get_bitmap_value(h, pixel_type));
paul@103 158
}
paul@103 159
paul@138 160
void test_pixel(unsigned short h, unsigned short v, unsigned short pixel_type)
paul@100 161
{
paul@100 162
	switch (panel_info.vl_bpix)
paul@100 163
	{
paul@100 164
		case LCD_COLOR32:
paul@138 165
		test_pixel32(h, v, pixel_type);
paul@100 166
		break;
paul@100 167
paul@101 168
		case LCD_COLOR8:
paul@138 169
		test_pixel8(h, v, pixel_type);
paul@101 170
		break;
paul@101 171
paul@103 172
		case LCD_COLOR4:
paul@138 173
		test_pixel4(h, v, pixel_type);
paul@103 174
		break;
paul@103 175
paul@101 176
		case LCD_COLOR16:
paul@100 177
		default:
paul@138 178
		test_pixel16_565(h, v, pixel_type);
paul@100 179
		break;
paul@100 180
	}
paul@100 181
}
paul@100 182
paul@100 183
void clear_pixel32(unsigned short h, unsigned short v)
paul@100 184
{
paul@100 185
	u32 *pix = get_pixel32(h, v);
paul@100 186
	*pix = 0;
paul@100 187
}
paul@100 188
paul@100 189
void clear_pixel16(unsigned short h, unsigned short v)
paul@100 190
{
paul@100 191
	u16 *pix = get_pixel16(h, v);
paul@100 192
	*pix = 0;
paul@68 193
}
paul@68 194
paul@101 195
void clear_pixel8(unsigned short h, unsigned short v)
paul@101 196
{
paul@101 197
	u8 *pix = get_pixel8(h, v);
paul@101 198
	*pix = 0;
paul@101 199
}
paul@101 200
paul@103 201
void clear_pixel4(unsigned short h, unsigned short v)
paul@103 202
{
paul@103 203
	u8 *pix = get_pixel4(h, v);
paul@103 204
	u8 mask = h & 1 ? 0xf0 : 0x0f;
paul@103 205
	*pix = *pix & mask;
paul@103 206
}
paul@103 207
paul@68 208
void clear_pixel(unsigned short h, unsigned short v)
paul@68 209
{
paul@100 210
	switch (panel_info.vl_bpix)
paul@100 211
	{
paul@100 212
		case LCD_COLOR32:
paul@100 213
		clear_pixel32(h, v);
paul@100 214
		break;
paul@68 215
paul@101 216
		case LCD_COLOR8:
paul@101 217
		clear_pixel8(h, v);
paul@101 218
		break;
paul@101 219
paul@103 220
		case LCD_COLOR4:
paul@103 221
		clear_pixel4(h, v);
paul@103 222
		break;
paul@103 223
paul@101 224
		case LCD_COLOR16:
paul@100 225
		default:
paul@100 226
		clear_pixel16(h, v);
paul@100 227
		break;
paul@100 228
	}
paul@68 229
}
paul@40 230
paul@100 231
void test_pattern()
paul@15 232
{
paul@15 233
	unsigned short v_max  = panel_info.vl_row;
paul@15 234
	unsigned short h_max  = panel_info.vl_col;
paul@15 235
	unsigned short v, h;
paul@68 236
paul@68 237
	for (v = 0; v < v_max; v += 1) {
paul@68 238
		for (h = 0; h < h_max; h += 1) {
paul@138 239
			test_pixel(h, v, 1);
paul@68 240
		}
paul@68 241
	}
paul@68 242
}
paul@68 243
paul@97 244
void lcd_clear(unsigned long lcd_base)
paul@68 245
{
paul@68 246
	unsigned short v_max  = panel_info.vl_row;
paul@68 247
	unsigned short h_max  = panel_info.vl_col;
paul@68 248
	unsigned short v, h;
paul@95 249
	unsigned long *pix = (unsigned long *)lcd_base;
paul@15 250
paul@22 251
	for (v = 0; v < v_max; v += 1) {
paul@22 252
		for (h = 0; h < h_max; h += 1) {
paul@68 253
			*pix++ = 0;
paul@15 254
		}
paul@15 255
	}
paul@15 256
}
paul@15 257
paul@15 258
/* LCD initialisation. */
paul@15 259
paul@15 260
void lcd_init(void)
paul@15 261
{
paul@20 262
	__lcd_display_pin_init();
paul@20 263
	__lcd_display_on();
paul@20 264
paul@97 265
	lcd_base = lcd_ctrl_init();
paul@15 266
	lcd_clear(lcd_base);
paul@15 267
	lcd_enable();
paul@15 268
}