diff options
Diffstat (limited to 'firmware/target')
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 | |||
4 | ENTRY(start) | ||
5 | OUTPUT_FORMAT(elf32-littlearm) | ||
6 | OUTPUT_ARCH(arm) | ||
7 | STARTUP(target/arm/imx233/crt0.o) | ||
8 | |||
9 | MEMORY | ||
10 | { | ||
11 | IRAM : ORIGIN = IRAM_ORIG, LENGTH = IRAM_SIZE | ||
12 | DRAM : ORIGIN = DRAM_ORIG, LENGTH = DRAM_SIZE - TTB_SIZE | ||
13 | } | ||
14 | |||
15 | SECTIONS | ||
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 | |||
26 | void 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 | |||
34 | void 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 | |||
57 | void 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 | |||
70 | void 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 | |||
42 | enum imx233_clock_t | ||
43 | { | ||
44 | CLK_PIX, | ||
45 | }; | ||
46 | |||
47 | void imx233_enable_timrot_xtal_clk32k(bool enable); | ||
48 | void imx233_enable_clock(enum imx233_clock_t clk, bool enable); | ||
49 | void imx233_set_clock_divisor(enum imx233_clock_t clk, int div); | ||
50 | void 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 | ||
27 | start: | ||
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 | ||
39 | newstart: | ||
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 | ||
45 | 1: | ||
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 | ||
76 | 1: | ||
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. */ | ||
83 | undef_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? */ | ||
95 | software_int_handler: | ||
96 | reserved_handler: | ||
97 | movs pc, lr | ||
98 | |||
99 | prefetch_abort_handler: | ||
100 | sub r0, lr, #4 | ||
101 | mov r1, #1 | ||
102 | b UIE | ||
103 | |||
104 | data_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 | ||
111 | irq_stack: | ||
112 | |||
113 | /* 256 words of FIQ stack */ | ||
114 | .space 256*4 | ||
115 | fiq_stack: | ||
116 | |||
117 | end: | ||
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 | |||
25 | static void tick_timer(void) | ||
26 | { | ||
27 | /* Run through the list of tick tasks */ | ||
28 | call_tick_tasks(); | ||
29 | } | ||
30 | |||
31 | void 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 | |||
23 | static unsigned lcdif_word_length = 0; | ||
24 | static unsigned lcdif_byte_packing = 0; | ||
25 | |||
26 | void 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 | |||
34 | void 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 | |||
42 | void 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 | |||
58 | void 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 | |||
67 | void 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 | |||
73 | void 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 | |||
80 | unsigned 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 | |||
93 | void 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 | |||
100 | void 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 | |||
116 | void imx233_lcdif_wait_ready(void) | ||
117 | { | ||
118 | while(HW_LCDIF_CTRL & HW_LCDIF_CTRL__RUN); | ||
119 | } | ||
120 | |||
121 | void 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 | |||
163 | void 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 | |||
86 | void imx233_lcdif_enable_bus_master(bool enable); | ||
87 | void imx233_lcdif_enable(bool enable); | ||
88 | void imx233_lcdif_reset(void); | ||
89 | void imx233_lcdif_set_timings(unsigned data_setup, unsigned data_hold, | ||
90 | unsigned cmd_setup, unsigned cmd_hold); | ||
91 | void imx233_lcdif_set_lcd_databus_width(unsigned width); | ||
92 | void imx233_lcdif_set_word_length(unsigned word_length); | ||
93 | void imx233_lcdif_set_byte_packing_format(unsigned byte_packing); | ||
94 | void imx233_lcdif_set_data_format(bool data_fmt_16, bool data_fmt_18, bool data_fmt_24); | ||
95 | unsigned imx233_lcdif_enable_irqs(unsigned irq_bm); /* return old mask */ | ||
96 | void imx233_lcdif_wait_ready(void); | ||
97 | void imx233_lcdif_pio_send(bool data_mode, unsigned len, uint32_t *buf); | ||
98 | void 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 | |||
54 | static 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 | |||
60 | static 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 | |||
66 | static 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 | |||
74 | static 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 | |||
82 | static 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 | |||
90 | static 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 | |||
98 | static 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 | |||
103 | static 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 | |||
26 | void powermgmt_init_target(void); | ||
27 | void charging_algorithm_step(void); | ||
28 | void 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 | |||
29 | void _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 | |||
40 | bool _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 | |||
51 | void _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 | |||
59 | void _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 | |||
24 | bool _backlight_init(void); | ||
25 | void _backlight_on(void); | ||
26 | void _backlight_off(void); | ||
27 | void _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 | |||
23 | void button_init_device(void) | ||
24 | { | ||
25 | } | ||
26 | |||
27 | int 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 | |||
27 | void button_init_device(void); | ||
28 | int 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 | |||
32 | static 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 | |||
39 | static 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 | |||
47 | static 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 | |||
80 | static 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 | |||
122 | static void common_lcd_enable(bool enable) | ||
123 | { | ||
124 | imx233_lcdif_enable(enable); | ||
125 | setup_lcd_pins(enable); /* use GPIO pins when disable */ | ||
126 | } | ||
127 | |||
128 | static 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 | |||
136 | static inline uint32_t encode_16_to_18(uint32_t a) | ||
137 | { | ||
138 | return ((a & 0xff) << 1) | (((a >> 8) & 0xff) << 10); | ||
139 | } | ||
140 | |||
141 | static inline uint32_t decode_18_to_16(uint32_t a) | ||
142 | { | ||
143 | return ((a >> 1) & 0xff) | ((a >> 2) & 0xff00); | ||
144 | } | ||
145 | |||
146 | static 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 | |||
155 | static 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 | |||
192 | static 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, ®); | ||
201 | if(old_reg != 0x22) | ||
202 | imx233_lcdif_pio_send(true, 2, &data); | ||
203 | } | ||
204 | |||
205 | static 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 | |||
214 | static 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 | |||
268 | static void lcd_init_seq_9325(void) | ||
269 | { | ||
270 | |||
271 | } | ||
272 | |||
273 | void 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 | |||
302 | static 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 | |||
333 | static void lcd_enable_9325(bool enable) | ||
334 | { | ||
335 | (void) enable; | ||
336 | } | ||
337 | |||
338 | void 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 | |||
352 | void 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 | |||
369 | void 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 | |||
23 | int sd_init(void) | ||
24 | { | ||
25 | return -1; | ||
26 | } | ||
27 | |||
28 | int 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 | |||
38 | int 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 | |||
60 | static void UIRQ (void) __attribute__((interrupt ("IRQ"))); | ||
61 | void irq_handler(void) __attribute__((interrupt("IRQ"))); | ||
62 | void fiq_handler(void) __attribute__((interrupt("FIQ"))); | ||
63 | |||
64 | default_interrupt(INT_USB_CTRL); | ||
65 | default_interrupt(INT_TIMER0); | ||
66 | default_interrupt(INT_TIMER1); | ||
67 | default_interrupt(INT_TIMER2); | ||
68 | default_interrupt(INT_TIMER3); | ||
69 | default_interrupt(INT_LCDIF_DMA); | ||
70 | default_interrupt(INT_LCDIF_ERROR); | ||
71 | |||
72 | typedef void (*isr_t)(void); | ||
73 | |||
74 | static 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 | |||
85 | static void UIRQ(void) | ||
86 | { | ||
87 | panicf("Unhandled IRQ %02X", | ||
88 | (unsigned int)(HW_ICOLL_VECTOR - (uint32_t)isr_table) / 4); | ||
89 | } | ||
90 | |||
91 | void 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 | |||
99 | void fiq_handler(void) | ||
100 | { | ||
101 | } | ||
102 | |||
103 | static void imx233_chip_reset(void) | ||
104 | { | ||
105 | HW_CLKCTRL_RESET = HW_CLKCTRL_RESET_CHIP; | ||
106 | } | ||
107 | |||
108 | void 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 | |||
119 | void system_exception_wait(void) | ||
120 | { | ||
121 | /* what is this supposed to do ? */ | ||
122 | } | ||
123 | |||
124 | void 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 | |||
132 | void 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 | |||
140 | void 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 | |||
157 | void power_off(void) | ||
158 | { | ||
159 | /* power down */ | ||
160 | HW_POWER_RESET = HW_POWER_RESET__UNLOCK | HW_POWER_RESET__PWD; | ||
161 | while(1); | ||
162 | } | ||
163 | |||
164 | bool 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 | |||
173 | void 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 | |||
186 | void 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 | |||
39 | void imx233_enable_interrupt(int src, bool enable); | ||
40 | void imx233_softirq(int src, bool enable); | ||
41 | void udelay(unsigned us); | ||
42 | bool imx233_us_elapsed(uint32_t ref, unsigned us_delay); | ||
43 | void imx233_reset_block(volatile uint32_t *block_reg); | ||
44 | void power_off(void); | ||
45 | |||
46 | void udelay(unsigned usecs); | ||
47 | |||
48 | static 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 | |||
24 | imx233_timer_fn_t timer_fns[4]; | ||
25 | |||
26 | #define define_timer_irq(nr) \ | ||
27 | void 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 | |||
34 | define_timer_irq(0) | ||
35 | define_timer_irq(1) | ||
36 | define_timer_irq(2) | ||
37 | define_timer_irq(3) | ||
38 | |||
39 | void 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 | |||
70 | void 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 | |||
51 | typedef void (*imx233_timer_fn_t)(void); | ||
52 | |||
53 | void imx233_timrot_init(void); | ||
54 | void 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 */ | ||