1
0
mirror of git://projects.qi-hardware.com/iris.git synced 2025-04-21 12:27:27 +03:00

working on things

This commit is contained in:
Bas Wijnen
2009-06-10 22:54:12 +02:00
parent 1bb67efc75
commit 8445be58dd
11 changed files with 160 additions and 360 deletions

View File

@@ -1,8 +1,11 @@
#pypp 0
#ifndef __JZ4730_HH__
#define __JZ4730_HH__
#include <iris.h>
#define JZ_EXTAL 3686400
// Base addresses are the place where the pages are mapped.
#define HARB_BASE 0x00000000
#define EMC_BASE 0x00001000
@@ -115,6 +118,10 @@ static void __map_io (unsigned physical, unsigned mapping):
#define map_uprt() do { __map_io (UPRT_PHYSICAL, UPRT_BASE); } while (0)
#define map_kbc() do { __map_io (KBC_PHYSICAL, KBC_BASE); } while (0)
#define REG8(x) (*(volatile unsigned char *)(x))
#define REG16(x) (*(volatile unsigned short *)(x))
#define REG32(x) (*(volatile unsigned *)(x))
/*************************************************************************
* MSC
*************************************************************************/
@@ -2255,6 +2262,14 @@ static void __map_io (unsigned physical, unsigned mapping):
//################### operations ######################################
static __inline__ void udelay (unsigned us):
for unsigned i = 0; i < us; ++i:
for unsigned k = 0; k < 100; ++k:
GPIO_GPDR (0) = GPIO_GPDR (0)
static __inline__ void mdelay (unsigned ms):
udelay (1000 * ms)
/***************************************************************************
* MSC
***************************************************************************/
@@ -2343,18 +2358,18 @@ static void __map_io (unsigned physical, unsigned mapping):
static __inline__ unsigned msc_calc_clk_divisor (bool is_sd, unsigned dev_clk, unsigned msc_clk):
unsigned rate, ret
rate = is_sd ? SD_CLK : MMC_CLK
if (msc_clk && msc_clk < dev_clk)
if msc_clk && msc_clk < dev_clk:
dev_clk = msc_clk
for ret = 0; dev_clk < rate; ++ret, rate >>= 1:
return ret
return 0
/* divide rate to little than or equal to 400kHz */
static __inline__ unsigned msc_calc_slow_clk_divisor (bool is_s):
static __inline__ unsigned msc_calc_slow_clk_divisor (bool is_sd):
unsigned rate, ret
rate = (is_sd ? SD_CLK : MMC_CLK) / 1000 / 400
for ret = 0; rate > 0; rate >>= 1, ++ret:
return ret
return ret
/***************************************************************************
* RTC
@@ -2763,7 +2778,7 @@ static __inline__ void gpio_as_uart3 ():
static __inline__ void gpio_as_uart2 ():
GPIO_GPALR (3) = (GPIO_GPALR (3) & 0x3FFFFFFF) | 0x40000000
GPIO_GPAUR (3) = (PIO_GPAUR (3) & 0xF3FFFFFF) | 0x04000000
GPIO_GPAUR (3) = (GPIO_GPAUR (3) & 0xF3FFFFFF) | 0x04000000
static __inline__ void gpio_as_uart1 ():
GPIO_GPAUR (0) = (GPIO_GPAUR (0) & 0xFFF0FFFF) | 0x00050000
@@ -2784,7 +2799,7 @@ static __inline__ void gpio_as_scc ():
static __inline__ void gpio_as_dma ():
GPIO_GPALR (0) = (GPIO_GPALR (0) & 0x00FFFFFF) | 0x55000000
GPIO_GPAUR (0) = (PIO_GPAUR (0) & 0xFF0FFFFF) | 0x00500000
GPIO_GPAUR (0) = (GPIO_GPAUR (0) & 0xFF0FFFFF) | 0x00500000
static __inline__ void gpio_as_msc ():
GPIO_GPALR (1) = (GPIO_GPALR (1) & 0xFFFF000F) | 0x00005550
@@ -2794,15 +2809,15 @@ static __inline__ void gpio_as_pcmcia ():
static __inline__ void gpio_as_emc ():
GPIO_GPALR (2) = (GPIO_GPALR (2) & 0x3FFFFFFF) | 0x40000000
GPIO_GPAUR (2) = (PIO_GPAUR (2) & 0xFFFF0000) | 0x00005555
GPIO_GPAUR (2) = (GPIO_GPAUR (2) & 0xFFFF0000) | 0x00005555
static __inline__ void gpio_as_lcd_slave ():
GPIO_GPALR (1) = (GPIO_GPALR (1) & 0x0000FFFF) | 0x55550000
GPIO_GPAUR (1) = (PIO_GPAUR (1) & 0x00000000) | 0x55555555
GPIO_GPAUR (1) = (GPIO_GPAUR (1) & 0x00000000) | 0x55555555
static __inline__ void gpio_as_lcd_master ():
GPIO_GPALR (1) = (GPIO_GPALR (1) & 0x0000FFFF) | 0x55550000
GPIO_GPAUR (1) = (PIO_GPAUR (1) & 0x00000000) | 0x556A5555
GPIO_GPAUR (1) = (GPIO_GPAUR (1) & 0x00000000) | 0x556A5555
static __inline__ void gpio_as_usb ():
GPIO_GPAUR (0) = (GPIO_GPAUR (0) & 0x00FFFFFF) | 0x55000000
@@ -2827,7 +2842,7 @@ static __inline__ void gpio_as_ps2 ():
static __inline__ void gpio_as_uprt ():
GPIO_GPALR (1) = (GPIO_GPALR (1) & 0x0000000F) | 0x55555550
GPIO_GPALR (3) = (PIO_GPALR (3) & 0xC0000000) | 0x15555555
GPIO_GPALR (3) = (GPIO_GPALR (3) & 0xC0000000) | 0x15555555
static __inline__ void gpio_as_cim ():
GPIO_GPALR (0) = (GPIO_GPALR (0) & 0xFF000000) | 0x00555555
@@ -3184,7 +3199,7 @@ static __inline__ void udc_ep5info_init (unsigned c, unsigned i, unsigned a, uns
UDC_EP5InfR &= ~UDC_EPInfR_EPT_MASK
UDC_EP5InfR |= UDC_EPInfR_EPT_BULK
UDC_EP5InfR &= ~UDC_EPInfR_EPD
UDC_EP5InfR |= UDC_EPInfR_EPD_OU;
UDC_EP5InfR |= UDC_EPInfR_EPD_OUT
UDC_EP5InfR &= ~UDC_EPInfR_EPN_MASK
UDC_EP5InfR |= (5 << UDC_EPInfR_EPN_BIT)
@@ -3200,7 +3215,7 @@ static __inline__ void udc_ep6info_init (unsigned c, unsigned i, unsigned a, uns
UDC_EP6InfR &= ~UDC_EPInfR_EPT_MASK
UDC_EP6InfR |= UDC_EPInfR_EPT_BULK
UDC_EP6InfR &= ~UDC_EPInfR_EPD
UDC_EP6InfR |= UDC_EPInfR_EPD_OU;
UDC_EP6InfR |= UDC_EPInfR_EPD_OUT
UDC_EP6InfR &= ~UDC_EPInfR_EPN_MASK
UDC_EP6InfR |= (6 << UDC_EPInfR_EPN_BIT)
@@ -3216,7 +3231,7 @@ static __inline__ void udc_ep7info_init (unsigned c, unsigned i, unsigned a, uns
UDC_EP7InfR &= ~UDC_EPInfR_EPT_MASK
UDC_EP7InfR |= UDC_EPInfR_EPT_ISO
UDC_EP7InfR &= ~UDC_EPInfR_EPD
UDC_EP7InfR |= UDC_EPInfR_EPD_OU;
UDC_EP7InfR |= UDC_EPInfR_EPD_OUT
UDC_EP7InfR &= ~UDC_EPInfR_EPN_MASK
UDC_EP7InfR |= (7 << UDC_EPInfR_EPN_BIT)
@@ -3385,11 +3400,11 @@ static __inline__ void ac97_cold_reset_codec ():
AIC_ACCR2 &= ~AIC_ACCR2_SR
AIC_ACCR2 &= ~AIC_ACCR2_SA
#else
static __inline__ ac97_cold_reset_codec ():
//gpio_as_output(70); /* SDATA_OUT */
//gpio_as_output(71); /* SDATA_IN */
//gpio_as_output(78); /* SYNC */
//gpio_as_output(69); /* RESET# */
static __inline__ void ac97_cold_reset_codec ():
//gpio_as_output(70); /* SDATA_OUT */
//gpio_as_output(71); /* SDATA_IN */
//gpio_as_output(78); /* SYNC */
//gpio_as_output(69); /* RESET# */
GPIO_GPDIR (2) |= 0x000040e0
GPIO_GPDR (2) &= ~0x000040e0
udelay (10)
@@ -3700,6 +3715,18 @@ static __inline__ void i2s_reset_codec ():
/***************************************************************************
* CPM
***************************************************************************/
static __inline__ unsigned int get_pllout ():
unsigned plcr = CPM_PLCR1
if plcr & CPM_PLCR1_PLL1EN:
unsigned nf, nr, no
unsigned od[4] = {1, 2, 2, 4}
nf = (plcr & CPM_PLCR1_PLL1FD_MASK) >> CPM_PLCR1_PLL1FD_BIT
nr = (plcr & CPM_PLCR1_PLL1RD_MASK) >> CPM_PLCR1_PLL1RD_BIT
no = od[((plcr & CPM_PLCR1_PLL1OD_MASK) >> CPM_PLCR1_PLL1OD_BIT)]
return (JZ_EXTAL) / ((nr+2) * no) * (nf+2)
else:
return JZ_EXTAL
#define cpm_plcr1_fd() ((CPM_PLCR1 & CPM_PLCR1_PLL1FD_MASK) >> CPM_PLCR1_PLL1FD_BIT)
#define cpm_plcr1_rd() ((CPM_PLCR1 & CPM_PLCR1_PLL1RD_MASK) >> CPM_PLCR1_PLL1RD_BIT)
#define cpm_plcr1_od() ((CPM_PLCR1 & CPM_PLCR1_PLL1OD_MASK) >> CPM_PLCR1_PLL1OD_BIT)
@@ -3708,15 +3735,12 @@ static __inline__ void i2s_reset_codec ():
#define cpm_cfcr_sfr() ((CPM_CFCR & CPM_CFCR_SFR_MASK) >> CPM_CFCR_SFR_BIT)
#define cpm_cfcr_ifr() ((CPM_CFCR & CPM_CFCR_IFR_MASK) >> CPM_CFCR_IFR_BIT)
static __inline__ unsigned int cpm_divisor_encode(unsigned int n)
{
unsigned int encode[10] = {1,2,3,4,6,8,12,16,24,32};
int i;
for (i=0;i<10;i++)
if (n < encode[i])
break;
return i;
}
static __inline__ unsigned int cpm_divisor_encode (unsigned int n):
unsigned encode[10] = {1,2,3,4,6,8,12,16,24,32}
for unsigned i = 0; i < 10; ++i:
if n < encode[i]:
return i
return 10
#define cpm_set_mclk_div(n) ( CPM_CFCR = (CPM_CFCR & ~CPM_CFCR_MFR_MASK) | ((n) << (CPM_CFCR_MFR_BIT)) )

