-
Notifications
You must be signed in to change notification settings - Fork 2
/
mlc.c
125 lines (107 loc) · 3.58 KB
/
mlc.c
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
/* mlc.c -- Basic Multi-Layer Controller (MLC) Driver for displaying boot
* splash screen.
*
* Copyright 2007 LeapFrog Enterprises Inc.
*
* Andrey Yurovsky <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include "include/autoconf.h" /* for partition info */
#include "include/mach-types.h" /* for machine info */
#include <platform.h>
#include <common.h>
#include "include/board.h"
#include "include/mlc_hal.h"
#define MLC32(x) REG32(LF1000_MLC_BASE+x)
#define R5G6B5(r,g,b) (((r&0x1F)<<11) | ((g&0x3F)<<5) | (b&0x1F))
#define MLC_LOCK_SIZE 8
#ifdef CPU_LF1000
#define MLC_PRIORITY 0
#else /* CPU_MF2530F */
#define MLC_PRIORITY 3
#endif
/*
* Basic MLC initialization: our goal is just to bring up Layer 0 so that it
* can be used to display an RGB splash screen.
*/
void mlc_init(void)
{
/* dynamic bus clock, PCLK on CPU access */
MLC32(MLCCLKENB) &= ~(0xF);
MLC32(MLCCLKENB) |= (2<<BCLKMODE);
/* set resolution */
MLC32(MLCSCREENSIZE) = (((X_RESOLUTION-1)<<SCREENWIDTH)|
((Y_RESOLUTION-1)<<SCREENHEIGHT));
/* set up layer priority, turn off field */
MLC32(MLCCONTROLT) &= ~((0x3<<PRIORITY)|(1<<FIELDENB));
MLC32(MLCCONTROLT) |= (MLC_PRIORITY<<PRIORITY);
/* make the background white */
MLC32(MLCBGCOLOR) = 0xFFFFFF;
/*
* Set up Layer 0
*/
#if 1
MLC32(MLCADDRESS0) = FRAME_BUFFER_ADDR;
MLC32(MLCCONTROL0) &= ~(3<<LOCKSIZE);
MLC32(MLCCONTROL0) |= ((MLC_LOCK_SIZE/8)<<LOCKSIZE);
MLC32(MLCHSTRIDE0) = 1; /* 1 bytes per pixel */
MLC32(MLCVSTRIDE0) = 1*X_RESOLUTION;
#ifdef CPU_LF1000
MLC32(MLCLEFTRIGHT0) = ((0<<LEFT)|((X_RESOLUTION-1)<<RIGHT));
MLC32(MLCTOPBOTTOM0) = ((0<<TOP)|((Y_RESOLUTION-1)<<BOTTOM));
#elif defined CPU_MF2530F
MLC32(MLCLEFTOP0) = ((0<<TOP)|(0<<LEFT));
MLC32(MLCRIGHTBOTTOM0) = (((X_RESOLUTION-1)<<RIGHT)|
((Y_RESOLUTION-1)<<BOTTOM));
#endif
MLC32(MLCCONTROL0) &= ~(0xFFFF<<FORMAT);
// MLC32(MLCCONTROL0) |= (0xC653<<FORMAT); /* B8G8R8 */
MLC32(MLCCONTROL0) |= (0x443a<<FORMAT); /* PTR5G6B5 */
MLC32(MLCCONTROL0) |= (0x3<<PALETTESLD);
MLC32(MLCPALETTE0) = R5G6B5(0,0,0x1F);
MLC32(MLCPALETTE0) = (0xFF<<24) | R5G6B5(0x1F,0x3F,0x1F);
MLC32(MLCPALETTE0) = (0x1<<24) | R5G6B5(0x0,0x0,0x0);
MLC32(MLCPALETTE0) = (0x2<<24) | R5G6B5(0x1F,0x0,0x0);
MLC32(MLCPALETTE0) = (0x3<<24) | R5G6B5(0x1F,0x0,0x0);
MLC32(MLCCONTROL0) |= (1<<DIRTYFLAG);
/*
* Turn on Layer 0
*/
#ifdef CPU_LF1000
BIT_SET(MLC32(MLCCONTROL0), PALETTEPWD); /* power up */
BIT_SET(MLC32(MLCCONTROL0), PALETTESLD); /* unsleep */
#endif
BIT_SET(MLC32(MLCCONTROL0), LAYERENB); /* enable */
BIT_SET(MLC32(MLCCONTROL0), DIRTYFLAG); /* apply */
#else
mlc_set_video_mode();
#endif
/*
* Finally, turn on the MLC!
*/
#ifdef CPU_LF1000
BIT_SET(MLC32(MLCCONTROLT), PIXELBUFFER_PWD); /* power up */
BIT_SET(MLC32(MLCCONTROLT), PIXELBUFFER_SLD); /* unsleep */
#endif
BIT_SET(MLC32(MLCCONTROLT), MLCENB); /* enable */
BIT_SET(MLC32(MLCCONTROLT), DITTYFLAG); /* apply */
}
void mlc_set_palette_entry(u8 p, u8 r, u8 g, u8 b)
{
u32 idx = p;
MLC32(MLCPALETTE0) = (idx << 24) | R5G6B5(r,g,b);
MLC32(MLCCONTROL0) |= (1<<DIRTYFLAG);
}
void mlc_set_video_mode(void) {
MLC32(MLCADDRESS0) = FRAME_BUFFER_ADDR;
MLC32(MLCCONTROL0) &= ~(3<<LOCKSIZE);
MLC32(MLCCONTROL0) |= ((MLC_LOCK_SIZE/8)<<LOCKSIZE);
MLC32(MLCHSTRIDE0) = 3; /* 3 bytes per pixel */
MLC32(MLCVSTRIDE0) = 3*X_RESOLUTION;
MLC32(MLCCONTROL0) &= ~(0xFFFF<<FORMAT);
MLC32(MLCCONTROL0) |= (0xC653<<FORMAT); /* B8G8R8 */
MLC32(MLCCONTROL0) |= (1<<DIRTYFLAG);
}