forked from len0rd/rockbox
PP LCD drivers: * Optimised and cleaned up PP colour LCD drivers. Immeasurable speedup on iPod Color, huge speedup on small H10 (a factor of 3). Should be a bit faster on big H10 too. * Big H10 changed bitmap format, so needs reconfiguring + full rebuild. * Better register naming for the mono LCD bridge. Register names for the colour LCD bridge.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15082 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
e88ac4ce4a
commit
8aeed2d32e
9 changed files with 144 additions and 174 deletions
|
|
@ -39,7 +39,7 @@
|
||||||
#define LCD_WIDTH 160
|
#define LCD_WIDTH 160
|
||||||
#define LCD_HEIGHT 128
|
#define LCD_HEIGHT 128
|
||||||
#define LCD_DEPTH 16 /* 65536 colours */
|
#define LCD_DEPTH 16 /* 65536 colours */
|
||||||
#define LCD_PIXELFORMAT RGB565 /* rgb565 */
|
#define LCD_PIXELFORMAT RGB565SWAPPED /* rgb565 byte-swapped */
|
||||||
|
|
||||||
/* Define this if your LCD can be enabled/disabled */
|
/* Define this if your LCD can be enabled/disabled */
|
||||||
#define HAVE_LCD_ENABLE
|
#define HAVE_LCD_ENABLE
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,9 @@
|
||||||
#define DRAM_START 0x28000000
|
#define DRAM_START 0x28000000
|
||||||
|
|
||||||
/* LCD bridge */
|
/* LCD bridge */
|
||||||
#define LCD1_BASE (*(volatile unsigned long *)(0xc0001000))
|
#define LCD1_BASE 0xc0001000
|
||||||
|
|
||||||
|
#define LCD1_CONTROL (*(volatile unsigned long *)(0xc0001000))
|
||||||
#define LCD1_CMD (*(volatile unsigned long *)(0xc0001008))
|
#define LCD1_CMD (*(volatile unsigned long *)(0xc0001008))
|
||||||
#define LCD1_DATA (*(volatile unsigned long *)(0xc0001010))
|
#define LCD1_DATA (*(volatile unsigned long *)(0xc0001010))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -407,7 +407,9 @@
|
||||||
/* Note: didn't bother to see of levels 0 and 16 actually work */
|
/* Note: didn't bother to see of levels 0 and 16 actually work */
|
||||||
|
|
||||||
/* First ("mono") LCD bridge */
|
/* First ("mono") LCD bridge */
|
||||||
#define LCD1_BASE (*(volatile unsigned long *)(0x70003000))
|
#define LCD1_BASE 0x70003000
|
||||||
|
|
||||||
|
#define LCD1_CONTROL (*(volatile unsigned long *)(0x70003000))
|
||||||
#define LCD1_CMD (*(volatile unsigned long *)(0x70003008))
|
#define LCD1_CMD (*(volatile unsigned long *)(0x70003008))
|
||||||
#define LCD1_DATA (*(volatile unsigned long *)(0x70003010))
|
#define LCD1_DATA (*(volatile unsigned long *)(0x70003010))
|
||||||
|
|
||||||
|
|
@ -417,6 +419,21 @@
|
||||||
#define SERIAL0 (*(volatile unsigned long*)(0x70006000))
|
#define SERIAL0 (*(volatile unsigned long*)(0x70006000))
|
||||||
#define SERIAL1 (*(volatile unsigned long*)(0x70006040))
|
#define SERIAL1 (*(volatile unsigned long*)(0x70006040))
|
||||||
|
|
||||||
|
/* Second ("color") LCD bridge */
|
||||||
|
#define LCD2_BASE 0x70008a00
|
||||||
|
|
||||||
|
#define LCD2_PORT (*(volatile unsigned long*)(0x70008a0c))
|
||||||
|
#define LCD2_BLOCK_CTRL (*(volatile unsigned long*)(0x70008a20))
|
||||||
|
#define LCD2_BLOCK_CONFIG (*(volatile unsigned long*)(0x70008a24))
|
||||||
|
#define LCD2_BLOCK_DATA (*(volatile unsigned long*)(0x70008b00))
|
||||||
|
|
||||||
|
#define LCD2_BUSY_MASK 0x80000000
|
||||||
|
#define LCD2_CMD_MASK 0x80000000
|
||||||
|
#define LCD2_DATA_MASK 0x81000000
|
||||||
|
|
||||||
|
#define LCD2_BLOCK_READY 0x04000000
|
||||||
|
#define LCD2_BLOCK_TXOK 0x01000000
|
||||||
|
|
||||||
/* I2C */
|
/* I2C */
|
||||||
#define I2C_BASE 0x7000c000
|
#define I2C_BASE 0x7000c000
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,15 +30,6 @@
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
#include "hwcompat.h"
|
#include "hwcompat.h"
|
||||||
|
|
||||||
/* check if number of useconds has past */
|
|
||||||
static inline bool timer_check(int clock_start, int usecs)
|
|
||||||
{
|
|
||||||
return ((int)(USEC_TIMER - clock_start)) >= usecs;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define IPOD_LCD_BASE 0x70008a0c
|
|
||||||
#define IPOD_LCD_BUSY_MASK 0x80000000
|
|
||||||
|
|
||||||
/* LCD command codes for HD66789R */
|
/* LCD command codes for HD66789R */
|
||||||
#define LCD_CNTL_RAM_ADDR_SET 0x21
|
#define LCD_CNTL_RAM_ADDR_SET 0x21
|
||||||
#define LCD_CNTL_WRITE_TO_GRAM 0x22
|
#define LCD_CNTL_WRITE_TO_GRAM 0x22
|
||||||
|
|
@ -48,39 +39,25 @@ static inline bool timer_check(int clock_start, int usecs)
|
||||||
/*** globals ***/
|
/*** globals ***/
|
||||||
int lcd_type = 1; /* 0 = "old" Color/Photo, 1 = "new" Color & Nano */
|
int lcd_type = 1; /* 0 = "old" Color/Photo, 1 = "new" Color & Nano */
|
||||||
|
|
||||||
static void lcd_wait_write(void)
|
static inline void lcd_wait_write(void)
|
||||||
{
|
{
|
||||||
if ((inl(IPOD_LCD_BASE) & IPOD_LCD_BUSY_MASK) != 0) {
|
while (LCD2_PORT & LCD2_BUSY_MASK);
|
||||||
int start = USEC_TIMER;
|
|
||||||
|
|
||||||
do {
|
|
||||||
if ((inl(IPOD_LCD_BASE) & IPOD_LCD_BUSY_MASK) == 0) break;
|
|
||||||
} while (timer_check(start, 1000) == 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lcd_send_lo(int v)
|
static void lcd_cmd_data(unsigned cmd, unsigned data)
|
||||||
{
|
{
|
||||||
|
if (lcd_type == 0) { /* 16 bit transfers */
|
||||||
lcd_wait_write();
|
lcd_wait_write();
|
||||||
outl(v | 0x80000000, IPOD_LCD_BASE);
|
LCD2_PORT = LCD2_CMD_MASK | cmd;
|
||||||
}
|
|
||||||
|
|
||||||
static void lcd_send_hi(int v)
|
|
||||||
{
|
|
||||||
lcd_wait_write();
|
lcd_wait_write();
|
||||||
outl(v | 0x81000000, IPOD_LCD_BASE);
|
LCD2_PORT = LCD2_CMD_MASK | data;
|
||||||
}
|
|
||||||
|
|
||||||
static void lcd_cmd_data(int cmd, int data)
|
|
||||||
{
|
|
||||||
if (lcd_type == 0) {
|
|
||||||
lcd_send_lo(cmd);
|
|
||||||
lcd_send_lo(data);
|
|
||||||
} else {
|
} else {
|
||||||
lcd_send_lo(0x0);
|
lcd_wait_write();
|
||||||
lcd_send_lo(cmd);
|
LCD2_PORT = LCD2_CMD_MASK;
|
||||||
lcd_send_hi((data >> 8) & 0xff);
|
LCD2_PORT = LCD2_CMD_MASK | cmd;
|
||||||
lcd_send_hi(data & 0xff);
|
lcd_wait_write();
|
||||||
|
LCD2_PORT = LCD2_DATA_MASK | (data >> 8);
|
||||||
|
LCD2_PORT = LCD2_DATA_MASK | (data & 0xff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -229,8 +206,9 @@ void lcd_yuv_blit(unsigned char * const src[3],
|
||||||
lcd_cmd_data(LCD_CNTL_RAM_ADDR_SET, ((x0 << 8) | y0));
|
lcd_cmd_data(LCD_CNTL_RAM_ADDR_SET, ((x0 << 8) | y0));
|
||||||
|
|
||||||
/* start drawing */
|
/* start drawing */
|
||||||
lcd_send_lo(0x0);
|
lcd_wait_write();
|
||||||
lcd_send_lo(LCD_CNTL_WRITE_TO_GRAM);
|
LCD2_PORT = LCD2_CMD_MASK;
|
||||||
|
LCD2_PORT = (LCD2_CMD_MASK|LCD_CNTL_WRITE_TO_GRAM);
|
||||||
}
|
}
|
||||||
|
|
||||||
const int stride_div_csub_x = stride/CSUB_X;
|
const int stride_div_csub_x = stride/CSUB_X;
|
||||||
|
|
@ -257,8 +235,8 @@ void lcd_yuv_blit(unsigned char * const src[3],
|
||||||
fb_data pixel1,pixel2;
|
fb_data pixel1,pixel2;
|
||||||
|
|
||||||
if (h==0) {
|
if (h==0) {
|
||||||
while ((inl(0x70008a20) & 0x4000000) == 0);
|
while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_READY));
|
||||||
outl(0x0, 0x70008a24);
|
LCD2_BLOCK_CONFIG = 0;
|
||||||
|
|
||||||
if (height == 0) break;
|
if (height == 0) break;
|
||||||
|
|
||||||
|
|
@ -272,9 +250,9 @@ void lcd_yuv_blit(unsigned char * const src[3],
|
||||||
}
|
}
|
||||||
|
|
||||||
height -= h;
|
height -= h;
|
||||||
outl(0x10000080, 0x70008a20);
|
LCD2_BLOCK_CTRL = 0x10000080;
|
||||||
outl((pixels_to_write - 1) | 0xc0010000, 0x70008a24);
|
LCD2_BLOCK_CONFIG = 0xc0010000 | (pixels_to_write - 1);
|
||||||
outl(0x34000000, 0x70008a20);
|
LCD2_BLOCK_CTRL = 0x34000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
do
|
do
|
||||||
|
|
@ -368,10 +346,10 @@ void lcd_yuv_blit(unsigned char * const src[3],
|
||||||
bbits = blue2 >> 16 ;
|
bbits = blue2 >> 16 ;
|
||||||
pixel2 = swap16((rbits << 11) | (gbits << 5) | bbits);
|
pixel2 = swap16((rbits << 11) | (gbits << 5) | bbits);
|
||||||
|
|
||||||
while ((inl(0x70008a20) & 0x1000000) == 0);
|
while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_TXOK));
|
||||||
|
|
||||||
/* output 2 pixels */
|
/* output 2 pixels */
|
||||||
outl((pixel2<<16)|pixel1, 0x70008b00);
|
LCD2_BLOCK_DATA = (pixel2 << 16) | pixel1;
|
||||||
}
|
}
|
||||||
while (ysrc < row_end);
|
while (ysrc < row_end);
|
||||||
|
|
||||||
|
|
@ -379,8 +357,8 @@ void lcd_yuv_blit(unsigned char * const src[3],
|
||||||
h--;
|
h--;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((inl(0x70008a20) & 0x4000000) == 0);
|
while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_READY));
|
||||||
outl(0x0, 0x70008a24);
|
LCD2_BLOCK_CONFIG = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -389,8 +367,7 @@ void lcd_update_rect(int x, int y, int width, int height)
|
||||||
{
|
{
|
||||||
int y0, x0, y1, x1;
|
int y0, x0, y1, x1;
|
||||||
int newx,newwidth;
|
int newx,newwidth;
|
||||||
|
unsigned long *addr;
|
||||||
unsigned long *addr = (unsigned long *)lcd_framebuffer;
|
|
||||||
|
|
||||||
/* Ensure x and width are both even - so we can read 32-bit aligned
|
/* Ensure x and width are both even - so we can read 32-bit aligned
|
||||||
data from lcd_framebuffer */
|
data from lcd_framebuffer */
|
||||||
|
|
@ -449,8 +426,9 @@ void lcd_update_rect(int x, int y, int width, int height)
|
||||||
lcd_cmd_data(LCD_CNTL_RAM_ADDR_SET, ((x0 << 8) | y0));
|
lcd_cmd_data(LCD_CNTL_RAM_ADDR_SET, ((x0 << 8) | y0));
|
||||||
|
|
||||||
/* start drawing */
|
/* start drawing */
|
||||||
lcd_send_lo(0x0);
|
lcd_wait_write();
|
||||||
lcd_send_lo(LCD_CNTL_WRITE_TO_GRAM);
|
LCD2_PORT = LCD2_CMD_MASK;
|
||||||
|
LCD2_PORT = (LCD2_CMD_MASK|LCD_CNTL_WRITE_TO_GRAM);
|
||||||
}
|
}
|
||||||
|
|
||||||
addr = (unsigned long*)&lcd_framebuffer[y][x];
|
addr = (unsigned long*)&lcd_framebuffer[y][x];
|
||||||
|
|
@ -468,28 +446,26 @@ void lcd_update_rect(int x, int y, int width, int height)
|
||||||
pixels_to_write = (width * h) * 2;
|
pixels_to_write = (width * h) * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
outl(0x10000080, 0x70008a20);
|
LCD2_BLOCK_CTRL = 0x10000080;
|
||||||
outl((pixels_to_write - 1) | 0xc0010000, 0x70008a24);
|
LCD2_BLOCK_CONFIG = 0xc0010000 | (pixels_to_write - 1);
|
||||||
outl(0x34000000, 0x70008a20);
|
LCD2_BLOCK_CTRL = 0x34000000;
|
||||||
|
|
||||||
/* for each row */
|
/* for each row */
|
||||||
for (r = 0; r < h; r++) {
|
for (r = 0; r < h; r++) {
|
||||||
/* for each column */
|
/* for each column */
|
||||||
for (c = 0; c < width; c += 2) {
|
for (c = 0; c < width; c += 2) {
|
||||||
while ((inl(0x70008a20) & 0x1000000) == 0);
|
while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_TXOK));
|
||||||
|
|
||||||
/* output 2 pixels */
|
/* output 2 pixels */
|
||||||
outl(*(addr++), 0x70008b00);
|
LCD2_BLOCK_DATA = *addr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
addr += (LCD_WIDTH - width)/2;
|
addr += (LCD_WIDTH - width)/2;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((inl(0x70008a20) & 0x4000000) == 0);
|
while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_READY));
|
||||||
|
LCD2_BLOCK_CONFIG = 0;
|
||||||
|
|
||||||
outl(0x0, 0x70008a24);
|
height -= h;
|
||||||
|
|
||||||
height = height - h;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ static const unsigned char dibits[16] ICONST_ATTR = {
|
||||||
/* wait for LCD with timeout */
|
/* wait for LCD with timeout */
|
||||||
static inline void lcd_wait_write(void)
|
static inline void lcd_wait_write(void)
|
||||||
{
|
{
|
||||||
while (LCD1_BASE & LCD1_BUSY_MASK);
|
while (LCD1_CONTROL & LCD1_BUSY_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* send LCD data */
|
/* send LCD data */
|
||||||
|
|
@ -155,7 +155,7 @@ void lcd_init_device(void)
|
||||||
power_reg_h = 0x1100;
|
power_reg_h = 0x1100;
|
||||||
#elif defined IPOD_MINI2G
|
#elif defined IPOD_MINI2G
|
||||||
lcd_wait_write();
|
lcd_wait_write();
|
||||||
LCD1_BASE = (LCD1_BASE & ~0x1f00000) | 0x1700000;
|
LCD1_CONTROL = (LCD1_CONTROL & ~0x1f00000) | 0x1700000;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
lcd_cmd_and_data(R_POWER_CONTROL, POWER_REG_H | 0xc);
|
lcd_cmd_and_data(R_POWER_CONTROL, POWER_REG_H | 0xc);
|
||||||
|
|
|
||||||
|
|
@ -22,12 +22,6 @@
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
|
|
||||||
/* check if number of useconds has past */
|
|
||||||
static inline bool timer_check(int clock_start, int usecs)
|
|
||||||
{
|
|
||||||
return ((int)(USEC_TIMER - clock_start)) >= usecs;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Initialized in lcd_init_device() **/
|
/** Initialized in lcd_init_device() **/
|
||||||
/* Is the power turned on? */
|
/* Is the power turned on? */
|
||||||
static bool power_on;
|
static bool power_on;
|
||||||
|
|
@ -43,17 +37,6 @@ static int lcd_contrast;
|
||||||
/* Forward declarations */
|
/* Forward declarations */
|
||||||
static void lcd_display_off(void);
|
static void lcd_display_off(void);
|
||||||
|
|
||||||
/* Hardware address of LCD. Bits are:
|
|
||||||
* 31 - set to write, poll for completion.
|
|
||||||
* 24 - 0 for command, 1 for data
|
|
||||||
* 7..0 - command/data to send
|
|
||||||
* Commands/Data are always sent in 16-bits, msb first.
|
|
||||||
*/
|
|
||||||
#define LCD_BASE *(volatile unsigned int *)0x70008a0c
|
|
||||||
#define LCD_BUSY_MASK 0x80000000
|
|
||||||
#define LCD_CMD 0x80000000
|
|
||||||
#define LCD_DATA 0x81000000
|
|
||||||
|
|
||||||
/* register defines for the Renesas HD66773R */
|
/* register defines for the Renesas HD66773R */
|
||||||
#define R_START_OSC 0x00
|
#define R_START_OSC 0x00
|
||||||
#define R_DEVICE_CODE_READ 0x00
|
#define R_DEVICE_CODE_READ 0x00
|
||||||
|
|
@ -91,31 +74,34 @@ static void lcd_display_off(void);
|
||||||
|
|
||||||
static inline void lcd_wait_write(void)
|
static inline void lcd_wait_write(void)
|
||||||
{
|
{
|
||||||
if ((LCD_BASE & LCD_BUSY_MASK) != 0) {
|
while (LCD2_PORT & LCD2_BUSY_MASK);
|
||||||
int start = USEC_TIMER;
|
|
||||||
|
|
||||||
do {
|
|
||||||
if ((LCD_BASE & LCD_BUSY_MASK) == 0) break;
|
|
||||||
} while (timer_check(start, 1000) == 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send command */
|
/* Send command */
|
||||||
static inline void lcd_send_cmd(int v)
|
static inline void lcd_send_cmd(unsigned v)
|
||||||
{
|
{
|
||||||
lcd_wait_write();
|
lcd_wait_write();
|
||||||
LCD_BASE = 0x00000000 | LCD_CMD;
|
LCD2_PORT = LCD2_CMD_MASK;
|
||||||
LCD_BASE = v | LCD_CMD;
|
LCD2_PORT = LCD2_CMD_MASK | v;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send 16-bit data */
|
/* Send 16-bit data */
|
||||||
static inline void lcd_send_data(int v)
|
static inline void lcd_send_data(unsigned v)
|
||||||
{
|
{
|
||||||
lcd_wait_write();
|
lcd_wait_write();
|
||||||
LCD_BASE = ((v>>8) & 0xff) | LCD_DATA; /* Send MSB first */
|
LCD2_PORT = LCD2_DATA_MASK | (v >> 8); /* Send MSB first */
|
||||||
LCD_BASE = ( v & 0xff) | LCD_DATA;
|
LCD2_PORT = LCD2_DATA_MASK | (v & 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Send 16-bit data byte-swapped. Only needed until we can use block transfer. */
|
||||||
|
static inline void lcd_send_data_swapped(unsigned v)
|
||||||
|
{
|
||||||
|
lcd_wait_write();
|
||||||
|
LCD2_PORT = LCD2_DATA_MASK | (v & 0xff); /* Send LSB first */
|
||||||
|
LCD2_PORT = LCD2_DATA_MASK | (v >> 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Write value to register */
|
/* Write value to register */
|
||||||
static inline void lcd_write_reg(int reg, int val)
|
static inline void lcd_write_reg(int reg, int val)
|
||||||
{
|
{
|
||||||
|
|
@ -635,7 +621,7 @@ void lcd_update_rect(int x0, int y0, int width, int height)
|
||||||
/* for each column */
|
/* for each column */
|
||||||
for (c = 0; c < width; c++) {
|
for (c = 0; c < width; c++) {
|
||||||
/* output 1 pixel */
|
/* output 1 pixel */
|
||||||
lcd_send_data(*(addr++));
|
lcd_send_data_swapped(*addr++);
|
||||||
}
|
}
|
||||||
|
|
||||||
addr += LCD_WIDTH - width;
|
addr += LCD_WIDTH - width;
|
||||||
|
|
|
||||||
|
|
@ -22,23 +22,6 @@
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
|
|
||||||
/* check if number of useconds has past */
|
|
||||||
static inline bool timer_check(int clock_start, int usecs)
|
|
||||||
{
|
|
||||||
return ((int)(USEC_TIMER - clock_start)) >= usecs;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Hardware address of LCD. Bits are:
|
|
||||||
* 31 - set to write, poll for completion.
|
|
||||||
* 24 - 0 for command, 1 for data
|
|
||||||
* 7..0 - command/data to send
|
|
||||||
* Commands/Data are always sent in 16-bits, msb first.
|
|
||||||
*/
|
|
||||||
#define LCD_BASE *(volatile unsigned int *)0x70008a0c
|
|
||||||
#define LCD_BUSY_MASK 0x80000000
|
|
||||||
#define LCD_CMD 0x80000000
|
|
||||||
#define LCD_DATA 0x81000000
|
|
||||||
|
|
||||||
/* register defines for TL1771 */
|
/* register defines for TL1771 */
|
||||||
#define R_START_OSC 0x00
|
#define R_START_OSC 0x00
|
||||||
#define R_DEVICE_CODE_READ 0x00
|
#define R_DEVICE_CODE_READ 0x00
|
||||||
|
|
@ -72,38 +55,23 @@ static inline bool timer_check(int clock_start, int usecs)
|
||||||
|
|
||||||
static inline void lcd_wait_write(void)
|
static inline void lcd_wait_write(void)
|
||||||
{
|
{
|
||||||
if ((LCD_BASE & LCD_BUSY_MASK) != 0) {
|
while (LCD2_PORT & LCD2_BUSY_MASK);
|
||||||
int start = USEC_TIMER;
|
|
||||||
|
|
||||||
do {
|
|
||||||
if ((LCD_BASE & LCD_BUSY_MASK) == 0) break;
|
|
||||||
} while (timer_check(start, 1000) == 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send command */
|
/* Send command */
|
||||||
static inline void lcd_send_cmd(int v)
|
static inline void lcd_send_cmd(unsigned v)
|
||||||
{
|
{
|
||||||
lcd_wait_write();
|
lcd_wait_write();
|
||||||
LCD_BASE = 0x00000000 | LCD_CMD;
|
LCD2_PORT = LCD2_CMD_MASK;
|
||||||
LCD_BASE = v | LCD_CMD;
|
LCD2_PORT = LCD2_CMD_MASK | v;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send 16-bit data */
|
/* Send 16-bit data */
|
||||||
static inline void lcd_send_data(int v)
|
static inline void lcd_send_data(unsigned v)
|
||||||
{
|
{
|
||||||
lcd_wait_write();
|
lcd_wait_write();
|
||||||
LCD_BASE = ( v & 0xff) | LCD_DATA; /* Send MSB first */
|
LCD2_PORT = LCD2_DATA_MASK | (v >> 8); /* Send MSB first */
|
||||||
LCD_BASE = ((v>>8) & 0xff) | LCD_DATA;
|
LCD2_PORT = LCD2_DATA_MASK | (v & 0xff);
|
||||||
}
|
|
||||||
|
|
||||||
/* Send two 16-bit data */
|
|
||||||
static inline void lcd_send_data2(int v)
|
|
||||||
{
|
|
||||||
unsigned int vsr = v;
|
|
||||||
lcd_send_data(vsr);
|
|
||||||
vsr = v >> 16;
|
|
||||||
lcd_send_data(vsr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -181,17 +149,17 @@ void lcd_yuv_blit(unsigned char * const src[3],
|
||||||
y0 = y;
|
y0 = y;
|
||||||
y1 = y + height - 1;
|
y1 = y + height - 1;
|
||||||
|
|
||||||
/* start horiz << 8 | max horiz */
|
/* max horiz << 8 | start horiz */
|
||||||
lcd_send_cmd(R_HORIZ_RAM_ADDR_POS);
|
lcd_send_cmd(R_HORIZ_RAM_ADDR_POS);
|
||||||
lcd_send_data((x0 << 8) | x1);
|
lcd_send_data((x1 << 8) | x0);
|
||||||
|
|
||||||
/* start vert << 8 | max vert */
|
/* max vert << 8 | start vert */
|
||||||
lcd_send_cmd(R_VERT_RAM_ADDR_POS);
|
lcd_send_cmd(R_VERT_RAM_ADDR_POS);
|
||||||
lcd_send_data((y0 << 8) | y1);
|
lcd_send_data((y1 << 8) | y0);
|
||||||
|
|
||||||
/* start horiz << 8 | start vert */
|
/* start vert << 8 | start horiz */
|
||||||
lcd_send_cmd(R_RAM_ADDR_SET);
|
lcd_send_cmd(R_RAM_ADDR_SET);
|
||||||
lcd_send_data(((x0 << 8) | y0));
|
lcd_send_data((y0 << 8) | x0);
|
||||||
|
|
||||||
/* start drawing */
|
/* start drawing */
|
||||||
lcd_send_cmd(R_WRITE_DATA_2_GRAM);
|
lcd_send_cmd(R_WRITE_DATA_2_GRAM);
|
||||||
|
|
@ -302,12 +270,12 @@ void lcd_yuv_blit(unsigned char * const src[3],
|
||||||
rbits = red1 >> 16 ;
|
rbits = red1 >> 16 ;
|
||||||
gbits = green1 >> 15 ;
|
gbits = green1 >> 15 ;
|
||||||
bbits = blue1 >> 16 ;
|
bbits = blue1 >> 16 ;
|
||||||
lcd_send_data(swap16((rbits << 11) | (gbits << 5) | bbits));
|
lcd_send_data((rbits << 11) | (gbits << 5) | bbits);
|
||||||
|
|
||||||
rbits = red2 >> 16 ;
|
rbits = red2 >> 16 ;
|
||||||
gbits = green2 >> 15 ;
|
gbits = green2 >> 15 ;
|
||||||
bbits = blue2 >> 16 ;
|
bbits = blue2 >> 16 ;
|
||||||
lcd_send_data(swap16((rbits << 11) | (gbits << 5) | bbits));
|
lcd_send_data((rbits << 11) | (gbits << 5) | bbits);
|
||||||
}
|
}
|
||||||
while (ysrc < row_end);
|
while (ysrc < row_end);
|
||||||
|
|
||||||
|
|
@ -321,8 +289,7 @@ void lcd_update_rect(int x0, int y0, int width, int height)
|
||||||
{
|
{
|
||||||
int x1, y1;
|
int x1, y1;
|
||||||
int newx,newwidth;
|
int newx,newwidth;
|
||||||
|
unsigned long *addr;
|
||||||
unsigned long *addr = (unsigned long *)lcd_framebuffer;
|
|
||||||
|
|
||||||
/* Ensure x and width are both even - so we can read 32-bit aligned
|
/* Ensure x and width are both even - so we can read 32-bit aligned
|
||||||
data from lcd_framebuffer */
|
data from lcd_framebuffer */
|
||||||
|
|
@ -352,35 +319,57 @@ void lcd_update_rect(int x0, int y0, int width, int height)
|
||||||
x1 = t;
|
x1 = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* start horiz << 8 | max horiz */
|
/* max horiz << 8 | start horiz */
|
||||||
lcd_send_cmd(R_HORIZ_RAM_ADDR_POS);
|
lcd_send_cmd(R_HORIZ_RAM_ADDR_POS);
|
||||||
lcd_send_data((x0 << 8) | x1);
|
lcd_send_data((x1 << 8) | x0);
|
||||||
|
|
||||||
/* start vert << 8 | max vert */
|
/* max vert << 8 | start vert */
|
||||||
lcd_send_cmd(R_VERT_RAM_ADDR_POS);
|
lcd_send_cmd(R_VERT_RAM_ADDR_POS);
|
||||||
lcd_send_data((y0 << 8) | y1);
|
lcd_send_data((y1 << 8) | y0);
|
||||||
|
|
||||||
/* start horiz << 8 | start vert */
|
/* start vert << 8 | start horiz */
|
||||||
lcd_send_cmd(R_RAM_ADDR_SET);
|
lcd_send_cmd(R_RAM_ADDR_SET);
|
||||||
lcd_send_data(((x0 << 8) | y0));
|
lcd_send_data((y0 << 8) | x0);
|
||||||
|
|
||||||
/* start drawing */
|
/* start drawing */
|
||||||
lcd_send_cmd(R_WRITE_DATA_2_GRAM);
|
lcd_send_cmd(R_WRITE_DATA_2_GRAM);
|
||||||
|
|
||||||
addr = (unsigned long*)&lcd_framebuffer[y0][x0];
|
addr = (unsigned long*)&lcd_framebuffer[y0][x0];
|
||||||
|
|
||||||
|
while (height > 0) {
|
||||||
int c, r;
|
int c, r;
|
||||||
|
int h, pixels_to_write;
|
||||||
|
|
||||||
/* for each row */
|
pixels_to_write = (width * height) * 2;
|
||||||
for (r = 0; r < height; r++) {
|
h = height;
|
||||||
/* for each column */
|
|
||||||
for (c = 0; c < width; c += 2) {
|
/* calculate how much we can do in one go */
|
||||||
/* output 2 pixels */
|
if (pixels_to_write > 0x10000) {
|
||||||
lcd_send_data2(*(addr++));
|
h = (0x10000/2) / width;
|
||||||
|
pixels_to_write = (width * h) * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LCD2_BLOCK_CTRL = 0x10000080;
|
||||||
|
LCD2_BLOCK_CONFIG = 0xc0010000 | (pixels_to_write - 1);
|
||||||
|
LCD2_BLOCK_CTRL = 0x34000000;
|
||||||
|
|
||||||
|
/* for each row */
|
||||||
|
for (r = 0; r < h; r++) {
|
||||||
|
/* for each column */
|
||||||
|
for (c = 0; c < width; c += 2) {
|
||||||
|
while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_TXOK));
|
||||||
|
|
||||||
|
/* output 2 pixels */
|
||||||
|
LCD2_BLOCK_DATA = *addr++;
|
||||||
|
}
|
||||||
addr += (LCD_WIDTH - width)/2;
|
addr += (LCD_WIDTH - width)/2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_READY));
|
||||||
|
LCD2_BLOCK_CONFIG = 0;
|
||||||
|
|
||||||
|
height -= h;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update the display.
|
/* Update the display.
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@
|
||||||
/* wait for LCD */
|
/* wait for LCD */
|
||||||
static inline void lcd_wait_write(void)
|
static inline void lcd_wait_write(void)
|
||||||
{
|
{
|
||||||
while (LCD1_BASE & LCD1_BUSY_MASK);
|
while (LCD1_CONTROL & LCD1_BUSY_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* send LCD data */
|
/* send LCD data */
|
||||||
|
|
@ -91,13 +91,13 @@ void lcd_init_device(void)
|
||||||
DEV_INIT &= ~0x400;
|
DEV_INIT &= ~0x400;
|
||||||
udelay(10000);
|
udelay(10000);
|
||||||
|
|
||||||
LCD1_BASE &= ~0x4;
|
LCD1_CONTROL &= ~0x4;
|
||||||
udelay(15);
|
udelay(15);
|
||||||
|
|
||||||
LCD1_BASE |= 0x4;
|
LCD1_CONTROL |= 0x4;
|
||||||
udelay(10);
|
udelay(10);
|
||||||
|
|
||||||
LCD1_BASE = 0x4687;
|
LCD1_CONTROL = 0x4687;
|
||||||
udelay(10000);
|
udelay(10000);
|
||||||
|
|
||||||
lcd_send_command(R_STANDBY_OFF);
|
lcd_send_command(R_STANDBY_OFF);
|
||||||
|
|
|
||||||
2
tools/configure
vendored
2
tools/configure
vendored
|
|
@ -941,7 +941,7 @@ EOF
|
||||||
arm7tdmicc
|
arm7tdmicc
|
||||||
tool="$rootdir/tools/scramble -mi4v3 -model=h10 -type=RBOS"
|
tool="$rootdir/tools/scramble -mi4v3 -model=h10 -type=RBOS"
|
||||||
bmp2rb_mono="$rootdir/tools/bmp2rb -f 0"
|
bmp2rb_mono="$rootdir/tools/bmp2rb -f 0"
|
||||||
bmp2rb_native="$rootdir/tools/bmp2rb -f 4"
|
bmp2rb_native="$rootdir/tools/bmp2rb -f 5"
|
||||||
output="rockbox.mi4"
|
output="rockbox.mi4"
|
||||||
appextra="recorder:gui"
|
appextra="recorder:gui"
|
||||||
archosrom=""
|
archosrom=""
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue