mirror of
git://projects.qi-hardware.com/iris.git
synced 2025-03-22 05:18:52 +02:00
154 lines
4.0 KiB
COBOL
154 lines
4.0 KiB
COBOL
#pypp 0
|
|
// Iris: micro-kernel for a capability-based operating system.
|
|
// lcd.ccp: Display driver.
|
|
// Copyright 2009 Bas Wijnen <wijnen@debian.org>
|
|
//
|
|
// 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 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
#include <iris.h>
|
|
#include "jz4730.hh"
|
|
#include "devices.hh"
|
|
|
|
// Pin definitions, all in port 2.
|
|
#define PWM_ENABLE (1 << 30)
|
|
#define SPEN (1 << 0) //LCD_SPL
|
|
#define SPCK (1 << 1) //LCD_CLS
|
|
#define SPDA (1 << 2) //LCD_PS
|
|
#define LCD_RET (1 << 3) //LCD_REV //use for lcd reset
|
|
|
|
// level is in the range [0, 300]
|
|
static void set_backlight (unsigned level):
|
|
PWM_DUT (0) = level
|
|
if level:
|
|
PWM_CTR (0) = 0xbf
|
|
GPIO_GPDR (2) |= PWM_ENABLE
|
|
else:
|
|
PWM_CTR (0) = 0x3f
|
|
GPIO_GPDR (2) &= ~PWM_ENABLE
|
|
|
|
// Write to a register. Value must be in range [0, 0xff].
|
|
static void write_reg (unsigned reg, unsigned value):
|
|
unsigned data = (reg << 0xa) | 0x200 | value
|
|
GPIO_GPDR (2) |= SPEN
|
|
GPIO_GPDR (2) = (GPIO_GPDR (2) & ~SPDA) | SPCK
|
|
GPIO_GPDR (2) &= ~SPEN
|
|
udelay(25)
|
|
for unsigned i = 0; i < 16; ++i:
|
|
GPIO_GPDR (2) &= ~SPCK
|
|
if data & 0x8000:
|
|
GPIO_GPDR (2) |= SPDA
|
|
else:
|
|
GPIO_GPDR (2) &= ~SPDA
|
|
udelay (25)
|
|
GPIO_GPDR (2) |= SPCK
|
|
udelay (25)
|
|
data <<= 1
|
|
GPIO_GPDR (2) |= SPEN
|
|
udelay(200)
|
|
|
|
static void lcd_enable ():
|
|
udelay (50)
|
|
GPIO_GPDR (2) &= ~LCD_RET
|
|
mdelay(150)
|
|
GPIO_GPDR (2) |= LCD_RET
|
|
mdelay(10)
|
|
// These values have been copied from the linux source.
|
|
// I have no idea what they do.
|
|
write_reg (0x00, 0x03)
|
|
write_reg (0x01, 0x40)
|
|
write_reg (0x02, 0x11)
|
|
write_reg (0x03, 0xcd)
|
|
write_reg (0x04, 0x32)
|
|
write_reg (0x05, 0x0e)
|
|
write_reg (0x07, 0x03)
|
|
write_reg (0x08, 0x08)
|
|
write_reg (0x09, 0x32)
|
|
write_reg (0x0A, 0x88)
|
|
write_reg (0x0B, 0xc6)
|
|
write_reg (0x0C, 0x20)
|
|
write_reg (0x0D, 0x20)
|
|
set_backlight (300)
|
|
|
|
static void lcd_disable ():
|
|
write_reg (0x00, 0x03)
|
|
set_backlight (0)
|
|
|
|
static void reset ():
|
|
// Use gpio pins as pwm.
|
|
GPIO_GPAUR (2) = (GPIO_GPAUR (2) & ~0x0fffffff) | 0x50000000
|
|
// Use gpio pins as lcd master.
|
|
GPIO_GPALR (1) = (GPIO_GPALR (1) & ~0x0000ffff) | 0x55550000
|
|
GPIO_GPAUR (1) = 0x556a5555
|
|
|
|
// initialize things.
|
|
GPIO_GPIER (2) &= ~(PWM_ENABLE | LCD_RET | SPEN | SPCK | SPDA)
|
|
GPIO_GPDIR (2) |= PWM_ENABLE | LCD_RET | SPEN | SPCK | SPDA
|
|
udelay (50)
|
|
GPIO_GPDR (2) &= ~LCD_RET
|
|
mdelay (150)
|
|
GPIO_GPDR (2) |= LCD_RET
|
|
mdelay (10)
|
|
lcd_enable ()
|
|
|
|
// For now, support only 16 bpp.
|
|
// Screen is 800x480 tft.
|
|
LCD_CTRL = LCD_CTRL_BPP_16 | LCD_CTRL_BST_16
|
|
LCD_VSYNC = 20
|
|
LCD_HSYNC = 80
|
|
LCD_DAV = (20 << 16) | 500
|
|
LCD_DAH = (80 << 16) | 880
|
|
LCD_VAT = (880 << 16) | 500
|
|
//LCD_CFG = MODE_TFT_GEN | PCLK_N | VSYNC_N
|
|
|
|
// Stop lcd.
|
|
CPM_MSCR |= 1 << 7
|
|
|
|
unsigned pclk = 60 * (800 * 3 + 80) * 500
|
|
unsigned pllout = get_pllout ()
|
|
CPM_CFCR2 = pllout / pclk - 1
|
|
unsigned v = pllout / (pclk * 4) - 1
|
|
while v < 0xf && pllout / (v + 1) > 150000000:
|
|
++v
|
|
CPM_CFCR = (CPM_CFCR & ~CPM_CFCR_LFR_MASK) | (v << CPM_CFCR_LFR_BIT) | CPM_CFCR_UPE
|
|
|
|
// Start lcd.
|
|
CPM_MSCR &= ~(1 << 7)
|
|
mdelay (1)
|
|
|
|
static void map_io (unsigned physical, unsigned address):
|
|
Capability page = memory_create_page (__my_memory)
|
|
alloc_physical (page, physical, 0)
|
|
memory_map (__my_memory, page, address, 1)
|
|
//drop (page)
|
|
|
|
int main ():
|
|
map_gpio ()
|
|
map_pwm0 ()
|
|
map_lcd ()
|
|
map_cpm ()
|
|
|
|
reset ()
|
|
|
|
while true:
|
|
Message msg
|
|
if !wait (&msg):
|
|
continue
|
|
switch msg.protected_data:
|
|
case LCD_BACKLIGHT:
|
|
set_backlight (msg.data[0] > 300 ? 300 : msg.data[0])
|
|
break
|
|
case LCD_RESET:
|
|
reset ()
|
|
break
|