mirror of
git://projects.qi-hardware.com/iris.git
synced 2025-04-21 12:27:27 +03:00
lcd working
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
|
||||
__start:
|
||||
bal 1f
|
||||
__hack_label:
|
||||
nop
|
||||
.word _gp
|
||||
1:
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
// For some reason, it only works if the rows are input and the columns are output.
|
||||
|
||||
static void event (bool release, unsigned row, unsigned col):
|
||||
kdebug ((release ? 0x10000 : 0) | (row << 8) | col)
|
||||
|
||||
#define COL_MASK 0x2000ffff
|
||||
#define ROW_MASK 0x000000ff
|
||||
|
||||
@@ -20,6 +20,13 @@
|
||||
#define ARCH
|
||||
#include "arch.hh"
|
||||
|
||||
#define assert(x) do { while (!(x)) kdebug (0, 0); } while (0)
|
||||
|
||||
// For now, support only 16 bpp.
|
||||
// Screen is 800x480 tft.
|
||||
unsigned h = 800, v = 480, hs = 80, vs = 20, fps = 60, Bpp = 2
|
||||
#define frame_size (v * h * Bpp)
|
||||
|
||||
// Pin definitions, all in port 2.
|
||||
#define PWM_ENABLE (1 << 30)
|
||||
#define SPEN (1 << 0) //LCD_SPL
|
||||
@@ -37,22 +44,25 @@ static void set_backlight (bool state):
|
||||
PWM_CTR (0) = 0x3f
|
||||
GPIO_GPDR (2) &= ~PWM_ENABLE
|
||||
|
||||
static void reset ():
|
||||
struct Descriptor:
|
||||
unsigned next
|
||||
unsigned frame
|
||||
unsigned id
|
||||
unsigned cmd
|
||||
|
||||
static void reset (unsigned physical_descriptor):
|
||||
PWM_PER (0) = 300
|
||||
set_backlight (false)
|
||||
set_backlight (true)
|
||||
|
||||
// initialize things.
|
||||
GPIO_GPIER (2) &= ~(PWM_ENABLE | LCD_RET | SPEN | SPCK | SPDA)
|
||||
GPIO_GPDIR (2) |= PWM_ENABLE | LCD_RET | SPEN | SPCK | SPDA
|
||||
GPIO_GPDIR (2) |= PWM_ENABLE | LCD_RET
|
||||
udelay (50)
|
||||
GPIO_GPDR (2) &= ~LCD_RET
|
||||
ddelay (2)
|
||||
GPIO_GPDR (2) |= LCD_RET
|
||||
ddelay (1)
|
||||
|
||||
// For now, support only 16 bpp.
|
||||
// Screen is 800x480 tft.
|
||||
unsigned h = 800, v = 480, hs = 80, vs = 20, fps = 60, Bpp = 2
|
||||
LCD_CTRL = LCD_CTRL_BPP_16 | LCD_CTRL_BST_16
|
||||
LCD_VSYNC = vs
|
||||
LCD_HSYNC = hs
|
||||
@@ -60,55 +70,99 @@ static void reset ():
|
||||
LCD_DAH = (hs << 16) | (hs + h)
|
||||
LCD_VAT = ((hs + h) << 16) | (vs + v)
|
||||
#define MODE_TFT_GEN 0
|
||||
#define PCLK_N (1 << 10)
|
||||
#define VSYNC_N (1 << 8)
|
||||
LCD_CFG = MODE_TFT_GEN | PCLK_N | VSYNC_N
|
||||
LCD_CFG = MODE_TFT_GEN | VSYNC_N
|
||||
|
||||
cpm_stop_lcd ()
|
||||
|
||||
unsigned pllout = cpm_get_pllout ()
|
||||
unsigned pixclock = fps * (hs + h) * (vs + v)
|
||||
unsigned pllout = cpm_get_pllout ()
|
||||
CPM_CFCR2 = pllout / pixclock - 1
|
||||
|
||||
unsigned val = pllout / (pixclock * 4) - 1
|
||||
while val < 0xf && pllout / (val + 1) > 150000000:
|
||||
++val
|
||||
assert (pllout / (val + 1) <= 150000000)
|
||||
assert (val <= 0xf)
|
||||
cpm_set_lcdclk_div (val)
|
||||
CPM_CFCR |= CPM_CFCR_UPE
|
||||
|
||||
cpm_start_lcd ()
|
||||
|
||||
udelay (1000)
|
||||
//LCD_DA0 = framebuffer
|
||||
unsigned frame_size = v * h * Bpp
|
||||
LCD_CMD0 = LCD_CMD_SOFINT | LCD_CMD_EOFINT | (frame_size << LCD_CMD_LEN_BIT)
|
||||
LCD_DA0 = physical_descriptor
|
||||
lcd_set_ena ()
|
||||
lcd_enable_eof_intr ()
|
||||
|
||||
int main ():
|
||||
// TODO: The descriptor takes an entire uncached page, because I don't know how to force a cache write-back. It's much better to do that instead.
|
||||
map_gpio ()
|
||||
map_pwm0 ()
|
||||
map_lcd ()
|
||||
map_cpm ()
|
||||
|
||||
reset ()
|
||||
unsigned pages = (frame_size + 16 + ~PAGE_MASK) >> PAGE_BITS
|
||||
assert (pages > CAPPAGE_SIZE && pages <= 2 * CAPPAGE_SIZE)
|
||||
unsigned physical = alloc_range (__my_memory, pages)
|
||||
assert (physical)
|
||||
//Capability cappage[2]
|
||||
//unsigned base[2]
|
||||
//cappage[0] = memory_create_cappage (__my_memory, &base[0])
|
||||
//cappage[1] = memory_create_cappage (__my_memory, &base[1])
|
||||
for unsigned i = 0; i < CAPPAGE_SIZE; ++i:
|
||||
Capability page = memory_create_page (__my_memory)
|
||||
//cappage_set (cappage[0], page, i)
|
||||
alloc_physical (page, physical + i * PAGE_SIZE, 0, 1)
|
||||
memory_map (__my_memory, page, (unsigned)LCD_FRAMEBUFFER_BASE + i * PAGE_SIZE, 1)
|
||||
drop (page)
|
||||
for unsigned i = 0; i < pages - CAPPAGE_SIZE; ++i:
|
||||
Capability page = memory_create_page (__my_memory)
|
||||
//cappage_set (cappage[1], page, i)
|
||||
alloc_physical (page, physical + (i + CAPPAGE_SIZE) * PAGE_SIZE, 0, 1)
|
||||
memory_map (__my_memory, page, (unsigned)LCD_FRAMEBUFFER_BASE + (i + CAPPAGE_SIZE) * PAGE_SIZE, 1)
|
||||
drop (page)
|
||||
unsigned og = 0
|
||||
for unsigned y = 0; y < 480; ++y:
|
||||
unsigned g = (y << 6) / 480
|
||||
if g != og:
|
||||
og = g
|
||||
g = 0x3f
|
||||
unsigned olr = 0, ob = ((25 * y * y) << 5) / (9 * 800 * 800 + 25 * 480 * 480)
|
||||
for unsigned x = 0; x < 800; ++x:
|
||||
unsigned r = (x << 5) / 800
|
||||
unsigned b = ((9 * x * x + 25 * y * y) << 5) / (9 * 800 * 800 + 25 * 480 * 480)
|
||||
if r != olr:
|
||||
olr = r
|
||||
r = 0x1f
|
||||
unsigned oyb = b
|
||||
if y > 0:
|
||||
oyb = ((9 * x * x + 25 * (y - 1) * (y - 1)) << 5) / (9 * 800 * 800 + 25 * 480 * 480)
|
||||
if b != ob || b != oyb:
|
||||
ob = b
|
||||
b = 0x1f
|
||||
LCD_FRAMEBUFFER_BASE[y * 800 + x] = (r << 11) | (g << 5) | (b)
|
||||
Descriptor *descriptor = (Descriptor *)((unsigned)LCD_FRAMEBUFFER_BASE + frame_size)
|
||||
unsigned physical_descriptor = physical + frame_size
|
||||
descriptor->next = physical_descriptor
|
||||
descriptor->frame = physical
|
||||
descriptor->id = 0xdeadbeef
|
||||
descriptor->cmd = LCD_CMD_EOFINT | ((frame_size / 4) << LCD_CMD_LEN_BIT)
|
||||
reset (physical_descriptor)
|
||||
register_interrupt (IRQ_LCD)
|
||||
set_backlight (true)
|
||||
|
||||
while true:
|
||||
Message msg
|
||||
if !wait (&msg):
|
||||
continue
|
||||
wait (&msg)
|
||||
switch msg.protected_data:
|
||||
case IRQ_LCD:
|
||||
kdebug (0)
|
||||
LCD_STATE &= ~LCD_STATE_EOF
|
||||
lcd_clr_eof ()
|
||||
register_interrupt (IRQ_LCD)
|
||||
// TODO: allow callback
|
||||
break
|
||||
#if 0
|
||||
case LCD_BACKLIGHT:
|
||||
set_backlight (msg.data[0])
|
||||
break
|
||||
case LCD_RESET:
|
||||
reset ()
|
||||
//reset (physical_descriptor)
|
||||
break
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user