NanoPayload

Annotated stage2/lcd.c

221:b4dcc2099e0f
2017-07-08 Paul Boddie Eliminate redundant members in vidinfo_t, adding a member referencing the framebuffer details, and changing the descriptor member name and type name. Note that the reference to the framebuffer details needs correcting for user mode usage.
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@217 5
 * Copyright (C) 2015, 2016, 2017 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@33 23
#include "jzlcd.h"
paul@33 24
#include "sdram.h"
paul@33 25
#include "board.h"
paul@15 26
paul@40 27
extern vidinfo_t panel_info;
paul@221 28
extern struct jzfb_info jzfb;
paul@221 29
static uint32_t lcd_base;
paul@68 30
paul@221 31
static uint16_t get_line_length()
paul@100 32
{
paul@221 33
	return ALIGN((panel_info.jz_fb->w * panel_info.jz_fb->bpp) / 8, sizeof(uint32_t));
paul@100 34
}
paul@100 35
paul@221 36
static uint32_t *get_pixel32(uint16_t h, uint16_t v)
paul@68 37
{
paul@217 38
	return (uint32_t *) (lcd_base + v * get_line_length()) + h;
paul@100 39
}
paul@68 40
paul@221 41
static uint16_t *get_pixel16(uint16_t h, uint16_t v)
paul@100 42
{
paul@217 43
	return (uint16_t *) (lcd_base + v * get_line_length()) + h;
paul@100 44
}
paul@100 45
paul@221 46
static uint8_t *get_pixel8(uint16_t h, uint16_t v)
paul@101 47
{
paul@217 48
	return (uint8_t *) (lcd_base + v * get_line_length()) + h;
paul@101 49
}
paul@101 50
paul@221 51
static uint8_t *get_pixel4(uint16_t h, uint16_t v)
paul@103 52
{
paul@217 53
	return (uint8_t *) (lcd_base + v * get_line_length()) + h / 2;
paul@103 54
}
paul@103 55
paul@221 56
static inline uint16_t div(uint16_t num, uint16_t denom, uint16_t scale)
paul@103 57
{
paul@103 58
	return (scale * num) / denom;
paul@103 59
}
paul@103 60
paul@217 61
static uint32_t pixel(uint8_t r, uint8_t g, uint8_t b, uint8_t rmax, uint8_t gmax, uint8_t bmax, uint8_t rshift, uint8_t gshift, uint8_t 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@221 66
uint32_t get_bitmap_value(uint16_t x, uint32_t value)
paul@162 67
{
paul@221 68
	return (value >> (((panel_info.jz_fb->w - 1 - x) * 32) / panel_info.jz_fb->w)) % 2 ? 0xffffffff : 0;
paul@162 69
}
paul@162 70
paul@221 71
static void get_colour(uint16_t h, uint16_t v, uint8_t rgb[], uint16_t pixel_type)
paul@100 72
{
paul@221 73
	uint16_t v_max = panel_info.jz_fb->h - 1;
paul@221 74
	uint16_t h_max = panel_info.jz_fb->w - 1;
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@221 81
static void set_pixel32(uint16_t h, uint16_t v, uint32_t value)
paul@161 82
{
paul@217 83
	uint32_t *pix = get_pixel32(h, v);
paul@161 84
	*pix = value;
paul@161 85
}
paul@161 86
paul@221 87
static void set_pixel16_565(uint16_t h, uint16_t v, uint32_t value)
paul@161 88
{
paul@217 89
	uint16_t *pix = get_pixel16(h, v);
paul@217 90
	*pix = (uint16_t) value;
paul@161 91
}
paul@161 92
paul@221 93
static void set_pixel8(uint16_t h, uint16_t v, uint32_t value)
paul@161 94
{
paul@217 95
	uint8_t *pix = get_pixel8(h, v);
paul@217 96
	*pix = (uint8_t) value;
paul@161 97
}
paul@161 98
paul@221 99
static void set_pixel4(uint16_t h, uint16_t v, uint32_t value)
paul@161 100
{
paul@217 101
	uint8_t *pix = get_pixel4(h, v);
paul@217 102
	uint8_t mask = h & 1 ? 0xf0 : 0x0f;
paul@217 103
	*pix = (*pix & mask) | ((uint8_t) value);
paul@161 104
}
paul@161 105
paul@221 106
void set_pixel(uint16_t h, uint16_t v, uint32_t value)
paul@161 107
{
paul@221 108
	switch (panel_info.jz_fb->bpp)
paul@161 109
	{
paul@221 110
		case 32:
paul@161 111
		set_pixel32(h, v, value);
paul@161 112
		break;
paul@161 113
paul@221 114
		case 8:
paul@161 115
		set_pixel8(h, v, value);
paul@161 116
		break;
paul@161 117
paul@221 118
		case 4:
paul@161 119
		set_pixel4(h, v, value);
paul@161 120
		break;
paul@161 121
paul@221 122
		case 16:
paul@161 123
		default:
paul@161 124
		set_pixel16_565(h, v, value);
paul@161 125
		break;
paul@161 126
	}
paul@161 127
}
paul@221 128
static void test_pixel32(uint16_t h, uint16_t v, uint16_t pixel_type)
paul@101 129
{
paul@217 130
	uint8_t 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@221 136
static void test_pixel16_565(uint16_t h, uint16_t v, uint16_t pixel_type)
paul@100 137
{
paul@217 138
	uint8_t 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@221 144
static void test_pixel8(uint16_t h, uint16_t v, uint16_t pixel_type)
paul@101 145
{
paul@217 146
	uint8_t 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@221 152
static void test_pixel4(uint16_t h, uint16_t v, uint16_t pixel_type)
paul@103 153
{
paul@217 154
	uint8_t 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@221 160
void test_pixel(uint16_t h, uint16_t v, uint16_t pixel_type)
paul@100 161
{
paul@221 162
	switch (panel_info.jz_fb->bpp)
paul@100 163
	{
paul@221 164
		case 32:
paul@138 165
		test_pixel32(h, v, pixel_type);
paul@100 166
		break;
paul@100 167
paul@221 168
		case 8:
paul@138 169
		test_pixel8(h, v, pixel_type);
paul@101 170
		break;
paul@101 171
paul@221 172
		case 4:
paul@138 173
		test_pixel4(h, v, pixel_type);
paul@103 174
		break;
paul@103 175
paul@221 176
		case 16:
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@221 183
void clear_pixel32(uint16_t h, uint16_t v)
paul@100 184
{
paul@217 185
	uint32_t *pix = get_pixel32(h, v);
paul@100 186
	*pix = 0;
paul@100 187
}
paul@100 188
paul@221 189
void clear_pixel16(uint16_t h, uint16_t v)
paul@100 190
{
paul@217 191
	uint16_t *pix = get_pixel16(h, v);
paul@100 192
	*pix = 0;
paul@68 193
}
paul@68 194
paul@221 195
void clear_pixel8(uint16_t h, uint16_t v)
paul@101 196
{
paul@217 197
	uint8_t *pix = get_pixel8(h, v);
paul@101 198
	*pix = 0;
paul@101 199
}
paul@101 200
paul@221 201
void clear_pixel4(uint16_t h, uint16_t v)
paul@103 202
{
paul@217 203
	uint8_t *pix = get_pixel4(h, v);
paul@217 204
	uint8_t mask = h & 1 ? 0xf0 : 0x0f;
paul@103 205
	*pix = *pix & mask;
paul@103 206
}
paul@103 207
paul@221 208
void clear_pixel(uint16_t h, uint16_t v)
paul@68 209
{
paul@221 210
	switch (panel_info.jz_fb->bpp)
paul@100 211
	{
paul@221 212
		case 32:
paul@100 213
		clear_pixel32(h, v);
paul@100 214
		break;
paul@68 215
paul@221 216
		case 8:
paul@101 217
		clear_pixel8(h, v);
paul@101 218
		break;
paul@101 219
paul@221 220
		case 4:
paul@103 221
		clear_pixel4(h, v);
paul@103 222
		break;
paul@103 223
paul@221 224
		case 16:
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@221 233
	uint16_t v_max  = panel_info.jz_fb->h;
paul@221 234
	uint16_t h_max  = panel_info.jz_fb->w;
paul@221 235
	uint16_t 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@221 244
void lcd_clear(uint32_t lcd_base)
paul@68 245
{
paul@221 246
	uint16_t v_max  = panel_info.jz_fb->h;
paul@221 247
	uint16_t h_max  = panel_info.jz_fb->w;
paul@221 248
	uint16_t v, h;
paul@221 249
	uint32_t *pix = (uint32_t *)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@195 260
void lcd_init()
paul@15 261
{
paul@20 262
	__lcd_display_pin_init();
paul@20 263
	__lcd_display_on();
paul@20 264
paul@221 265
	/* Initialise the member here since the address is otherwise invalid. */
paul@221 266
paul@221 267
	panel_info.jz_fb = (struct jzfb_info *) ((uint32_t) &jzfb & ~0x80000000);
paul@221 268
paul@97 269
	lcd_base = lcd_ctrl_init();
paul@15 270
	lcd_clear(lcd_base);
paul@15 271
	lcd_enable();
paul@15 272
}