summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx233
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/imx233')
-rw-r--r--firmware/target/arm/imx233/boot.lds71
-rw-r--r--firmware/target/arm/imx233/clkctrl-imx233.c84
-rw-r--r--firmware/target/arm/imx233/clkctrl-imx233.h52
-rw-r--r--firmware/target/arm/imx233/clock-target.h27
-rw-r--r--firmware/target/arm/imx233/crt0.S117
-rw-r--r--firmware/target/arm/imx233/kernel-imx233.c37
-rw-r--r--firmware/target/arm/imx233/lcdif-imx233.c171
-rw-r--r--firmware/target/arm/imx233/lcdif-imx233.h100
-rw-r--r--firmware/target/arm/imx233/pinctrl-imx233.h109
-rw-r--r--firmware/target/arm/imx233/powermgmt-target.h30
-rw-r--r--firmware/target/arm/imx233/sansa-fuzeplus/adc-target.h24
-rw-r--r--firmware/target/arm/imx233/sansa-fuzeplus/backlight-fuzeplus.c66
-rw-r--r--firmware/target/arm/imx233/sansa-fuzeplus/backlight-target.h29
-rw-r--r--firmware/target/arm/imx233/sansa-fuzeplus/button-fuzeplus.c30
-rw-r--r--firmware/target/arm/imx233/sansa-fuzeplus/button-target.h44
-rw-r--r--firmware/target/arm/imx233/sansa-fuzeplus/lcd-fuzeplus.c376
-rw-r--r--firmware/target/arm/imx233/sd-imx233.c48
-rw-r--r--firmware/target/arm/imx233/system-imx233.c191
-rw-r--r--firmware/target/arm/imx233/system-target.h53
-rw-r--r--firmware/target/arm/imx233/timrot-imx233.c76
-rw-r--r--firmware/target/arm/imx233/timrot-imx233.h57
21 files changed, 1792 insertions, 0 deletions
diff --git a/firmware/target/arm/imx233/boot.lds b/firmware/target/arm/imx233/boot.lds
new file mode 100644
index 0000000000..39e570a03e
--- /dev/null
+++ b/firmware/target/arm/imx233/boot.lds
@@ -0,0 +1,71 @@
1#include "config.h"
2#include "cpu.h"
3
4ENTRY(start)
5OUTPUT_FORMAT(elf32-littlearm)
6OUTPUT_ARCH(arm)
7STARTUP(target/arm/imx233/crt0.o)
8
9MEMORY
10{
11 IRAM : ORIGIN = IRAM_ORIG, LENGTH = IRAM_SIZE
12 DRAM : ORIGIN = DRAM_ORIG, LENGTH = DRAM_SIZE - TTB_SIZE
13}
14
15SECTIONS
16{
17 .vectors 0 :
18 {
19 *(.vectors);
20 . = ALIGN(0x4);
21 } > IRAM
22
23 .itext :
24 {
25 *(.icode)
26 *(.init.text)
27 . = ALIGN(0x4);
28 } > IRAM
29
30 .idata :
31 {
32 *(.qharray)
33 *(.idata)
34 *(.irodata)
35 . = ALIGN(0x4);
36 } > IRAM
37
38 .ibss :
39 {
40 *(.ibss)
41 } > IRAM
42
43 .text :
44 {
45 *(.text*)
46 } > DRAM
47
48 .data :
49 {
50 *(.data*)
51 *(.rodata*)
52 _dataend = . ;
53 } > DRAM
54
55 .stack (NOLOAD) :
56 {
57 *(.stack)
58 _stackbegin = .;
59 stackbegin = .;
60 . += 0x2000;
61 _stackend = .;
62 stackend = .;
63 } > DRAM
64
65 .bss (NOLOAD) :
66 {
67 _edata = .;
68 *(.bss*);
69 _end = .;
70 } > DRAM
71}
diff --git a/firmware/target/arm/imx233/clkctrl-imx233.c b/firmware/target/arm/imx233/clkctrl-imx233.c
new file mode 100644
index 0000000000..0b46a0e8db
--- /dev/null
+++ b/firmware/target/arm/imx233/clkctrl-imx233.c
@@ -0,0 +1,84 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright © 2011 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "clkctrl-imx233.h"
22
23#define __CLK_CLKGATE (1 << 31)
24#define __CLK_BUSY (1 << 29)
25
26void imx233_enable_timrot_xtal_clk32k(bool enable)
27{
28 if(enable)
29 __REG_CLR(HW_CLKCTRL_XTAL) = HW_CLKCTRL_XTAL__TIMROT_CLK32K_GATE;
30 else
31 __REG_SET(HW_CLKCTRL_XTAL) = HW_CLKCTRL_XTAL__TIMROT_CLK32K_GATE;
32}
33
34void imx233_enable_clock(enum imx233_clock_t clk, bool enable)
35{
36 volatile uint32_t *REG;
37 switch(clk)
38 {
39 case CLK_PIX: REG = &HW_CLKCTRL_PIX; break;
40 default: return;
41 }
42
43 /* warning: some registers like HW_CLKCTRL_PIX don't have a CLR/SET variant ! */
44 if(enable)
45 {
46 *REG = (*REG) & ~__CLK_CLKGATE;
47 while((*REG) & __CLK_CLKGATE);
48 while((*REG) & __CLK_BUSY);
49 }
50 else
51 {
52 *REG |= __CLK_CLKGATE;
53 while(!((*REG) & __CLK_CLKGATE));
54 }
55}
56
57void imx233_set_clock_divisor(enum imx233_clock_t clk, int div)
58{
59 switch(clk)
60 {
61 case CLK_PIX:
62 __REG_CLR(HW_CLKCTRL_PIX) = (1 << 12) - 1;
63 __REG_SET(HW_CLKCTRL_PIX) = div;
64 while(HW_CLKCTRL_PIX & __CLK_BUSY);
65 break;
66 default: return;
67 }
68}
69
70void imx233_set_bypass_pll(enum imx233_clock_t clk, bool bypass)
71{
72 uint32_t msk;
73 switch(clk)
74 {
75 case CLK_PIX: msk = HW_CLKCTRL_CLKSEQ__BYPASS_PIX; break;
76 default: return;
77 }
78
79 if(bypass)
80 __REG_SET(HW_CLKCTRL_CLKSEQ) = msk;
81 else
82 __REG_CLR(HW_CLKCTRL_CLKSEQ) = msk;
83}
84
diff --git a/firmware/target/arm/imx233/clkctrl-imx233.h b/firmware/target/arm/imx233/clkctrl-imx233.h
new file mode 100644
index 0000000000..ffc15c1043
--- /dev/null
+++ b/firmware/target/arm/imx233/clkctrl-imx233.h
@@ -0,0 +1,52 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright © 2011 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef CLKCTRL_IMX233_H
22#define CLKCTRL_IMX233_H
23
24#include "config.h"
25#include "system.h"
26#include "cpu.h"
27
28#define HW_CLKCTRL_BASE 0x80040000
29
30#define HW_CLKCTRL_XTAL (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x50))
31#define HW_CLKCTRL_XTAL__TIMROT_CLK32K_GATE (1 << 26)
32
33#define HW_CLKCTRL_PIX (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x60))
34
35#define HW_CLKCTRL_CLKSEQ (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x110))
36#define HW_CLKCTRL_CLKSEQ__BYPASS_PIX (1 << 1)
37
38#define HW_CLKCTRL_RESET (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x120))
39#define HW_CLKCTRL_RESET_CHIP 0x2
40#define HW_CLKCTRL_RESET_DIG 0x1
41
42enum imx233_clock_t
43{
44 CLK_PIX,
45};
46
47void imx233_enable_timrot_xtal_clk32k(bool enable);
48void imx233_enable_clock(enum imx233_clock_t clk, bool enable);
49void imx233_set_clock_divisor(enum imx233_clock_t clk, int div);
50void imx233_set_bypass_pll(enum imx233_clock_t clk, bool bypass);
51
52#endif /* CLKCTRL_IMX233_H */
diff --git a/firmware/target/arm/imx233/clock-target.h b/firmware/target/arm/imx233/clock-target.h
new file mode 100644
index 0000000000..59f684f16c
--- /dev/null
+++ b/firmware/target/arm/imx233/clock-target.h
@@ -0,0 +1,27 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright © 2011 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef CLOCK_TARGET_H
22#define CLOCK_TARGET_H
23
24#include "config.h"
25#include "cpu.h"
26
27#endif /* CLOCK_TARGET_H */
diff --git a/firmware/target/arm/imx233/crt0.S b/firmware/target/arm/imx233/crt0.S
new file mode 100644
index 0000000000..836c3e88cb
--- /dev/null
+++ b/firmware/target/arm/imx233/crt0.S
@@ -0,0 +1,117 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "config.h"
22#include "cpu.h"
23
24.section .vectors,"ax",%progbits
25.code 32
26.global start
27start:
28 /* most handlers are in DRAM which is too far away for a relative jump */
29 ldr pc, =newstart
30 ldr pc, =undef_instr_handler
31 ldr pc, =software_int_handler
32 ldr pc, =prefetch_abort_handler
33 ldr pc, =data_abort_handler
34 ldr pc, =reserved_handler
35 ldr pc, =irq_handler
36 ldr pc, =fiq_handler
37
38.text
39newstart:
40 msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */
41 /* Set up some stack and munge it with 0xdeadbeef */
42 ldr sp, =stackend
43 ldr r2, =stackbegin
44 ldr r3, =0xdeadbeef
451:
46 cmp sp, r2
47 strhi r3, [r2], #4
48 bhi 1b
49
50 /* Set up stack for IRQ mode */
51 msr cpsr_c, #0xd2
52 ldr sp, =irq_stack
53
54 /* Set up stack for FIQ mode */
55 msr cpsr_c, #0xd1
56 ldr sp, =fiq_stack
57
58 /* Let abort and undefined modes use IRQ stack */
59 msr cpsr_c, #0xd7
60 ldr sp, =irq_stack
61 msr cpsr_c, #0xdb
62 ldr sp, =irq_stack
63
64 /* Switch back to supervisor mode */
65 msr cpsr_c, #0xd3
66
67 /* Disable MMU, disable caching and buffering;
68 * use low exception range address (the core uses high range by default) */
69 mrc p15, 0, r0, c1, c0, 0
70 ldr r1, =0x3005
71 bic r0, r1
72 mcr p15, 0, r0, c1, c0, 0
73
74 /* Jump to main */
75 bl main
761:
77 b 1b
78
79/* All illegal exceptions call into UIE with exception address as first
80 * parameter. This is calculated differently depending on which exception
81 * we're in. Second parameter is exception number, used for a string lookup
82 * in UIE. */
83undef_instr_handler:
84 sub r0, lr, #4 @ r0 points to the faulty ARM instruction
85#ifdef USE_THUMB
86 mrs r1, spsr
87 tst r1, #(1<<5) @ T bit set ?
88 subne r0, lr, #2 @ if yes, r0 points to the faulty THUMB instruction
89#endif /* USE_THUMB */
90 mov r1, #0
91 b UIE
92
93/* We run supervisor mode most of the time, and should never see a software
94 * exception being thrown. Perhaps make it illegal and call UIE? */
95software_int_handler:
96reserved_handler:
97 movs pc, lr
98
99prefetch_abort_handler:
100 sub r0, lr, #4
101 mov r1, #1
102 b UIE
103
104data_abort_handler:
105 sub r0, lr, #8
106 mov r1, #2
107 b UIE
108
109/* 256 words of IRQ stack */
110 .space 256*4
111irq_stack:
112
113/* 256 words of FIQ stack */
114 .space 256*4
115fiq_stack:
116
117end:
diff --git a/firmware/target/arm/imx233/kernel-imx233.c b/firmware/target/arm/imx233/kernel-imx233.c
new file mode 100644
index 0000000000..367f359dc0
--- /dev/null
+++ b/firmware/target/arm/imx233/kernel-imx233.c
@@ -0,0 +1,37 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "kernel.h"
22#include "timrot-imx233.h"
23#include "clkctrl-imx233.h"
24
25static void tick_timer(void)
26{
27 /* Run through the list of tick tasks */
28 call_tick_tasks();
29}
30
31void tick_start(unsigned int interval_in_ms)
32{
33 /* use the 1-kHz XTAL clock source */
34 imx233_setup_timer(0, true, interval_in_ms,
35 HW_TIMROT_TIMCTRL__SELECT_1KHZ_XTAL, HW_TIMROT_TIMCTRL__PRESCALE_1,
36 false, &tick_timer);
37}
diff --git a/firmware/target/arm/imx233/lcdif-imx233.c b/firmware/target/arm/imx233/lcdif-imx233.c
new file mode 100644
index 0000000000..0b96cbf2bc
--- /dev/null
+++ b/firmware/target/arm/imx233/lcdif-imx233.c
@@ -0,0 +1,171 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (c) 2011 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "lcdif-imx233.h"
22
23static unsigned lcdif_word_length = 0;
24static unsigned lcdif_byte_packing = 0;
25
26void imx233_lcdif_enable_bus_master(bool enable)
27{
28 if(enable)
29 __REG_SET(HW_LCDIF_CTRL) = HW_LCDIF_CTRL__LCDIF_MASTER;
30 else
31 __REG_CLR(HW_LCDIF_CTRL) = HW_LCDIF_CTRL__LCDIF_MASTER;
32}
33
34void imx233_lcdif_enable(bool enable)
35{
36 if(enable)
37 __REG_CLR(HW_LCDIF_CTRL) = __BLOCK_CLKGATE;
38 else
39 __REG_SET(HW_LCDIF_CTRL) = __BLOCK_CLKGATE;
40}
41
42void imx233_lcdif_reset(void)
43{
44 //imx233_reset_block(&HW_LCDIF_CTRL);// doesn't work
45 while(HW_LCDIF_CTRL & __BLOCK_CLKGATE)
46 HW_LCDIF_CTRL &= ~__BLOCK_CLKGATE;
47 while(!(HW_LCDIF_CTRL & __BLOCK_SFTRST))
48 HW_LCDIF_CTRL |= __BLOCK_SFTRST;
49 while(HW_LCDIF_CTRL & __BLOCK_CLKGATE)
50 HW_LCDIF_CTRL &= ~__BLOCK_CLKGATE;
51 while(HW_LCDIF_CTRL & __BLOCK_SFTRST)
52 HW_LCDIF_CTRL &= ~__BLOCK_SFTRST;
53 while(HW_LCDIF_CTRL & __BLOCK_CLKGATE)
54 HW_LCDIF_CTRL &= ~__BLOCK_CLKGATE;
55 __REG_SET(HW_LCDIF_CTRL1) = HW_LCDIF_CTRL1__RESET;
56}
57
58void imx233_lcdif_set_timings(unsigned data_setup, unsigned data_hold,
59 unsigned cmd_setup, unsigned cmd_hold)
60{
61 HW_LCDIF_TIMING = (data_setup << HW_LCDIF_TIMING__DATA_SETUP_BP) |
62 (data_hold << HW_LCDIF_TIMING__DATA_HOLD_BP) |
63 (cmd_setup << HW_LCDIF_TIMING__CMD_SETUP_BP) |
64 (cmd_hold << HW_LCDIF_TIMING__CMD_HOLD_BP);
65}
66
67void imx233_lcdif_set_lcd_databus_width(unsigned width)
68{
69 __REG_CLR(HW_LCDIF_CTRL) = HW_LCDIF_CTRL__LCD_DATABUS_WIDTH_BM;
70 __REG_SET(HW_LCDIF_CTRL) = width;
71}
72
73void imx233_lcdif_set_word_length(unsigned word_length)
74{
75 __REG_CLR(HW_LCDIF_CTRL) = HW_LCDIF_CTRL__WORD_LENGTH_BM;
76 __REG_SET(HW_LCDIF_CTRL) = word_length;
77 lcdif_word_length = word_length;
78}
79
80unsigned imx233_lcdif_enable_irqs(unsigned irq_bm)
81{
82 unsigned old_msk = (HW_LCDIF_CTRL1 & HW_LCDIF_CTRL1__IRQ_EN_BM) >>HW_LCDIF_CTRL1__IRQ_EN_BP ;
83 /* clear irq status */
84 __REG_CLR(HW_LCDIF_CTRL1) = irq_bm << HW_LCDIF_CTRL1__IRQ_BP;
85 /* disable irqs */
86 __REG_CLR(HW_LCDIF_CTRL1) = HW_LCDIF_CTRL1__IRQ_EN_BM;
87 /* enable irqs */
88 __REG_SET(HW_LCDIF_CTRL1) = irq_bm << HW_LCDIF_CTRL1__IRQ_EN_BP;
89
90 return old_msk;
91}
92
93void imx233_lcdif_set_byte_packing_format(unsigned byte_packing)
94{
95 __REG_CLR(HW_LCDIF_CTRL1) = HW_LCDIF_CTRL1__BYTE_PACKING_FORMAT_BM;
96 __REG_SET(HW_LCDIF_CTRL1) = byte_packing << HW_LCDIF_CTRL1__BYTE_PACKING_FORMAT_BP;
97 lcdif_byte_packing = byte_packing;
98}
99
100void imx233_lcdif_set_data_format(bool data_fmt_16, bool data_fmt_18, bool data_fmt_24)
101{
102 if(data_fmt_16)
103 __REG_SET(HW_LCDIF_CTRL) = HW_LCDIF_CTRL__DATA_FORMAT_16_BIT;
104 else
105 __REG_CLR(HW_LCDIF_CTRL) = HW_LCDIF_CTRL__DATA_FORMAT_16_BIT;
106 if(data_fmt_18)
107 __REG_SET(HW_LCDIF_CTRL) = HW_LCDIF_CTRL__DATA_FORMAT_18_BIT;
108 else
109 __REG_CLR(HW_LCDIF_CTRL) = HW_LCDIF_CTRL__DATA_FORMAT_18_BIT;
110 if(data_fmt_24)
111 __REG_SET(HW_LCDIF_CTRL) = HW_LCDIF_CTRL__DATA_FORMAT_24_BIT;
112 else
113 __REG_CLR(HW_LCDIF_CTRL) = HW_LCDIF_CTRL__DATA_FORMAT_24_BIT;
114}
115
116void imx233_lcdif_wait_ready(void)
117{
118 while(HW_LCDIF_CTRL & HW_LCDIF_CTRL__RUN);
119}
120
121void imx233_lcdif_pio_send(bool data_mode, unsigned len, uint32_t *buf)
122{
123 unsigned max_xfer_size = 0xffff;
124 if(len == 0)
125 return;
126 if(lcdif_word_length == HW_LCDIF_CTRL__WORD_LENGTH_16_BIT)
127 max_xfer_size = 0x1fffe;
128 imx233_lcdif_wait_ready();
129 unsigned msk = imx233_lcdif_enable_irqs(0);
130 imx233_lcdif_enable_bus_master(false);
131
132 do
133 {
134 unsigned burst = MIN(len, max_xfer_size);
135 len -= burst;
136 unsigned count = burst;
137 if(lcdif_word_length != HW_LCDIF_CTRL__WORD_LENGTH_8_BIT)
138 {
139 if(burst & 1)
140 burst++;
141 count = burst / 2;
142 }
143 else
144 count = burst;
145 HW_LCDIF_TRANSFER_COUNT = 0;
146 HW_LCDIF_TRANSFER_COUNT = 0x10000 | count;
147 __REG_CLR(HW_LCDIF_CTRL) = HW_LCDIF_CTRL__DATA_SELECT | HW_LCDIF_CTRL__RUN;
148 if(data_mode)
149 __REG_SET(HW_LCDIF_CTRL) = HW_LCDIF_CTRL__DATA_SELECT;
150 __REG_SET(HW_LCDIF_CTRL) = HW_LCDIF_CTRL__RUN;
151 burst = (burst + 3) / 4;
152 while(burst-- > 0)
153 {
154 while(HW_LCDIF_STAT & HW_LCDIF_STAT__LFIFO_FULL);
155 HW_LCDIF_DATA = *buf++;
156 }
157 while(HW_LCDIF_CTRL & HW_LCDIF_CTRL__RUN);
158 }while(len > 0);
159 imx233_lcdif_enable_bus_master(true);
160 imx233_lcdif_enable_irqs(msk);
161}
162
163void imx233_lcdif_dma_send(void *buf, unsigned width, unsigned height)
164{
165 HW_LCDIF_CUR_BUF = (uint32_t)buf;
166 HW_LCDIF_TRANSFER_COUNT = 0;
167 HW_LCDIF_TRANSFER_COUNT = (height << 16) | width;
168 __REG_CLR(HW_LCDIF_CTRL) = HW_LCDIF_CTRL__RUN;
169 __REG_SET(HW_LCDIF_CTRL) = HW_LCDIF_CTRL__DATA_SELECT;
170 __REG_SET(HW_LCDIF_CTRL) = HW_LCDIF_CTRL__RUN;
171}
diff --git a/firmware/target/arm/imx233/lcdif-imx233.h b/firmware/target/arm/imx233/lcdif-imx233.h
new file mode 100644
index 0000000000..970b8661e5
--- /dev/null
+++ b/firmware/target/arm/imx233/lcdif-imx233.h
@@ -0,0 +1,100 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (c) 2011 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef __LCDIF_IMX233_H__
22#define __LCDIF_IMX233_H__
23
24#include <string.h>
25#include "cpu.h"
26#include "system.h"
27#include "system-target.h"
28
29#define HW_LCDIF_BASE 0x80030000
30
31#define HW_LCDIF_CTRL (*(volatile uint32_t *)(HW_LCDIF_BASE + 0x0))
32#define HW_LCDIF_CTRL__WORD_LENGTH_16_BIT (0 << 8)
33#define HW_LCDIF_CTRL__WORD_LENGTH_8_BIT (1 << 8)
34#define HW_LCDIF_CTRL__WORD_LENGTH_18_BIT (2 << 8)
35#define HW_LCDIF_CTRL__WORD_LENGTH_24_BIT (3 << 8)
36#define HW_LCDIF_CTRL__WORD_LENGTH_BM (3 << 8)
37#define HW_LCDIF_CTRL__LCD_DATABUS_WIDTH_18_BIT (2 << 10)
38#define HW_LCDIF_CTRL__LCD_DATABUS_WIDTH_BM (3 << 10)
39#define HW_LCDIF_CTRL__LCDIF_MASTER (1 << 5)
40#define HW_LCDIF_CTRL__DATA_FORMAT_16_BIT (1 << 3)
41#define HW_LCDIF_CTRL__DATA_FORMAT_18_BIT (1 << 2)
42#define HW_LCDIF_CTRL__DATA_FORMAT_24_BIT (1 << 1)
43#define HW_LCDIF_CTRL__RUN 0x1
44#define HW_LCDIF_CTRL__DATA_SELECT (1 << 16)
45
46#define HW_LCDIF_CTRL1 (*(volatile uint32_t *)(HW_LCDIF_BASE + 0x10))
47#define HW_LCDIF_CTRL1__RESET 1
48#define HW_LCDIF_CTRL1__BUSY_ENABLE (1 << 2)
49#define HW_LCDIF_CTRL1__MODE86 (1 << 1)
50#define HW_LCDIF_CTRL1__IRQ_EN_BP 12
51#define HW_LCDIF_CTRL1__IRQ_EN_BM (0xf << 12)
52#define HW_LCDIF_CTRL1__IRQ_BP 8
53#define HW_LCDIF_CTRL1__BYTE_PACKING_FORMAT_BM (0xf << 16)
54#define HW_LCDIF_CTRL1__BYTE_PACKING_FORMAT_BP 16
55
56#define HW_LCDIF__VSYNC_EDGE_IRQ 1
57#define HW_LCDIF__CUR_FRAME_DONE_IRQ 2
58#define HW_LCDIF__UNDERFLOW_IRQ 4
59#define HW_LCDIF__OVERFLOW_IRQ 8
60
61#define HW_LCDIF_TRANSFER_COUNT (*(volatile uint32_t *)(HW_LCDIF_BASE + 0x20))
62#define HW_LCDIF_CUR_BUF (*(volatile uint32_t *)(HW_LCDIF_BASE + 0x30))
63#define HW_LCDIF_NEXT_BUF (*(volatile uint32_t *)(HW_LCDIF_BASE + 0x40))
64#define HW_LCDIF_TIMING (*(volatile uint32_t *)(HW_LCDIF_BASE + 0x60))
65#define HW_LCDIF_TIMING__DATA_SETUP_BP 0
66#define HW_LCDIF_TIMING__DATA_HOLD_BP 8
67#define HW_LCDIF_TIMING__CMD_SETUP_BP 16
68#define HW_LCDIF_TIMING__CMD_HOLD_BP 24
69
70#define HW_LCDIF_CSC_COEFF0 (*(volatile uint32_t *)(HW_LCDIF_BASE + 0x110))
71#define HW_LCDIF_CSC_COEFF1 (*(volatile uint32_t *)(HW_LCDIF_BASE + 0x120))
72#define HW_LCDIF_CSC_COEFF2 (*(volatile uint32_t *)(HW_LCDIF_BASE + 0x130))
73#define HW_LCDIF_CSC_COEFF3 (*(volatile uint32_t *)(HW_LCDIF_BASE + 0x140))
74#define HW_LCDIF_CSC_COEFF4 (*(volatile uint32_t *)(HW_LCDIF_BASE + 0x150))
75#define HW_LCDIF_CSC_OFFSET (*(volatile uint32_t *)(HW_LCDIF_BASE + 0x160))
76#define HW_LCDIF_CSC_LIMIT (*(volatile uint32_t *)(HW_LCDIF_BASE + 0x170))
77#define HW_LCDIF_DATA (*(volatile uint32_t *)(HW_LCDIF_BASE + 0x1b0))
78
79#define HW_LCDIF_STAT (*(volatile uint32_t *)(HW_LCDIF_BASE + 0x1d0))
80#define HW_LCDIF_STAT__LFIFO_FULL (1 << 29)
81#define HW_LCDIF_STAT__LFIFO_EMPTY (1 << 28)
82#define HW_LCDIF_STAT__TXFIFO_FULL (1 << 27)
83#define HW_LCDIF_STAT__TXFIFO_EMPTY (1 << 26)
84#define HW_LCDIF_STAT__BUSY (1 << 25)
85
86void imx233_lcdif_enable_bus_master(bool enable);
87void imx233_lcdif_enable(bool enable);
88void imx233_lcdif_reset(void);
89void imx233_lcdif_set_timings(unsigned data_setup, unsigned data_hold,
90 unsigned cmd_setup, unsigned cmd_hold);
91void imx233_lcdif_set_lcd_databus_width(unsigned width);
92void imx233_lcdif_set_word_length(unsigned word_length);
93void imx233_lcdif_set_byte_packing_format(unsigned byte_packing);
94void imx233_lcdif_set_data_format(bool data_fmt_16, bool data_fmt_18, bool data_fmt_24);
95unsigned imx233_lcdif_enable_irqs(unsigned irq_bm); /* return old mask */
96void imx233_lcdif_wait_ready(void);
97void imx233_lcdif_pio_send(bool data_mode, unsigned len, uint32_t *buf);
98void imx233_lcdif_dma_send(void *buf, unsigned width, unsigned height);
99
100#endif /* __LCDIF_IMX233_H__ */
diff --git a/firmware/target/arm/imx233/pinctrl-imx233.h b/firmware/target/arm/imx233/pinctrl-imx233.h
new file mode 100644
index 0000000000..291b5c8ff7
--- /dev/null
+++ b/firmware/target/arm/imx233/pinctrl-imx233.h
@@ -0,0 +1,109 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22
23#ifndef __PINCTRL_IMX233_H__
24#define __PINCTRL_IMX233_H__
25
26#include "cpu.h"
27
28#define HW_PINCTRL_BASE 0x80018000
29
30#define HW_PINCTRL_CTRL (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x0))
31#define HW_PINCTRL_MUXSEL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x100 + (i) * 0x10))
32#define HW_PINCTRL_DRIVE(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x200 + (i) * 0x10))
33#define HW_PINCTRL_PULL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x400 + (i) * 0x10))
34#define HW_PINCTRL_DOUT(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x500 + (i) * 0x10))
35#define HW_PINCTRL_DIN(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x600 + (i) * 0x10))
36#define HW_PINCTRL_DOE(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x700 + (i) * 0x10))
37#define HW_PINCTRL_PIN2IRQ(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x800 + (i) * 0x10))
38#define HW_PINCTRL_IRQEN(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x900 + (i) * 0x10))
39#define HW_PINCTRL_IRQEN(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x900 + (i) * 0x10))
40#define HW_PINCTRL_IRQLEVEL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0xa00 + (i) * 0x10))
41#define HW_PINCTRL_IRQPOL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0xb00 + (i) * 0x10))
42#define HW_PINCTRL_IRQSTAT(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0xc00 + (i) * 0x10))
43
44#define PINCTRL_FUNCTION_MAIN 0
45#define PINCTRL_FUNCTION_ALT1 1
46#define PINCTRL_FUNCTION_ALT2 2
47#define PINCTRL_FUNCTION_GPIO 3
48
49#define PINCTRL_DRIVE_4mA 0
50#define PINCTRL_DRIVE_8mA 1
51#define PINCTRL_DRIVE_12mA 2
52#define PINCTRL_DRIVE_16mA 3 /* not available on all pins */
53
54static inline void imx233_pinctrl_init(void)
55{
56 __REG_CLR(HW_PINCTRL_CTRL) = __BLOCK_CLKGATE;
57 __REG_CLR(HW_PINCTRL_CTRL) = __BLOCK_SFTRST;
58}
59
60static inline void imx233_set_pin_drive_strength(unsigned bank, unsigned pin, unsigned strength)
61{
62 __REG_CLR(HW_PINCTRL_DRIVE(4 * bank + pin / 8)) = 3 << (4 * (pin % 8));
63 __REG_SET(HW_PINCTRL_DRIVE(4 * bank + pin / 8)) = strength << (4 * (pin % 8));
64}
65
66static inline void imx233_enable_gpio_output(unsigned bank, unsigned pin, bool enable)
67{
68 if(enable)
69 __REG_SET(HW_PINCTRL_DOE(bank)) = 1 << pin;
70 else
71 __REG_CLR(HW_PINCTRL_DOE(bank)) = 1 << pin;
72}
73
74static inline void imx233_enable_gpio_output_mask(unsigned bank, uint32_t pin_mask, bool enable)
75{
76 if(enable)
77 __REG_SET(HW_PINCTRL_DOE(bank)) = pin_mask;
78 else
79 __REG_CLR(HW_PINCTRL_DOE(bank)) = pin_mask;
80}
81
82static inline void imx233_set_gpio_output(unsigned bank, unsigned pin, bool value)
83{
84 if(value)
85 __REG_SET(HW_PINCTRL_DOUT(bank)) = 1 << pin;
86 else
87 __REG_CLR(HW_PINCTRL_DOUT(bank)) = 1 << pin;
88}
89
90static inline void imx233_set_gpio_output_mask(unsigned bank, uint32_t pin_mask, bool value)
91{
92 if(value)
93 __REG_SET(HW_PINCTRL_DOUT(bank)) = pin_mask;
94 else
95 __REG_CLR(HW_PINCTRL_DOUT(bank)) = pin_mask;
96}
97
98static inline uint32_t imx233_get_gpio_input_mask(unsigned bank, uint32_t pin_mask)
99{
100 return HW_PINCTRL_DIN(bank) & pin_mask;
101}
102
103static inline void imx233_set_pin_function(unsigned bank, unsigned pin, unsigned function)
104{
105 __REG_CLR(HW_PINCTRL_MUXSEL(2 * bank + pin / 16)) = 3 << (2 * (pin % 16));
106 __REG_SET(HW_PINCTRL_MUXSEL(2 * bank + pin / 16)) = function << (2 * (pin % 16));
107}
108
109#endif /* __PINCTRL_IMX233_H__ */
diff --git a/firmware/target/arm/imx233/powermgmt-target.h b/firmware/target/arm/imx233/powermgmt-target.h
new file mode 100644
index 0000000000..d539a66d16
--- /dev/null
+++ b/firmware/target/arm/imx233/powermgmt-target.h
@@ -0,0 +1,30 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef POWERMGMT_TARGET_H
22#define POWERMGMT_TARGET_H
23
24#include "config.h"
25
26void powermgmt_init_target(void);
27void charging_algorithm_step(void);
28void charging_algorithm_close(void);
29
30#endif /* POWERMGMT_TARGET_H */
diff --git a/firmware/target/arm/imx233/sansa-fuzeplus/adc-target.h b/firmware/target/arm/imx233/sansa-fuzeplus/adc-target.h
new file mode 100644
index 0000000000..e6b5152f5b
--- /dev/null
+++ b/firmware/target/arm/imx233/sansa-fuzeplus/adc-target.h
@@ -0,0 +1,24 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef _ADC_TARGET_H_
22#define _ADC_TARGET_H_
23
24#endif
diff --git a/firmware/target/arm/imx233/sansa-fuzeplus/backlight-fuzeplus.c b/firmware/target/arm/imx233/sansa-fuzeplus/backlight-fuzeplus.c
new file mode 100644
index 0000000000..0638e30aeb
--- /dev/null
+++ b/firmware/target/arm/imx233/sansa-fuzeplus/backlight-fuzeplus.c
@@ -0,0 +1,66 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "config.h"
23#include "system.h"
24#include "lcd.h"
25#include "backlight.h"
26#include "backlight-target.h"
27#include "pinctrl-imx233.h"
28
29void _backlight_set_brightness(int brightness)
30{
31 imx233_set_gpio_output(1, 28, false);
32 udelay(600);
33 while(brightness-- > 0)
34 {
35 imx233_set_gpio_output(1, 28, false);
36 imx233_set_gpio_output(1, 28, true);
37 }
38}
39
40bool _backlight_init(void)
41{
42 imx233_set_pin_function(1, 28, PINCTRL_FUNCTION_GPIO);
43 imx233_set_pin_drive_strength(1, 28, PINCTRL_DRIVE_8mA);
44 imx233_enable_gpio_output(1, 28, true);
45 imx233_set_gpio_output(1, 29, true);
46 udelay(600);
47 _backlight_set_brightness(100);
48 return true;
49}
50
51void _backlight_on(void)
52{
53#ifdef HAVE_LCD_ENABLE
54 lcd_enable(true); /* power on lcd + visible display */
55#endif
56 /* don't do anything special, the core will set the brightness */
57}
58
59void _backlight_off(void)
60{
61 /* there is no real on/off but we can set to 0 brightness */
62 _backlight_set_brightness(0);
63#ifdef HAVE_LCD_ENABLE
64 lcd_enable(false); /* power off visible display */
65#endif
66}
diff --git a/firmware/target/arm/imx233/sansa-fuzeplus/backlight-target.h b/firmware/target/arm/imx233/sansa-fuzeplus/backlight-target.h
new file mode 100644
index 0000000000..e3766965d8
--- /dev/null
+++ b/firmware/target/arm/imx233/sansa-fuzeplus/backlight-target.h
@@ -0,0 +1,29 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef BACKLIGHT_TARGET_H
22#define BACKLIGHT_TARGET_H
23
24bool _backlight_init(void);
25void _backlight_on(void);
26void _backlight_off(void);
27void _backlight_set_brightness(int brightness);
28
29#endif /* BACKLIGHT_TARGET_H */
diff --git a/firmware/target/arm/imx233/sansa-fuzeplus/button-fuzeplus.c b/firmware/target/arm/imx233/sansa-fuzeplus/button-fuzeplus.c
new file mode 100644
index 0000000000..7f37d67d43
--- /dev/null
+++ b/firmware/target/arm/imx233/sansa-fuzeplus/button-fuzeplus.c
@@ -0,0 +1,30 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "button-target.h"
22
23void button_init_device(void)
24{
25}
26
27int button_read_device(void)
28{
29 return 0;
30}
diff --git a/firmware/target/arm/imx233/sansa-fuzeplus/button-target.h b/firmware/target/arm/imx233/sansa-fuzeplus/button-target.h
new file mode 100644
index 0000000000..b5d27bb176
--- /dev/null
+++ b/firmware/target/arm/imx233/sansa-fuzeplus/button-target.h
@@ -0,0 +1,44 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef _BUTTON_TARGET_H_
22#define _BUTTON_TARGET_H_
23
24#include <stdbool.h>
25#include "config.h"
26
27void button_init_device(void);
28int button_read_device(void);
29
30/* Main unit's buttons */
31#define BUTTON_POWER 0x00000001
32
33#define BUTTON_VOL_UP 0x00000002
34#define BUTTON_VOL_DOWN 0x00000004
35
36#define BUTTON_MAIN (BUTTON_VOL_UP|BUTTON_VOL_DOWN|BUTTON_POWER)
37
38#define BUTTON_REMOTE 0
39
40/* Software power-off */
41#define POWEROFF_BUTTON BUTTON_POWER
42#define POWEROFF_COUNT 10
43
44#endif /* _BUTTON_TARGET_H_ */
diff --git a/firmware/target/arm/imx233/sansa-fuzeplus/lcd-fuzeplus.c b/firmware/target/arm/imx233/sansa-fuzeplus/lcd-fuzeplus.c
new file mode 100644
index 0000000000..d6f8f5323b
--- /dev/null
+++ b/firmware/target/arm/imx233/sansa-fuzeplus/lcd-fuzeplus.c
@@ -0,0 +1,376 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (c) 2011 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include <string.h>
22#include "cpu.h"
23#include "system.h"
24#include "backlight-target.h"
25#include "lcd.h"
26#include "lcdif-imx233.h"
27#include "clkctrl-imx233.h"
28#include "pinctrl-imx233.h"
29
30#define logf(...)
31
32static enum lcd_kind_t
33{
34 LCD_KIND_7783 = 0x7783,
35 LCD_KIND_9325 = 0x9325,
36 LCD_KIND_OTHER = 0,
37} lcd_kind = LCD_KIND_OTHER;
38
39static void setup_parameters(void)
40{
41 imx233_lcdif_reset();
42 imx233_lcdif_set_lcd_databus_width(HW_LCDIF_CTRL__LCD_DATABUS_WIDTH_18_BIT);
43 imx233_lcdif_set_word_length(HW_LCDIF_CTRL__WORD_LENGTH_18_BIT);
44 imx233_lcdif_set_timings(1, 2, 2, 2);
45}
46
47static void setup_lcd_pins(bool use_lcdif)
48{
49 if(use_lcdif)
50 {
51 imx233_set_pin_function(1, 25, PINCTRL_FUNCTION_GPIO); /* lcd_vsync */
52 imx233_set_pin_function(1, 21, PINCTRL_FUNCTION_MAIN); /* lcd_cs */
53 imx233_set_pin_function(1, 22, PINCTRL_FUNCTION_GPIO); /* lcd_dotclk */
54 imx233_set_pin_function(1, 23, PINCTRL_FUNCTION_GPIO); /* lcd_enable */
55 imx233_set_pin_function(1, 24, PINCTRL_FUNCTION_GPIO); /* lcd_hsync */
56 imx233_set_pin_function(1, 18, PINCTRL_FUNCTION_MAIN); /* lcd_reset */
57 imx233_set_pin_function(1, 19, PINCTRL_FUNCTION_MAIN); /* lcd_rs */
58 imx233_set_pin_function(1, 16, PINCTRL_FUNCTION_MAIN); /* lcd_d16 */
59 imx233_set_pin_function(1, 17, PINCTRL_FUNCTION_MAIN); /* lcd_d17 */
60 imx233_set_pin_function(1, 20, PINCTRL_FUNCTION_MAIN); /* lcd_wr */
61 __REG_CLR(HW_PINCTRL_MUXSEL(2)) = 0xffffffff; /* lcd_d{0-15} */
62 }
63 else
64 {
65
66 __REG_SET(HW_PINCTRL_MUXSEL(2)) = 0xffffffff; /* lcd_d{0-15} */
67 imx233_enable_gpio_output_mask(1, 0x3ffffff, false); /* lcd_{d{0-17},reset,rs,wr,cs,dotclk,enable,hsync,vsync} */
68 imx233_set_pin_function(1, 16, PINCTRL_FUNCTION_GPIO); /* lcd_d16 */
69 imx233_set_pin_function(1, 17, PINCTRL_FUNCTION_GPIO); /* lcd_d17 */
70 imx233_set_pin_function(1, 19, PINCTRL_FUNCTION_GPIO); /* lcd_rs */
71 imx233_set_pin_function(1, 20, PINCTRL_FUNCTION_GPIO); /* lcd_wr */
72 imx233_set_pin_function(1, 21, PINCTRL_FUNCTION_GPIO); /* lcd_cs */
73 imx233_set_pin_function(1, 22, PINCTRL_FUNCTION_GPIO); /* lcd_dotclk */
74 imx233_set_pin_function(1, 23, PINCTRL_FUNCTION_GPIO); /* lcd_enable */
75 imx233_set_pin_function(1, 24, PINCTRL_FUNCTION_GPIO); /* lcd_hsync */
76 imx233_set_pin_function(1, 25, PINCTRL_FUNCTION_GPIO); /* lcd_vsync */
77 }
78}
79
80static void setup_lcd_pins_i80(bool i80)
81{
82 if(i80)
83 {
84 imx233_set_pin_drive_strength(1, 19, PINCTRL_DRIVE_12mA); /* lcd_rs */
85 imx233_set_pin_drive_strength(1, 20, PINCTRL_DRIVE_12mA); /* lcd_wr */
86 imx233_set_pin_drive_strength(1, 21, PINCTRL_DRIVE_12mA); /* lcd_cs */
87 imx233_set_pin_drive_strength(1, 23, PINCTRL_DRIVE_12mA); /* lcd_enable */
88 imx233_set_pin_function(1, 19, PINCTRL_FUNCTION_GPIO); /* lcd_rs */
89 imx233_set_pin_function(1, 20, PINCTRL_FUNCTION_GPIO); /* lcd_wr */
90 imx233_set_pin_function(1, 21, PINCTRL_FUNCTION_GPIO); /* lcd_cs */
91 imx233_set_pin_function(1, 23, PINCTRL_FUNCTION_GPIO); /* lcd_enable */
92 /* lcd_{rs,wr,cs,enable} */
93 imx233_enable_gpio_output_mask(1, (1 << 19) | (1 << 20) | (1 << 21) | (1 << 23), true);
94 imx233_set_gpio_output_mask(1, (1 << 19) | (1 << 20) | (1 << 21) | (1 << 23), true);
95
96 imx233_enable_gpio_output_mask(1, 0x3ffff, false); /* lcd_d{0-17} */
97 __REG_SET(HW_PINCTRL_MUXSEL(2)) = 0xffffffff; /* lcd_d{0-15} as GPIO */
98 imx233_set_pin_function(1, 16, PINCTRL_FUNCTION_GPIO); /* lcd_d16 */
99 imx233_set_pin_function(1, 17, PINCTRL_FUNCTION_GPIO); /* lcd_d17 */
100 imx233_set_pin_function(1, 18, PINCTRL_FUNCTION_GPIO); /* lcd_reset */
101 imx233_set_pin_function(1, 19, PINCTRL_FUNCTION_GPIO); /* lcd_rs */
102 }
103 else
104 {
105 imx233_set_gpio_output_mask(1, (1 << 19) | (1 << 20) | (1 << 21) | (1 << 23), true);
106 imx233_set_pin_drive_strength(1, 19, PINCTRL_DRIVE_4mA); /* lcd_rs */
107 imx233_set_pin_drive_strength(1, 20, PINCTRL_DRIVE_4mA); /* lcd_wr */
108 imx233_set_pin_drive_strength(1, 21, PINCTRL_DRIVE_4mA); /* lcd_cs */
109 imx233_set_pin_drive_strength(1, 23, PINCTRL_DRIVE_4mA); /* lcd_enable */
110 imx233_set_pin_function(1, 19, PINCTRL_FUNCTION_MAIN); /* lcd_rs */
111 imx233_set_pin_function(1, 20, PINCTRL_FUNCTION_MAIN); /* lcd_wr */
112 imx233_set_pin_function(1, 21, PINCTRL_FUNCTION_MAIN); /* lcd_cs */
113 imx233_enable_gpio_output_mask(1, 0x3ffff, false); /* lcd_d{0-17} */
114 __REG_CLR(HW_PINCTRL_MUXSEL(2)) = 0xffffffff; /* lcd_d{0-15} as lcd_d{0-15} */
115 imx233_set_pin_function(1, 16, PINCTRL_FUNCTION_MAIN); /* lcd_d16 */
116 imx233_set_pin_function(1, 17, PINCTRL_FUNCTION_MAIN); /* lcd_d17 */
117 imx233_set_pin_function(1, 18, PINCTRL_FUNCTION_MAIN); /* lcd_reset */
118 imx233_set_pin_function(1, 19, PINCTRL_FUNCTION_MAIN); /* lcd_rs */
119 }
120}
121
122static void common_lcd_enable(bool enable)
123{
124 imx233_lcdif_enable(enable);
125 setup_lcd_pins(enable); /* use GPIO pins when disable */
126}
127
128static void setup_lcdif(void)
129{
130 setup_parameters();
131 common_lcd_enable(true);
132 imx233_lcdif_enable_bus_master(true);
133 //imx233_lcdif_enable_irqs(HW_LCDIF__CUR_FRAME_DONE_IRQ);
134}
135
136static inline uint32_t encode_16_to_18(uint32_t a)
137{
138 return ((a & 0xff) << 1) | (((a >> 8) & 0xff) << 10);
139}
140
141static inline uint32_t decode_18_to_16(uint32_t a)
142{
143 return ((a >> 1) & 0xff) | ((a >> 2) & 0xff00);
144}
145
146static void setup_lcdif_clock(void)
147{
148 /* the LCD seems to works at 24Mhz, so use the xtal clock with no divider */
149 imx233_enable_clock(CLK_PIX, false);
150 imx233_set_clock_divisor(CLK_PIX, 1);
151 imx233_set_bypass_pll(CLK_PIX, true); /* use XTAL */
152 imx233_enable_clock(CLK_PIX, true);
153}
154
155static uint32_t i80_write_read_single(uint32_t data_out)
156{
157 imx233_set_gpio_output(1, 21, true); /* lcd_cs */
158 imx233_set_gpio_output(1, 19, true); /* lcd_rs */
159 imx233_set_gpio_output(1, 23, true); /* lcd_enable */
160 imx233_set_gpio_output(1, 20, true); /* lcd_wr */
161 imx233_enable_gpio_output_mask(1, 0x3ffff, true); /* lcd_d{0-17} */
162 udelay(2);
163 imx233_set_gpio_output(1, 19, false); /* lcd_rs */
164 udelay(1);
165 imx233_set_gpio_output(1, 21, false); /* lcd_cs */
166 udelay(1);
167 imx233_set_gpio_output(1, 20, false); /* lcd_wr */
168 udelay(1);
169 imx233_set_gpio_output_mask(1, data_out & 0x3ffff, true); /* lcd_d{0-17} */
170 udelay(1);
171 imx233_set_gpio_output(1, 20, true); /* lcd_wr */
172 udelay(3);
173 imx233_enable_gpio_output_mask(1, 0x3ffff, false); /* lcd_d{0-17} */
174 udelay(2);
175 imx233_set_gpio_output(1, 23, false); /* lcd_enable */
176 udelay(1);
177 imx233_set_gpio_output(1, 19, true); /* lcd_rs */
178 udelay(1);
179 imx233_set_gpio_output(1, 23, true); /* lcd_enable */
180 udelay(3);
181 imx233_set_gpio_output(1, 23, false); /* lcd_enable */
182 udelay(2);
183 uint32_t data_in = imx233_get_gpio_input_mask(1, 0x3ffff); /* lcd_d{0-17} */
184 udelay(1);
185 imx233_set_gpio_output(1, 23, true); /* lcd_enable */
186 udelay(1);
187 imx233_set_gpio_output(1, 21, true); /* lcd_cs */
188 udelay(1);
189 return data_in;
190}
191
192static void lcd_write_reg(uint32_t reg, uint32_t data)
193{
194 uint32_t old_reg = reg;
195 /* get back to 18-bit word length */
196 imx233_lcdif_set_word_length(HW_LCDIF_CTRL__WORD_LENGTH_18_BIT);
197 reg = encode_16_to_18(reg);
198 data = encode_16_to_18(data);
199
200 imx233_lcdif_pio_send(false, 2, &reg);
201 if(old_reg != 0x22)
202 imx233_lcdif_pio_send(true, 2, &data);
203}
204
205static uint32_t lcd_read_reg(uint32_t reg)
206{
207 setup_lcd_pins_i80(true);
208 uint32_t data_in = i80_write_read_single(encode_16_to_18(reg));
209 setup_lcd_pins_i80(false);
210 lcd_write_reg(0x22, 0);
211 return decode_18_to_16(data_in);
212}
213
214static void lcd_init_seq_7783(void)
215{
216 __REG_SET(HW_LCDIF_CTRL1) = HW_LCDIF_CTRL1__RESET;
217 udelay(50);
218 __REG_CLR(HW_LCDIF_CTRL1) = HW_LCDIF_CTRL1__RESET;
219 udelay(10);
220 __REG_SET(HW_LCDIF_CTRL1) = HW_LCDIF_CTRL1__RESET;
221 udelay(200);
222 lcd_write_reg(1, 0x100);
223 lcd_write_reg(2, 0x700);
224 lcd_write_reg(3, 0x1030);
225 lcd_write_reg(7, 0x121);
226 lcd_write_reg(8, 0x302);
227 lcd_write_reg(9, 0x200);
228 lcd_write_reg(0xa, 0);
229 lcd_write_reg(0x10, 0x790);
230 lcd_write_reg(0x11, 5);
231 lcd_write_reg(0x12, 0);
232 lcd_write_reg(0x13, 0);
233 udelay(100);
234 lcd_write_reg(0x10, 0x12b0);
235 udelay(100);
236 lcd_write_reg(0x11, 7);
237 udelay(100);
238 lcd_write_reg(0x12, 0x89);
239 lcd_write_reg(0x13, 0x1d00);
240 lcd_write_reg(0x29, 0x2f);
241 udelay(50);
242 lcd_write_reg(0x30, 0);
243 lcd_write_reg(0x31, 0x505);
244 lcd_write_reg(0x32, 0x205);
245 lcd_write_reg(0x35, 0x206);
246 lcd_write_reg(0x36, 0x408);
247 lcd_write_reg(0x37, 0);
248 lcd_write_reg(0x38, 0x504);
249 lcd_write_reg(0x39, 0x206);
250 lcd_write_reg(0x3c, 0x206);
251 lcd_write_reg(0x3d, 0x408);
252 lcd_write_reg(0x50, 0); /* left X ? */
253 lcd_write_reg(0x51, 0xef); /* right X ? */
254 lcd_write_reg(0x52, 0); /* top Y ? */
255 lcd_write_reg(0x53, 0x13f); /* bottom Y ? */
256 lcd_write_reg(0x20, 0); /* left X ? */
257 lcd_write_reg(0x21, 0); /* top Y ? */
258 lcd_write_reg(0x60, 0xa700);
259 lcd_write_reg(0x61, 1);
260 lcd_write_reg(0x90, 0x33);
261 lcd_write_reg(0x2b, 0xa);
262 lcd_write_reg(9, 0);
263 lcd_write_reg(7, 0x133);
264 udelay(50);
265 lcd_write_reg(0x22, 0);
266}
267
268static void lcd_init_seq_9325(void)
269{
270
271}
272
273void lcd_init_device(void)
274{
275 setup_lcdif();
276 setup_lcdif_clock();
277
278 for(int i = 0; i < 10; i++)
279 {
280 uint32_t kind = lcd_read_reg(0);
281 if(kind == LCD_KIND_7783 || kind == LCD_KIND_9325)
282 {
283 lcd_kind = kind;
284 break;
285 }
286 else
287 {
288 lcd_kind = LCD_KIND_OTHER;
289 }
290 }
291 udelay(5);
292 switch(lcd_kind)
293 {
294 case LCD_KIND_7783: lcd_init_seq_7783(); break;
295 case LCD_KIND_9325: lcd_init_seq_9325(); break;
296 default:
297 lcd_init_seq_7783(); break;
298 }
299}
300
301
302static void lcd_enable_7783(bool enable)
303{
304 if(!enable)
305 {
306 lcd_write_reg(7, 0x131);
307 udelay(50);
308 lcd_write_reg(7, 0x20);
309 udelay(50);
310 lcd_write_reg(0x10, 0x82);
311 udelay(50);
312 }
313 else
314 {
315 lcd_write_reg(0x11, 5);
316 lcd_write_reg(0x10, 0x12b0);
317 udelay(50);
318 lcd_write_reg(7, 0x11);
319 udelay(50);
320 lcd_write_reg(0x12, 0x89);
321 udelay(50);
322 lcd_write_reg(0x13, 0x1d00);
323 udelay(50);
324 lcd_write_reg(0x29, 0x2f);
325 udelay(50);
326 lcd_write_reg(0x2b, 0xa);
327 lcd_write_reg(7, 0x133);
328 udelay(50);
329 lcd_write_reg(0x22, 0);
330 }
331}
332
333static void lcd_enable_9325(bool enable)
334{
335 (void) enable;
336}
337
338void lcd_enable(bool enable)
339{
340 if(enable)
341 common_lcd_enable(true);
342 switch(lcd_kind)
343 {
344 case LCD_KIND_7783: lcd_enable_7783(enable); break;
345 case LCD_KIND_9325: lcd_enable_9325(enable); break;
346 default: lcd_enable_7783(enable); break;
347 }
348 if(!enable)
349 common_lcd_enable(false);
350}
351
352void lcd_update(void)
353{
354 lcd_write_reg(0x50, 0);
355 lcd_write_reg(0x51, LCD_WIDTH - 1);
356 lcd_write_reg(0x52, 0);
357 lcd_write_reg(0x53, LCD_HEIGHT - 1);
358 lcd_write_reg(0x20, 0);
359 lcd_write_reg(0x21, 0);
360 lcd_write_reg(0x22, 0);
361 imx233_lcdif_wait_ready();
362 imx233_lcdif_set_word_length(HW_LCDIF_CTRL__WORD_LENGTH_16_BIT);
363 imx233_lcdif_set_byte_packing_format(0xf); /* two pixels per 32-bit word */
364 imx233_lcdif_set_data_format(false, false, false); /* RGB565, don't care, don't care */
365 imx233_lcdif_dma_send(lcd_framebuffer, LCD_WIDTH, LCD_HEIGHT);
366 imx233_lcdif_wait_ready();
367}
368
369void lcd_update_rect(int x, int y, int width, int height)
370{
371 (void) x;
372 (void) y;
373 (void) width;
374 (void) height;
375 lcd_update();
376}
diff --git a/firmware/target/arm/imx233/sd-imx233.c b/firmware/target/arm/imx233/sd-imx233.c
new file mode 100644
index 0000000000..eec1ce14db
--- /dev/null
+++ b/firmware/target/arm/imx233/sd-imx233.c
@@ -0,0 +1,48 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "sd.h"
22
23int sd_init(void)
24{
25 return -1;
26}
27
28int sd_read_sectors(IF_MD2(int drive,) unsigned long start, int count,
29 void* buf)
30{
31 IF_MD((void) drive);
32 (void) start;
33 (void) count;
34 (void) buf;
35 return -1;
36}
37
38int sd_write_sectors(IF_MD2(int drive,) unsigned long start, int count,
39 const void* buf)
40{
41 IF_MD((void) drive);
42 (void) start;
43 (void) count;
44 (void) buf;
45 return -1;
46}
47
48
diff --git a/firmware/target/arm/imx233/system-imx233.c b/firmware/target/arm/imx233/system-imx233.c
new file mode 100644
index 0000000000..bcccce194c
--- /dev/null
+++ b/firmware/target/arm/imx233/system-imx233.c
@@ -0,0 +1,191 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 by amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "kernel.h"
23#include "system.h"
24#include "gcc_extensions.h"
25#include "system-target.h"
26#include "cpu.h"
27#include "clkctrl-imx233.h"
28#include "pinctrl-imx233.h"
29#include "timrot-imx233.h"
30#include "lcd.h"
31#include "backlight-target.h"
32
33#define HW_POWER_BASE 0x80044000
34
35#define HW_POWER_RESET (*(volatile uint32_t *)(HW_POWER_BASE + 0x100))
36#define HW_POWER_RESET__UNLOCK 0x3E770000
37#define HW_POWER_RESET__PWD 0x1
38
39#define HW_ICOLL_BASE 0x80000000
40
41#define HW_ICOLL_VECTOR (*(volatile uint32_t *)(HW_ICOLL_BASE + 0x0))
42
43#define HW_ICOLL_LEVELACK (*(volatile uint32_t *)(HW_ICOLL_BASE + 0x10))
44#define HW_ICOLL_LEVELACK__LEVEL0 0x1
45
46#define HW_ICOLL_CTRL (*(volatile uint32_t *)(HW_ICOLL_BASE + 0x20))
47#define HW_ICOLL_CTRL__IRQ_FINAL_ENABLE (1 << 16)
48#define HW_ICOLL_CTRL__ARM_RSE_MODE (1 << 18)
49
50#define HW_ICOLL_VBASE (*(volatile uint32_t *)(HW_ICOLL_BASE + 0x40))
51#define HW_ICOLL_INTERRUPT(i) (*(volatile uint32_t *)(HW_ICOLL_BASE + 0x120 + (i) * 0x10))
52#define HW_ICOLL_INTERRUPT__PRIORITY_BM 0x3
53#define HW_ICOLL_INTERRUPT__ENABLE 0x4
54#define HW_ICOLL_INTERRUPT__SOFTIRQ 0x8
55#define HW_ICOLL_INTERRUPT__ENFIQ 0x10
56
57#define default_interrupt(name) \
58 extern __attribute__((weak, alias("UIRQ"))) void name(void)
59
60static void UIRQ (void) __attribute__((interrupt ("IRQ")));
61void irq_handler(void) __attribute__((interrupt("IRQ")));
62void fiq_handler(void) __attribute__((interrupt("FIQ")));
63
64default_interrupt(INT_USB_CTRL);
65default_interrupt(INT_TIMER0);
66default_interrupt(INT_TIMER1);
67default_interrupt(INT_TIMER2);
68default_interrupt(INT_TIMER3);
69default_interrupt(INT_LCDIF_DMA);
70default_interrupt(INT_LCDIF_ERROR);
71
72typedef void (*isr_t)(void);
73
74static isr_t isr_table[INT_SRC_NR_SOURCES] =
75{
76 [INT_SRC_USB_CTRL] = INT_USB_CTRL,
77 [INT_SRC_TIMER(0)] = INT_TIMER0,
78 [INT_SRC_TIMER(1)] = INT_TIMER1,
79 [INT_SRC_TIMER(2)] = INT_TIMER2,
80 [INT_SRC_TIMER(3)] = INT_TIMER3,
81 [INT_SRC_LCDIF_DMA] = INT_LCDIF_DMA,
82 [INT_SRC_LCDIF_ERROR] = INT_LCDIF_ERROR,
83};
84
85static void UIRQ(void)
86{
87 panicf("Unhandled IRQ %02X",
88 (unsigned int)(HW_ICOLL_VECTOR - (uint32_t)isr_table) / 4);
89}
90
91void irq_handler(void)
92{
93 HW_ICOLL_VECTOR = HW_ICOLL_VECTOR; /* notify icoll that we entered ISR */
94 (*(isr_t *)HW_ICOLL_VECTOR)();
95 /* acknowledge completion of IRQ (all use the same priority 0 */
96 HW_ICOLL_LEVELACK = HW_ICOLL_LEVELACK__LEVEL0;
97}
98
99void fiq_handler(void)
100{
101}
102
103static void imx233_chip_reset(void)
104{
105 HW_CLKCTRL_RESET = HW_CLKCTRL_RESET_CHIP;
106}
107
108void system_reboot(void)
109{
110 _backlight_off();
111
112 disable_irq();
113
114 /* use watchdog to reset */
115 imx233_chip_reset();
116 while(1);
117}
118
119void system_exception_wait(void)
120{
121 /* what is this supposed to do ? */
122}
123
124void imx233_enable_interrupt(int src, bool enable)
125{
126 if(enable)
127 __REG_SET(HW_ICOLL_INTERRUPT(src)) = HW_ICOLL_INTERRUPT__ENABLE;
128 else
129 __REG_CLR(HW_ICOLL_INTERRUPT(src)) = HW_ICOLL_INTERRUPT__ENABLE;
130}
131
132void imx233_softirq(int src, bool enable)
133{
134 if(enable)
135 __REG_SET(HW_ICOLL_INTERRUPT(src)) = HW_ICOLL_INTERRUPT__SOFTIRQ;
136 else
137 __REG_CLR(HW_ICOLL_INTERRUPT(src)) = HW_ICOLL_INTERRUPT__SOFTIRQ;
138}
139
140void system_init(void)
141{
142 /* disable all interrupts */
143 for(int i = 0; i < INT_SRC_NR_SOURCES; i++)
144 {
145 /* priority = 0, disable, disable fiq */
146 HW_ICOLL_INTERRUPT(i) = 0;
147 }
148 /* setup vbase as isr_table */
149 HW_ICOLL_VBASE = (uint32_t)&isr_table;
150 /* enable final irq bit */
151 __REG_SET(HW_ICOLL_CTRL) = HW_ICOLL_CTRL__IRQ_FINAL_ENABLE;
152
153 imx233_pinctrl_init();
154 imx233_timrot_init();
155}
156
157void power_off(void)
158{
159 /* power down */
160 HW_POWER_RESET = HW_POWER_RESET__UNLOCK | HW_POWER_RESET__PWD;
161 while(1);
162}
163
164bool imx233_us_elapsed(uint32_t ref, unsigned us_delay)
165{
166 uint32_t cur = HW_DIGCTL_MICROSECONDS;
167 if(ref + us_delay <= ref)
168 return !(cur > ref) && !(cur < (ref + us_delay));
169 else
170 return (cur < ref) || cur >= (ref + us_delay);
171}
172
173void imx233_reset_block(volatile uint32_t *block_reg)
174{
175 __REG_CLR(*block_reg) = __BLOCK_SFTRST;
176 while(*block_reg & __BLOCK_SFTRST);
177 __REG_CLR(*block_reg) = __BLOCK_CLKGATE;
178 __REG_SET(*block_reg) = __BLOCK_SFTRST;
179 while(!(*block_reg & __BLOCK_CLKGATE));
180 __REG_CLR(*block_reg) = __BLOCK_SFTRST;
181 while(*block_reg & __BLOCK_SFTRST);
182 __REG_CLR(*block_reg) = __BLOCK_CLKGATE;
183 while(*block_reg & __BLOCK_CLKGATE);
184}
185
186void udelay(unsigned us)
187{
188 uint32_t ref = HW_DIGCTL_MICROSECONDS;
189 while(!imx233_us_elapsed(ref, us));
190}
191
diff --git a/firmware/target/arm/imx233/system-target.h b/firmware/target/arm/imx233/system-target.h
new file mode 100644
index 0000000000..675adb448b
--- /dev/null
+++ b/firmware/target/arm/imx233/system-target.h
@@ -0,0 +1,53 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef SYSTEM_TARGET_H
22#define SYSTEM_TARGET_H
23
24#include "system-arm.h"
25#include "mmu-arm.h"
26#include "panic.h"
27
28#include "clock-target.h" /* CPUFREQ_* are defined here */
29
30#define HW_DIGCTL_BASE 0x8001C000
31#define HW_DIGCTL_MICROSECONDS (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0xC0))
32
33#define INT_SRC_USB_CTRL 11
34#define INT_SRC_TIMER(nr) (28 + (nr))
35#define INT_SRC_LCDIF_DMA 45
36#define INT_SRC_LCDIF_ERROR 46
37#define INT_SRC_NR_SOURCES 66
38
39void imx233_enable_interrupt(int src, bool enable);
40void imx233_softirq(int src, bool enable);
41void udelay(unsigned us);
42bool imx233_us_elapsed(uint32_t ref, unsigned us_delay);
43void imx233_reset_block(volatile uint32_t *block_reg);
44void power_off(void);
45
46void udelay(unsigned usecs);
47
48static inline void mdelay(unsigned msecs)
49{
50 udelay(1000 * msecs);
51}
52
53#endif /* SYSTEM_TARGET_H */
diff --git a/firmware/target/arm/imx233/timrot-imx233.c b/firmware/target/arm/imx233/timrot-imx233.c
new file mode 100644
index 0000000000..64a7c63f24
--- /dev/null
+++ b/firmware/target/arm/imx233/timrot-imx233.c
@@ -0,0 +1,76 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "timrot-imx233.h"
22#include "clkctrl-imx233.h"
23
24imx233_timer_fn_t timer_fns[4];
25
26#define define_timer_irq(nr) \
27void INT_TIMER##nr(void) \
28{ \
29 if(timer_fns[nr]) \
30 timer_fns[nr](); \
31 __REG_CLR(HW_TIMROT_TIMCTRL(nr)) = HW_TIMROT_TIMCTRL__IRQ; \
32}
33
34define_timer_irq(0)
35define_timer_irq(1)
36define_timer_irq(2)
37define_timer_irq(3)
38
39void imx233_setup_timer(unsigned timer_nr, bool reload, unsigned count,
40 unsigned src, unsigned prescale, bool polarity, imx233_timer_fn_t fn)
41{
42 timer_fns[timer_nr] = fn;
43
44 HW_TIMROT_TIMCTRL(timer_nr) = src | prescale;
45 if(polarity)
46 __REG_SET(HW_TIMROT_TIMCTRL(timer_nr)) = HW_TIMROT_TIMCTRL__POLARITY;
47 if(reload)
48 {
49 __REG_SET(HW_TIMROT_TIMCTRL(timer_nr)) = HW_TIMROT_TIMCTRL__RELOAD;
50 /* manual says count - 1 for reload timers */
51 HW_TIMROT_TIMCOUNT(timer_nr) = count - 1;
52 }
53 else
54 HW_TIMROT_TIMCOUNT(timer_nr) = count;
55 /* only enable interrupt if function is set */
56 if(fn != NULL)
57 {
58 /* enable interrupt */
59 imx233_enable_interrupt(INT_SRC_TIMER(timer_nr), true);
60 /* clear irq bit and enable */
61 __REG_CLR(HW_TIMROT_TIMCTRL(timer_nr)) = HW_TIMROT_TIMCTRL__IRQ;
62 __REG_SET(HW_TIMROT_TIMCTRL(timer_nr)) = HW_TIMROT_TIMCTRL__IRQ_EN;
63 }
64 else
65 imx233_enable_interrupt(INT_SRC_TIMER(timer_nr), false);
66 /* finally update */
67 __REG_SET(HW_TIMROT_TIMCTRL(timer_nr)) = HW_TIMROT_TIMCTRL__UPDATE;
68}
69
70void imx233_timrot_init(void)
71{
72 __REG_CLR(HW_TIMROT_ROTCTRL) = __BLOCK_CLKGATE;
73 __REG_CLR(HW_TIMROT_ROTCTRL) = __BLOCK_SFTRST;
74 /* enable xtal path to timrot */
75 imx233_enable_timrot_xtal_clk32k(true);
76}
diff --git a/firmware/target/arm/imx233/timrot-imx233.h b/firmware/target/arm/imx233/timrot-imx233.h
new file mode 100644
index 0000000000..792ab767ac
--- /dev/null
+++ b/firmware/target/arm/imx233/timrot-imx233.h
@@ -0,0 +1,57 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef TIMROT_IMX233_H
22#define TIMROT_IMX233_H
23
24#include "system.h"
25#include "cpu.h"
26
27#define HW_TIMROT_BASE 0x80068000
28
29#define HW_TIMROT_ROTCTRL (*(volatile uint32_t *)(HW_TIMROT_BASE + 0x0))
30
31#define HW_TIMROT_ROTCOUNT (*(volatile uint32_t *)(HW_TIMROT_BASE + 0x10))
32
33#define HW_TIMROT_TIMCTRL(i) (*(volatile uint32_t *)(HW_TIMROT_BASE + 0x20 + (i) * 0x20))
34#define HW_TIMROT_TIMCTRL__IRQ (1 << 15)
35#define HW_TIMROT_TIMCTRL__IRQ_EN (1 << 14)
36#define HW_TIMROT_TIMCTRL__POLARITY (1 << 8)
37#define HW_TIMROT_TIMCTRL__UPDATE (1 << 7)
38#define HW_TIMROT_TIMCTRL__RELOAD (1 << 6)
39#define HW_TIMROT_TIMCTRL__PRESCALE_1 (0 << 4)
40#define HW_TIMROT_TIMCTRL__PRESCALE_2 (1 << 4)
41#define HW_TIMROT_TIMCTRL__PRESCALE_4 (2 << 4)
42#define HW_TIMROT_TIMCTRL__PRESCALE_8 (3 << 4)
43#define HW_TIMROT_TIMCTRL__SELECT_32KHZ_XTAL 8
44#define HW_TIMROT_TIMCTRL__SELECT_8KHZ_XTAL 9
45#define HW_TIMROT_TIMCTRL__SELECT_4KHZ_XTAL 10
46#define HW_TIMROT_TIMCTRL__SELECT_1KHZ_XTAL 11
47#define HW_TIMROT_TIMCTRL__SELECT_TICK_ALWAYS 12
48
49#define HW_TIMROT_TIMCOUNT(i) (*(volatile uint32_t *)(HW_TIMROT_BASE + 0x30 + (i) * 0x20))
50
51typedef void (*imx233_timer_fn_t)(void);
52
53void imx233_timrot_init(void);
54void imx233_setup_timer(unsigned timer_nr, bool reload, unsigned count,
55 unsigned src, unsigned prescale, bool polarity, imx233_timer_fn_t fn);
56
57#endif /* TIMROT_IMX233_H */