diff options
author | Frank Gevaerts <frank@gevaerts.be> | 2008-10-05 20:01:25 +0000 |
---|---|---|
committer | Frank Gevaerts <frank@gevaerts.be> | 2008-10-05 20:01:25 +0000 |
commit | 2d5e6e1a8792c71c765e2c8f6956cf71e6178b01 (patch) | |
tree | 1841b69b63954ab6daa89d3d9de0223d3063c202 | |
parent | 4450d3c9fe3cb21f1e5f3f3c839aa5d17d6fdcb8 (diff) | |
download | rockbox-2d5e6e1a8792c71c765e2c8f6956cf71e6178b01.tar.gz rockbox-2d5e6e1a8792c71c765e2c8f6956cf71e6178b01.zip |
LCD driver for meizu M3, new type (older M3s are not yet supported)
Thanks to Denes Balatoni
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18719 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | bootloader/meizu_m3.c | 29 | ||||
-rw-r--r-- | firmware/target/arm/s5l8700/meizu-m3/lcd-m3.c | 127 |
2 files changed, 134 insertions, 22 deletions
diff --git a/bootloader/meizu_m3.c b/bootloader/meizu_m3.c index cc9fbab88d..1c1f45a40a 100644 --- a/bootloader/meizu_m3.c +++ b/bootloader/meizu_m3.c | |||
@@ -101,6 +101,26 @@ void bl_debug_int(unsigned int input,unsigned int count) | |||
101 | 101 | ||
102 | void main(void) | 102 | void main(void) |
103 | { | 103 | { |
104 | char mystring[64]; | ||
105 | int tmpval; | ||
106 | |||
107 | /* set clock to 200 MHz */ | ||
108 | CLKCON = 0x00800080; | ||
109 | CLKCON2= 0x00; | ||
110 | PLL0PMS = 0x1ad200; | ||
111 | PLLCON = 1; | ||
112 | while (!(PLLLOCK & 1)) ; | ||
113 | CLKCON = 0x20802080; | ||
114 | |||
115 | /* mask all interrupts | ||
116 | this is done, because the lcd framebuffer | ||
117 | overwrites some stuff, which leads to a freeze | ||
118 | when an irq is generated after the dfu upload. | ||
119 | crt0 should have disabled irqs, | ||
120 | but the bootrom hands us execution in | ||
121 | user mode so we can't switch interrupts off */ | ||
122 | INTMSK = 0; | ||
123 | |||
104 | //Set backlight pin to output and enable | 124 | //Set backlight pin to output and enable |
105 | int oldval = PCON0; | 125 | int oldval = PCON0; |
106 | PCON0 = ((oldval & ~(3 << 4)) | (1 << 4)); | 126 | PCON0 = ((oldval & ~(3 << 4)) | (1 << 4)); |
@@ -110,6 +130,15 @@ void main(void) | |||
110 | oldval = PCON1; | 130 | oldval = PCON1; |
111 | PCON1 = ((oldval & ~(0xf << 16)) | (0 << 16)); | 131 | PCON1 = ((oldval & ~(0xf << 16)) | (0 << 16)); |
112 | 132 | ||
133 | asm volatile("mrs %0, cpsr \n\t" | ||
134 | : "=r" (tmpval) | ||
135 | ); | ||
136 | |||
137 | lcd_init(); | ||
138 | snprintf(mystring, 64, "tmpval: %x", tmpval); | ||
139 | lcd_putsxy(0,0,mystring); | ||
140 | lcd_update(); | ||
141 | |||
113 | init_qt1106(); | 142 | init_qt1106(); |
114 | 143 | ||
115 | // Wait for play to be pressed | 144 | // Wait for play to be pressed |
diff --git a/firmware/target/arm/s5l8700/meizu-m3/lcd-m3.c b/firmware/target/arm/s5l8700/meizu-m3/lcd-m3.c index 1affab3b01..3c2e8c646c 100644 --- a/firmware/target/arm/s5l8700/meizu-m3/lcd-m3.c +++ b/firmware/target/arm/s5l8700/meizu-m3/lcd-m3.c | |||
@@ -25,12 +25,14 @@ | |||
25 | #include "lcd.h" | 25 | #include "lcd.h" |
26 | #include "system.h" | 26 | #include "system.h" |
27 | #include "cpu.h" | 27 | #include "cpu.h" |
28 | #include "inttypes.h" | ||
29 | #include "s5l8700.h" | ||
28 | 30 | ||
29 | /*** definitions ***/ | 31 | /*** definitions ***/ |
30 | 32 | ||
31 | 33 | ||
32 | /** globals **/ | 34 | /** globals **/ |
33 | 35 | static uint8_t lcd_type; | |
34 | static int xoffset; /* needed for flip */ | 36 | static int xoffset; /* needed for flip */ |
35 | 37 | ||
36 | /*** hardware configuration ***/ | 38 | /*** hardware configuration ***/ |
@@ -64,10 +66,88 @@ void lcd_set_flip(bool yesno) | |||
64 | } | 66 | } |
65 | } | 67 | } |
66 | 68 | ||
69 | static void lcd_sleep(uint32_t t) { | ||
70 | uint32_t i; | ||
71 | |||
72 | for(i=0;i<t;++i) t=t; | ||
73 | } | ||
74 | |||
75 | static uint8_t lcd_readdata() { | ||
76 | LCD_RDATA = 0; | ||
77 | lcd_sleep(64); | ||
78 | return (LCD_DBUFF/* & 0xff*/); | ||
79 | } | ||
80 | |||
81 | void lcd_on() { | ||
82 | if (lcd_type == 1) { | ||
83 | LCD_WCMD = 0x29; | ||
84 | } else { | ||
85 | |||
86 | } | ||
87 | } | ||
88 | |||
89 | void lcd_off() { | ||
90 | /* FIXME wait for DMA to finnish */ | ||
91 | if (lcd_type == 1) { | ||
92 | LCD_WCMD = 0x28; | ||
93 | LCD_WDATA = 0; | ||
94 | } else { | ||
95 | |||
96 | } | ||
97 | } | ||
67 | 98 | ||
68 | /* LCD init */ | 99 | /* LCD init */ |
69 | void lcd_init_device(void) | 100 | void lcd_init_device(void) |
70 | { | 101 | { |
102 | uint8_t data[5]; | ||
103 | |||
104 | /* init basic things */ | ||
105 | PWRCON &= ~0x800; | ||
106 | PCON_ASRAM = 0x2; | ||
107 | PCON7 = 0x12222233; | ||
108 | |||
109 | LCD_CON = 0xca0; | ||
110 | LCD_PHTIME = 0; | ||
111 | LCD_INTCON = 0; | ||
112 | LCD_RST_TIME = 0x7ff; | ||
113 | |||
114 | /* detect lcd type */ | ||
115 | LCD_WCMD = 0x1; | ||
116 | lcd_sleep(166670); | ||
117 | LCD_WCMD = 0x11; | ||
118 | lcd_sleep(2000040); | ||
119 | lcd_readdata(); | ||
120 | LCD_WCMD = 0x4; | ||
121 | lcd_sleep(100); | ||
122 | data[0]=lcd_readdata(); | ||
123 | data[1]=lcd_readdata(); | ||
124 | data[2]=lcd_readdata(); | ||
125 | data[3]=lcd_readdata(); | ||
126 | data[4]=lcd_readdata(); | ||
127 | |||
128 | lcd_type=0; | ||
129 | if (((data[1]==0x38) && ((data[2] & 0xf0) == 0x80)) || | ||
130 | ((data[2]==0x38) && ((data[3] & 0xf0) == 0x80))) | ||
131 | lcd_type=1; | ||
132 | |||
133 | /* init lcd */ | ||
134 | if (lcd_type == 1) { | ||
135 | LCD_WCMD = 0x3a; | ||
136 | LCD_WDATA = 0x6; | ||
137 | LCD_WCMD = 0xab; | ||
138 | LCD_WCMD = 0x35; | ||
139 | LCD_WDATA = 0; | ||
140 | LCD_WCMD=0x13; | ||
141 | LCD_WCMD = 0x2a; | ||
142 | LCD_WDATA = 0; | ||
143 | LCD_WDATA = 0; | ||
144 | LCD_WCMD = 0x2b; | ||
145 | LCD_WDATA = 0; | ||
146 | LCD_WDATA = 0; | ||
147 | LCD_WCMD = 0x29; | ||
148 | } else { | ||
149 | |||
150 | } | ||
71 | } | 151 | } |
72 | 152 | ||
73 | /*** Update functions ***/ | 153 | /*** Update functions ***/ |
@@ -103,33 +183,36 @@ void lcd_blit_grey_phase_blit(unsigned char *values, unsigned char *phases, | |||
103 | void lcd_update(void) ICODE_ATTR; | 183 | void lcd_update(void) ICODE_ATTR; |
104 | void lcd_update(void) | 184 | void lcd_update(void) |
105 | { | 185 | { |
106 | int y; | 186 | int i; |
187 | fb_data *p; | ||
107 | 188 | ||
108 | /* Copy display bitmap to hardware */ | 189 | /* Copy display bitmap to hardware */ |
109 | for (y = 0; y < LCD_FBHEIGHT; y++) | 190 | if (lcd_type == 1) { |
110 | { | 191 | LCD_WCMD = 0x2a; |
111 | } | 192 | LCD_WDATA = 0; |
193 | LCD_WDATA = 0; | ||
194 | LCD_WDATA = 0; | ||
195 | LCD_WDATA = 0xaf; | ||
196 | LCD_WCMD = 0x2b; | ||
197 | LCD_WDATA = 0; | ||
198 | LCD_WDATA = 0; | ||
199 | LCD_WDATA = 0; | ||
200 | LCD_WDATA = 0x83; | ||
201 | LCD_WCMD = 0x2c; | ||
202 | for(p=&lcd_framebuffer[0][0], i=0;i<LCD_WIDTH*LCD_FBHEIGHT;++i, ++p) { | ||
203 | LCD_WDATA = RGB_UNPACK_RED(*p)<<3; | ||
204 | LCD_WDATA = RGB_UNPACK_GREEN(*p)<<2; | ||
205 | LCD_WDATA = RGB_UNPACK_BLUE(*p)<<3; | ||
206 | lcd_sleep(1); /* if data is sent too fast to lcdif, machine freezes */ | ||
207 | } | ||
208 | } else { | ||
209 | |||
210 | } | ||
112 | } | 211 | } |
113 | 212 | ||
114 | /* Update a fraction of the display. */ | 213 | /* Update a fraction of the display. */ |
115 | void lcd_update_rect(int, int, int, int) ICODE_ATTR; | 214 | void lcd_update_rect(int, int, int, int) ICODE_ATTR; |
116 | void lcd_update_rect(int x, int y, int width, int height) | 215 | void lcd_update_rect(int x, int y, int width, int height) |
117 | { | 216 | { |
118 | int ymax; | 217 | lcd_update(); |
119 | |||
120 | /* The Y coordinates have to work on even 8 pixel rows */ | ||
121 | ymax = (y + height-1) >> 3; | ||
122 | y >>= 3; | ||
123 | |||
124 | if(x + width > LCD_WIDTH) | ||
125 | width = LCD_WIDTH - x; | ||
126 | if (width <= 0) | ||
127 | return; /* nothing left to do, 0 is harmful to lcd_write_data() */ | ||
128 | if(ymax >= LCD_FBHEIGHT) | ||
129 | ymax = LCD_FBHEIGHT-1; | ||
130 | |||
131 | /* Copy specified rectange bitmap to hardware */ | ||
132 | for (; y <= ymax; y++) | ||
133 | { | ||
134 | } | ||
135 | } | 218 | } |