View File

@@ -16,79 +16,40 @@
// 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 <iris.h>
#include "devices.hh"
#include "jz4730.hh"
// GPIO pins for the keyboard://
// Rows = 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 125
// Cols = 0, 1, 2, 3, 4, 5, 6, 7
// Rows: 60...6f; 7d
// Nicely aligned to a port: use rows as output; cols as input.
// Map memory from b0010000, which is really 10010000 in kseg1.
#define D(n) (*(volatile unsigned *)(0x00 + 0x30 * n + address))
#define DI(n) (*(volatile unsigned *)(0x04 + 0x30 * n + address))
#define PU(n) (*(volatile unsigned *)(0x0c + 0x30 * n + address))
#define AL(n) (*(volatile unsigned *)(0x10 + 0x30 * n + address))
#define AU(n) (*(volatile unsigned *)(0x14 + 0x30 * n + address))
#define IE(n) (*(volatile unsigned *)(0x20 + 0x30 * n + address))
unsigned const address = 0x00010000
static void event (bool release, unsigned row, unsigned col):
debug_set_led (col * 2 + (release ? 1 : 0))
kdebug (col * 2 + (release ? 1 : 0))
static void delay ():
for unsigned i = 0; i < 100000; ++i:
IE (3) &= ~0x2000ffff
#define ROW_MASK 0x2000ffff
#define COL_MASK 0x000000ff
int main ():
// map memory
Capability page = memory_create_page (__my_memory)
alloc_physical (page, 0x10010000, 0)
memory_map (__my_memory, page, address, 1)
map_gpio ()
#if 0
// Keyboard stuff doesn't seem to work. Try the simpler part: touchpad buttons.
IE (0) &= ~0x00012000
AL (0) &= ~0x0c000000
AU (0) &= ~0x00000003
DI (0) &= ~0x00012000
PU (0) &= ~0x00012000
unsigned old = 0
while true:
unsigned data = D (0) & 0x00012000
if data == old:
continue
if data & ~old & 0x00010000:
event (true, 0, 0)
else if ~data & old & 0x00010000:
event (false, 0, 0)
if data & ~old & 0x00002000:
event (true, 1, 1)
else if ~data & old & 0x00002000:
event (false, 1, 1)
old = data
#else
// Disable all interrupts.
IE (3) &= ~0x2000ffff
IE (0) &= ~0x000001ff
GPIO_GPIER (3) &= ~ROW_MASK
GPIO_GPIER (0) &= ~COL_MASK
// Set all to GPIO.
AL (3) = 0
AU (3) &= ~0x0c000000
AL (0) &= ~0x0003ffff
GPIO_GPALR (3) = 0
GPIO_GPAUR (3) &= ~0x0c000000
GPIO_GPALR (0) &= ~0x0003ffff
// Set all rows to input and enable the pull-ups.
DI (0) &= ~0x000000ff
PU (0) |= 0x000000ff
GPIO_GPDIR (0) &= ~COL_MASK
GPIO_GPPUR (0) |= COL_MASK
// Set all columns to output, 0.
DI (3) |= 0x2000ffff
D (3) &= ~0x2000ffff
// Set all columns to input and enable the pull-ups; set to 0 when output.
GPIO_GPDIR (3) &= ROW_MASK
GPIO_GPPUR (3) |= ROW_MASK
GPIO_GPDR (3) &= ~ROW_MASK
#define NUM_COLS 17
unsigned keys[NUM_COLS]
@@ -101,18 +62,12 @@ int main ():
// read keyboard
unsigned data[NUM_COLS]
for unsigned col = 0; col < NUM_COLS; ++col:
D (3) &= ~0x2000ffff
delay ()
unsigned zero = ~D (0) & 0x000000ff
D (3) = (D (3) & ~0x2000ffff) | (1 << cols[col])
delay ()
data[col] = D (0) & zero
// Generate events.
for unsigned col = 0; col < NUM_COLS; ++col:
GPIO_GPDIR (3) = (GPIO_GPDIR (3) & ~ROW_MASK) | 1 << cols[col]
udelay (100)
unsigned data = GPIO_GPDR (0) & COL_MASK
// Generate events.
for unsigned row = 0; row < 8; ++row:
if (data[col] ^ keys[col]) & (1 << row):
event (data[col] & (1 << row), row, col)
keys[col] = data[col]
if (data ^ keys[col]) & (1 << row):
event (data & (1 << row), row, col)
keys[col] = data
schedule ()
#endif

