440872bb42
This speeds up partial updates quite a bit but what is more important it opens up a way to efficiently implement lcd_blit_yuv() using hw colorspace conversion. Tested on rk27generic, hm60x v1 and v2 and on ma9. Benchmark for hm60x v1 (by mortalis): HEAD patched 1/1 141fps 138fps 1/4 315fps 395fps Change-Id: I4cc115786c3139000fc14c49a7290e289cfd6c42
371 lines
8.2 KiB
C
371 lines
8.2 KiB
C
/***************************************************************************
|
|
* __________ __ ___.
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
* \/ \/ \/ \/ \/
|
|
* $Id$
|
|
*
|
|
* Copyright (C) 2011 Andrew Ryabinin
|
|
*
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
* KIND, either express or implied.
|
|
*
|
|
****************************************************************************/
|
|
|
|
|
|
#include "config.h"
|
|
#include "kernel.h"
|
|
#include "lcd.h"
|
|
#include "system.h"
|
|
#include "cpu.h"
|
|
#include "lcdif-rk27xx.h"
|
|
#include "lcd-target.h"
|
|
|
|
static bool display_on = false;
|
|
|
|
static void reset_lcd(void)
|
|
{
|
|
GPIO_PCCON |= (1<<7);
|
|
GPIO_PCDR &= ~(1<<7);
|
|
udelay(10);
|
|
GPIO_PCDR |= (1<<7);
|
|
udelay(5000);
|
|
}
|
|
|
|
void lcd_v1_display_init(void)
|
|
{
|
|
unsigned int x, y;
|
|
|
|
/* Driving ability setting */
|
|
lcd_write_reg(0x60, 0x00);
|
|
lcd_write_reg(0x61, 0x06);
|
|
lcd_write_reg(0x62, 0x00);
|
|
lcd_write_reg(0x63, 0xC8);
|
|
|
|
/* Gamma 2.2 Setting */
|
|
lcd_write_reg(0x40, 0x00);
|
|
lcd_write_reg(0x41, 0x40);
|
|
lcd_write_reg(0x42, 0x45);
|
|
lcd_write_reg(0x43, 0x01);
|
|
lcd_write_reg(0x44, 0x60);
|
|
lcd_write_reg(0x45, 0x05);
|
|
lcd_write_reg(0x46, 0x0C);
|
|
lcd_write_reg(0x47, 0xD1);
|
|
lcd_write_reg(0x48, 0x05);
|
|
|
|
lcd_write_reg(0x50, 0x75);
|
|
lcd_write_reg(0x51, 0x01);
|
|
lcd_write_reg(0x52, 0x67);
|
|
lcd_write_reg(0x53, 0x14);
|
|
lcd_write_reg(0x54, 0xF2);
|
|
lcd_write_reg(0x55, 0x07);
|
|
lcd_write_reg(0x56, 0x03);
|
|
lcd_write_reg(0x57, 0x49);
|
|
|
|
/* Power voltage setting */
|
|
lcd_write_reg(0x1F, 0x03);
|
|
lcd_write_reg(0x20, 0x00);
|
|
lcd_write_reg(0x24, 0x28);
|
|
lcd_write_reg(0x25, 0x45);
|
|
|
|
lcd_write_reg(0x23, 0x2F);
|
|
|
|
/* Power on setting */
|
|
lcd_write_reg(0x18, 0x44);
|
|
lcd_write_reg(0x21, 0x01);
|
|
lcd_write_reg(0x01, 0x00);
|
|
lcd_write_reg(0x1C, 0x03);
|
|
lcd_write_reg(0x19, 0x06);
|
|
udelay(5);
|
|
|
|
/* Display on setting */
|
|
lcd_write_reg(0x26, 0x84);
|
|
udelay(40);
|
|
lcd_write_reg(0x26, 0xB8);
|
|
udelay(40);
|
|
lcd_write_reg(0x26, 0xBC);
|
|
udelay(40);
|
|
|
|
/* Memmory access setting */
|
|
lcd_write_reg(0x16, 0x68);
|
|
/* Setup 16bit mode */
|
|
lcd_write_reg(0x17, 0x05);
|
|
|
|
/* Set GRAM area */
|
|
lcd_write_reg(0x02, 0x00);
|
|
lcd_write_reg(0x03, 0x00);
|
|
lcd_write_reg(0x04, 0x00);
|
|
lcd_write_reg(0x05, LCD_WIDTH - 1);
|
|
lcd_write_reg(0x06, 0x00);
|
|
lcd_write_reg(0x07, 0x00);
|
|
lcd_write_reg(0x08, 0x00);
|
|
lcd_write_reg(0x09, LCD_HEIGHT - 1);
|
|
|
|
/* Start GRAM write */
|
|
lcd_cmd(0x22);
|
|
|
|
for (x=0; x<LCD_WIDTH; x++)
|
|
for(y=0; y<LCD_HEIGHT; y++)
|
|
lcd_data(0x00);
|
|
|
|
display_on = true;
|
|
}
|
|
|
|
static void lcd_v1_enable (bool on)
|
|
{
|
|
if (on == display_on)
|
|
return;
|
|
|
|
lcdctrl_bypass(1);
|
|
LCDC_CTRL |= RGB24B;
|
|
|
|
if (on)
|
|
{
|
|
lcd_write_reg(0x18, 0x44);
|
|
lcd_write_reg(0x21, 0x01);
|
|
lcd_write_reg(0x01, 0x00);
|
|
lcd_write_reg(0x1C, 0x03);
|
|
lcd_write_reg(0x19, 0x06);
|
|
udelay(5);
|
|
lcd_write_reg(0x26, 0x84);
|
|
udelay(40);
|
|
lcd_write_reg(0x26, 0xB8);
|
|
udelay(40);
|
|
lcd_write_reg(0x26, 0xBC);
|
|
}
|
|
else
|
|
{
|
|
lcd_write_reg(0x26, 0xB8);
|
|
udelay(40);
|
|
lcd_write_reg(0x19, 0x01);
|
|
udelay(40);
|
|
lcd_write_reg(0x26, 0xA4);
|
|
udelay(40);
|
|
lcd_write_reg(0x26, 0x84);
|
|
udelay(40);
|
|
lcd_write_reg(0x1C, 0x00);
|
|
lcd_write_reg(0x01, 0x02);
|
|
lcd_write_reg(0x21, 0x00);
|
|
}
|
|
display_on = on;
|
|
|
|
LCDC_CTRL &= ~RGB24B;
|
|
}
|
|
|
|
static void lcd_v1_set_gram_area(int x_start, int y_start,
|
|
int x_end, int y_end)
|
|
{
|
|
lcdctrl_bypass(1);
|
|
LCDC_CTRL |= RGB24B;
|
|
|
|
lcd_write_reg(0x03, x_start);
|
|
lcd_write_reg(0x05, x_end);
|
|
lcd_write_reg(0x07, y_start);
|
|
lcd_write_reg(0x09, y_end);
|
|
|
|
lcd_cmd(0x22);
|
|
LCDC_CTRL &= ~RGB24B;
|
|
}
|
|
|
|
#ifdef HM60X
|
|
|
|
enum lcd_type_t lcd_type;
|
|
|
|
static void identify_lcd(void)
|
|
{
|
|
SCU_IOMUXB_CON &= ~(1<<2);
|
|
|
|
if (GPIO_PCDR & (1<<4))
|
|
{
|
|
lcd_type = LCD_V1;
|
|
}
|
|
else
|
|
{
|
|
lcd_type = LCD_v2;
|
|
}
|
|
}
|
|
|
|
static void lcd_v2_display_init(void)
|
|
{
|
|
unsigned int x, y;
|
|
|
|
lcd_write_reg(0xD0, 0x0003);
|
|
lcd_write_reg(0xEB, 0x0B00);
|
|
lcd_write_reg(0xEC, 0x00CF);
|
|
lcd_write_reg(0xC7, 0x030F);
|
|
|
|
lcd_write_reg(0x01, 0x001C);
|
|
lcd_write_reg(0x02, 0x0100);
|
|
lcd_write_reg(0x03, 0x1038);
|
|
lcd_write_reg(0x07, 0x0000);
|
|
lcd_write_reg(0x08, 0x0808);
|
|
lcd_write_reg(0x0F, 0x0901);
|
|
lcd_write_reg(0x10, 0x0000);
|
|
lcd_write_reg(0x11, 0x1B41);
|
|
lcd_write_reg(0x12, 0x2010);
|
|
lcd_write_reg(0x13, 0x0009);
|
|
lcd_write_reg(0x14, 0x4C65);
|
|
|
|
lcd_write_reg(0x30, 0x0000);
|
|
lcd_write_reg(0x31, 0x00DB);
|
|
lcd_write_reg(0x32, 0x0000);
|
|
lcd_write_reg(0x33, 0x0000);
|
|
lcd_write_reg(0x34, 0x00DB);
|
|
lcd_write_reg(0x35, 0x0000);
|
|
lcd_write_reg(0x36, 0x00AF);
|
|
lcd_write_reg(0x37, 0x0000);
|
|
lcd_write_reg(0x38, 0x00DB);
|
|
lcd_write_reg(0x39, 0x0000);
|
|
|
|
lcd_write_reg(0x50, 0x0000);
|
|
lcd_write_reg(0x51, 0x0705);
|
|
lcd_write_reg(0x52, 0x0C0A);
|
|
lcd_write_reg(0x53, 0x0401);
|
|
lcd_write_reg(0x54, 0x040C);
|
|
lcd_write_reg(0x55, 0x0608);
|
|
lcd_write_reg(0x56, 0x0000);
|
|
lcd_write_reg(0x57, 0x0104);
|
|
lcd_write_reg(0x58, 0x0E06);
|
|
lcd_write_reg(0x59, 0x060E);
|
|
|
|
lcd_write_reg(0x20, 0x0000);
|
|
lcd_write_reg(0x21, 0x0000);
|
|
|
|
lcd_write_reg(0x07, 0x1017);
|
|
|
|
lcd_cmd(0x22);
|
|
|
|
for (x=0; x<LCD_WIDTH; x++)
|
|
for(y=0; y<LCD_HEIGHT; y++)
|
|
lcd_data(0x00);
|
|
|
|
display_on = true;
|
|
}
|
|
|
|
static void lcd_v2_enable (bool on)
|
|
{
|
|
if (on == display_on)
|
|
return;
|
|
|
|
lcdctrl_bypass(1);
|
|
LCDC_CTRL |= RGB24B;
|
|
|
|
if (on)
|
|
{
|
|
lcd_write_reg(0x10, 0x0000);
|
|
lcd_write_reg(0x11, 0x1B41);
|
|
udelay(50000);
|
|
lcd_write_reg(0x07, 0x1017);
|
|
udelay(50000);
|
|
}
|
|
else
|
|
{
|
|
lcd_write_reg(0x07, 0x0000);
|
|
udelay(50000);
|
|
lcd_write_reg(0x11, 0x0001);
|
|
udelay(50000);
|
|
lcd_write_reg(0x10, 0x0001);
|
|
}
|
|
display_on = on;
|
|
|
|
LCDC_CTRL &= ~RGB24B;
|
|
|
|
}
|
|
|
|
static void lcd_v2_set_gram_area(int x_start, int y_start,
|
|
int x_end, int y_end)
|
|
{
|
|
lcdctrl_bypass(1);
|
|
LCDC_CTRL |= RGB24B;
|
|
|
|
lcd_write_reg(0x36, y_end);
|
|
lcd_write_reg(0x37, y_start);
|
|
lcd_write_reg(0x38, x_end);
|
|
lcd_write_reg(0x39, x_start);
|
|
|
|
/* set GRAM address */
|
|
lcd_write_reg(0x20, y_start);
|
|
lcd_write_reg(0x21, x_start);
|
|
|
|
lcd_cmd(0x22);
|
|
LCDC_CTRL &= ~RGB24B;
|
|
}
|
|
|
|
void lcd_display_init(void)
|
|
{
|
|
reset_lcd();
|
|
identify_lcd();
|
|
if (lcd_type == LCD_V1)
|
|
lcd_v1_display_init();
|
|
else
|
|
lcd_v2_display_init();
|
|
}
|
|
|
|
void lcd_enable (bool on)
|
|
{
|
|
if (lcd_type == LCD_V1)
|
|
lcd_v1_enable(on);
|
|
else
|
|
lcd_v2_enable(on);
|
|
}
|
|
|
|
void lcd_set_gram_area(int x_start, int y_start,
|
|
int x_end, int y_end)
|
|
{
|
|
if (lcd_type == LCD_V1)
|
|
lcd_v1_set_gram_area(x_start, y_start, x_end, y_end);
|
|
else
|
|
lcd_v2_set_gram_area(x_start, y_start, x_end, y_end);
|
|
}
|
|
|
|
#else /* HM801 */
|
|
|
|
void lcd_display_init(void)
|
|
{
|
|
reset_lcd();
|
|
lcd_v1_display_init();
|
|
}
|
|
|
|
void lcd_enable (bool on)
|
|
{
|
|
lcd_v1_enable(on);
|
|
}
|
|
|
|
void lcd_set_gram_area(int x_start, int y_start,
|
|
int x_end, int y_end)
|
|
{
|
|
lcd_v1_set_gram_area(x_start, y_start, x_end, y_end);
|
|
}
|
|
#endif
|
|
|
|
bool lcd_active()
|
|
{
|
|
return display_on;
|
|
}
|
|
|
|
/* Blit a YUV bitmap directly to the LCD
|
|
* provided by generic fallback in lcd-16bit-common.c
|
|
*/
|
|
#if 0
|
|
void lcd_blit_yuv(unsigned char * const src[3],
|
|
int src_x, int src_y, int stride,
|
|
int x, int y, int width, int height)
|
|
{
|
|
(void)src;
|
|
(void)src_x;
|
|
(void)src_y;
|
|
(void)stride;
|
|
(void)x;
|
|
(void)y;
|
|
(void)width;
|
|
(void)height;
|
|
}
|
|
#endif
|