View File

@@ -16,46 +16,9 @@
// 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"
// gpio stuff
#define D(n) (*(volatile unsigned *)(0x00 + 0x30 * n + gpio_address))
#define DI(n) (*(volatile unsigned *)(0x04 + 0x30 * n + gpio_address))
#define PU(n) (*(volatile unsigned *)(0x0c + 0x30 * n + gpio_address))
#define AL(n) (*(volatile unsigned *)(0x10 + 0x30 * n + gpio_address))
#define AU(n) (*(volatile unsigned *)(0x14 + 0x30 * n + gpio_address))
#define IE(n) (*(volatile unsigned *)(0x20 + 0x30 * n + gpio_address))
// pwm stuff
#define CTR (*(volatile unsigned char *)(pwm_address + 0x00))
#define PER (*(volatile unsigned short *)(pwm_address + 0x04))
#define DUT (*(volatile unsigned short *)(pwm_address + 0x08))
#define CPM_MSCR (*(volatile unsigned *)(cpm_address + 0x20))
// Mapping address for I/O memory.
unsigned const gpio_address = 0x00001000
unsigned const pwm_address = 0x00002000
unsigned const lcd_address = 0x00003000
unsigned const cpm_address = 0x00004000
//#define PWM0_BASE 0xB0050000
//#define PWM1_BASE 0xB0051000
/* PWM Control Register (PWM_CTR) */
//#define PWM_CTR_EN (1 << 7)
//#define PWM_CTR_SD (1 << 6)
//#define PWM_CTR_PRESCALE_MASK 0x3f
/* PWM Period Register (PWM_PER) */
//#define PWM_PER_PERIOD_MASK 0x3ff
/* PWM Duty Register (PWM_DUT) */
//#define PWM_DUT_FDUTY (1 << 10)
//#define PWM_DUT_DUTY_MASK 0x3ff
#include <iris.h>
#include "jz4730.hh"
#include "devices.hh"
// Pin definitions, all in port 2.
#define PWM_ENABLE (1 << 30)
@@ -64,177 +27,41 @@ unsigned const cpm_address = 0x00004000
#define SPDA (1 << 2) //LCD_PS
#define LCD_RET (1 << 3) //LCD_REV //use for lcd reset
// Lcd register definitions.
#define LCD_CFG (*(volatile unsigned *)(lcd_address + 0x00))
#define LCD_VSYNC (*(volatile unsigned *)(lcd_address + 0x04))
#define LCD_HSYNC (*(volatile unsigned *)(lcd_address + 0x08))
#define LCD_VAT (*(volatile unsigned *)(lcd_address + 0x0c))
#define LCD_DAH (*(volatile unsigned *)(lcd_address + 0x10))
#define LCD_DAV (*(volatile unsigned *)(lcd_address + 0x14))
#define LCD_PS (*(volatile unsigned *)(lcd_address + 0x18))
#define LCD_CLS (*(volatile unsigned *)(lcd_address + 0x1c))
#define LCD_SPL (*(volatile unsigned *)(lcd_address + 0x20))
#define LCD_REV (*(volatile unsigned *)(lcd_address + 0x24))
#define LCD_CTRL (*(volatile unsigned *)(lcd_address + 0x30))
#define LCD_STATE (*(volatile unsigned *)(lcd_address + 0x34))
#define LCD_IID (*(volatile unsigned *)(lcd_address + 0x38))
#define LCD_DA0 (*(volatile unsigned *)(lcd_address + 0x40))
#define LCD_SA0 (*(volatile unsigned *)(lcd_address + 0x44))
#define LCD_FID0 (*(volatile unsigned *)(lcd_address + 0x48))
#define LCD_CMD0 (*(volatile unsigned *)(lcd_address + 0x4c))
#define LCD_DA1 (*(volatile unsigned *)(lcd_address + 0x50))
#define LCD_SA1 (*(volatile unsigned *)(lcd_address + 0x54))
#define LCD_FID1 (*(volatile unsigned *)(lcd_address + 0x58))
#define LCD_CMD1 (*(volatile unsigned *)(lcd_address + 0x5c))
// Bit definitions.
#define LCD_CFG_PDW_BIT 4
#define LCD_CFG_PDW_MASK (0x03 << LCD_DEV_PDW_BIT)
#define LCD_CFG_PDW_1 (0 << LCD_DEV_PDW_BIT)
#define LCD_CFG_PDW_2 (1 << LCD_DEV_PDW_BIT)
#define LCD_CFG_PDW_4 (2 << LCD_DEV_PDW_BIT)
#define LCD_CFG_PDW_8 (3 << LCD_DEV_PDW_BIT)
#define LCD_CFG_MODE_BIT 0
#define LCD_CFG_MODE_MASK (0x0f << LCD_DEV_MODE_BIT)
#define LCD_CFG_MODE_GENERIC_TFT (0 << LCD_DEV_MODE_BIT)
#define LCD_CFG_MODE_SHARP_HR (1 << LCD_DEV_MODE_BIT)
#define LCD_CFG_MODE_CASIO_TFT (2 << LCD_DEV_MODE_BIT)
#define LCD_CFG_MODE_SAMSUNG_ALPHA (3 << LCD_DEV_MODE_BIT)
#define LCD_CFG_MODE_NONINTER_CCIR656 (4 << LCD_DEV_MODE_BIT)
#define LCD_CFG_MODE_INTER_CCIR656 (5 << LCD_DEV_MODE_BIT)
#define LCD_CFG_MODE_SINGLE_CSTN (8 << LCD_DEV_MODE_BIT)
#define LCD_CFG_MODE_SINGLE_MSTN (9 << LCD_DEV_MODE_BIT)
#define LCD_CFG_MODE_DUAL_CSTN (10 << LCD_DEV_MODE_BIT)
#define LCD_CFG_MODE_DUAL_MSTN (11 << LCD_DEV_MODE_BIT)
#define LCD_VSYNC_VPS_BIT 16
#define LCD_VSYNC_VPS_MASK (0xffff << LCD_VSYNC_VPS_BIT)
#define LCD_VSYNC_VPE_BIT 0
#define LCD_VSYNC_VPE_MASK (0xffff << LCD_VSYNC_VPS_BIT)
#define LCD_HSYNC_HPS_BIT 16
#define LCD_HSYNC_HPS_MASK (0xffff << LCD_HSYNC_HPS_BIT)
#define LCD_HSYNC_HPE_BIT 0
#define LCD_HSYNC_HPE_MASK (0xffff << LCD_HSYNC_HPE_BIT)
#define LCD_VAT_HT_BIT 16
#define LCD_VAT_HT_MASK (0xffff << LCD_VAT_HT_BIT)
#define LCD_VAT_VT_BIT 0
#define LCD_VAT_VT_MASK (0xffff << LCD_VAT_VT_BIT)
#define LCD_DAH_HDS_BIT 16
#define LCD_DAH_HDS_MASK (0xffff << LCD_DAH_HDS_BIT)
#define LCD_DAH_HDE_BIT 0
#define LCD_DAH_HDE_MASK (0xffff << LCD_DAH_HDE_BIT)
#define LCD_DAV_VDS_BIT 16
#define LCD_DAV_VDS_MASK (0xffff << LCD_DAV_VDS_BIT)
#define LCD_DAV_VDE_BIT 0
#define LCD_DAV_VDE_MASK (0xffff << LCD_DAV_VDE_BIT)
#define LCD_CTRL_BST_BIT 28
#define LCD_CTRL_BST_MASK (0x03 << LCD_CTRL_BST_BIT)
#define LCD_CTRL_BST_4 (0 << LCD_CTRL_BST_BIT)
#define LCD_CTRL_BST_8 (1 << LCD_CTRL_BST_BIT)
#define LCD_CTRL_BST_16 (2 << LCD_CTRL_BST_BIT)
#define LCD_CTRL_RGB555 (1 << 27)
#define LCD_CTRL_OFUP (1 << 26)
#define LCD_CTRL_FRC_BIT 24
#define LCD_CTRL_FRC_MASK (0x03 << LCD_CTRL_FRC_BIT)
#define LCD_CTRL_FRC_16 (0 << LCD_CTRL_FRC_BIT)
#define LCD_CTRL_FRC_4 (1 << LCD_CTRL_FRC_BIT)
#define LCD_CTRL_FRC_2 (2 << LCD_CTRL_FRC_BIT)
#define LCD_CTRL_PDD_BIT 16
#define LCD_CTRL_PDD_MASK (0xff << LCD_CTRL_PDD_BIT)
#define LCD_CTRL_EOFM (1 << 13)
#define LCD_CTRL_SOFM (1 << 12)
#define LCD_CTRL_OFUM (1 << 11)
#define LCD_CTRL_IFUM0 (1 << 10)
#define LCD_CTRL_IFUM1 (1 << 9)
#define LCD_CTRL_LDDM (1 << 8)
#define LCD_CTRL_QDM (1 << 7)
#define LCD_CTRL_BEDN (1 << 6)
#define LCD_CTRL_PEDN (1 << 5)
#define LCD_CTRL_DIS (1 << 4)
#define LCD_CTRL_ENA (1 << 3)
#define LCD_CTRL_BPP_BIT 0
#define LCD_CTRL_BPP_MASK (0x07 << LCD_CTRL_BPP_BIT)
#define LCD_CTRL_BPP_1 (0 << LCD_CTRL_BPP_BIT)
#define LCD_CTRL_BPP_2 (1 << LCD_CTRL_BPP_BIT)
#define LCD_CTRL_BPP_4 (2 << LCD_CTRL_BPP_BIT)
#define LCD_CTRL_BPP_8 (3 << LCD_CTRL_BPP_BIT)
#define LCD_CTRL_BPP_16 (4 << LCD_CTRL_BPP_BIT)
#define LCD_STATE_QD (1 << 7)
#define LCD_STATE_EOF (1 << 5)
#define LCD_STATE_SOF (1 << 4)
#define LCD_STATE_OFU (1 << 3)
#define LCD_STATE_IFU0 (1 << 2)
#define LCD_STATE_IFU1 (1 << 1)
#define LCD_STATE_LDD (1 << 0)
#define LCD_CMD_SOFINT (1 << 31)
#define LCD_CMD_EOFINT (1 << 30)
#define LCD_CMD_PAL (1 << 28)
#define LCD_CMD_LEN_BIT 0
#define LCD_CMD_LEN_MASK (0xffffff << LCD_CMD_LEN_BIT)
static void udelay (unsigned us):
for unsigned i = 0; i < us; ++i:
for unsigned k = 0; k < 100; ++k:
IE (2) &= ~SPEN
static void mdelay (unsigned ms):
udelay (1000 * ms)
static unsigned int get_pllout ():
unsigned plcr = CPM_PLCR1
if (plcr & CPM_PLCR1_PLL1EN)
unsigned nf, nr, no
unsigned od[4] = {1, 2, 2, 4}
nf = (plcr & CPM_PLCR1_PLL1FD_MASK) >> CPM_PLCR1_PLL1FD_BIT
nr = (plcr & CPM_PLCR1_PLL1RD_MASK) >> CPM_PLCR1_PLL1RD_BIT
no = od[((plcr & CPM_PLCR1_PLL1OD_MASK) >> CPM_PLCR1_PLL1OD_BIT)]
return (JZ_EXTAL) / ((nr+2) * no) * (nf+2)
else
return JZ_EXTAL
// level is in the range [0, 300]
static void set_backlight (unsigned level):
DUT = level
PWM_DUT (0) = level
if level:
CTR = 0xbf
D (2) |= PWM_ENABLE
PWM_CTR (0) = 0xbf
GPIO_GPDR (2) |= PWM_ENABLE
else:
CTR = 0x3f
D (2) &= ~PWM_ENABLE
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
D (2) |= SPEN
D (2) = (D (2) & ~SPDA) | SPCK
D (2) &= ~SPEN
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:
D (2) &= ~SPCK
GPIO_GPDR (2) &= ~SPCK
if data & 0x8000:
D (2) |= SPDA
GPIO_GPDR (2) |= SPDA
else:
D (2) &= ~SPDA
GPIO_GPDR (2) &= ~SPDA
udelay (25)
D (2) |= SPCK
GPIO_GPDR (2) |= SPCK
udelay (25)
data <<= 1
D (2) |= SPEN
GPIO_GPDR (2) |= SPEN
udelay(200)
static void lcd_enable ():
udelay (50)
D (2) &= ~LCD_RET
GPIO_GPDR (2) &= ~LCD_RET
mdelay(150)
D (2) |= LCD_RET
GPIO_GPDR (2) |= LCD_RET
mdelay(10)
// These values have been copied from the linux source.
// I have no idea what they do.
@@ -259,18 +86,18 @@ static void lcd_disable ():
static void reset ():
// Use gpio pins as pwm.
AUR (2) = (AUR (2) & ~0x0fffffff) | 0x50000000
GPIO_GPAUR (2) = (GPIO_GPAUR (2) & ~0x0fffffff) | 0x50000000
// Use gpio pins as lcd master.
ALR (1) = (ALR (1) & ~0x0000ffff) | 0x55550000
AUR (1) = 0x556a5555
GPIO_GPALR (1) = (GPIO_GPALR (1) & ~0x0000ffff) | 0x55550000
GPIO_GPAUR (1) = 0x556a5555
// initialize things.
IE(2) &= ~(PWM_ENABLE | LCD_RET | SPEN | SPCK | SPDA)
DI(2) |= PWM_ENABLE | LCD_RET | SPEN | SPCK | SPDA
GPIO_GPIER (2) &= ~(PWM_ENABLE | LCD_RET | SPEN | SPCK | SPDA)
GPIO_GPDIR (2) |= PWM_ENABLE | LCD_RET | SPEN | SPCK | SPDA
udelay (50)
D (2) &= ~LCD_RET
GPIO_GPDR (2) &= ~LCD_RET
mdelay (150)
D (2) |= LCD_RET
GPIO_GPDR (2) |= LCD_RET
mdelay (10)
lcd_enable ()
@@ -282,7 +109,7 @@ static void reset ():
LCD_DAV = (20 << 16) | 500
LCD_DAH = (80 << 16) | 880
LCD_VAT = (880 << 16) | 500
LCD_CFG = MODE_TFT_GEN | PCLK_N | VSYNC_N
//LCD_CFG = MODE_TFT_GEN | PCLK_N | VSYNC_N
// Stop lcd.
CPM_MSCR |= 1 << 7
@@ -306,10 +133,10 @@ static void map_io (unsigned physical, unsigned address):
//drop (page)
int main ():
map_io (0x10010000, gpio_address)
map_io (0x10050000, pwm_address)
map_io (0x13050000, lcd_address)
map_io (0x10000000, cpm_address)
map_gpio ()
map_pwm0 ()
map_lcd ()
map_cpm ()
reset ()
@@ -319,7 +146,7 @@ int main ():
continue
switch msg.protected_data:
case LCD_BACKLIGHT:
set_backlight (c.data[0] > 300 ? 300 : c.data[0])
set_backlight (msg.data[0] > 300 ? 300 : msg.data[0])
break
case LCD_RESET:
reset ()