summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmaury Pouly <pamaury@rockbox.org>2011-09-05 11:29:32 +0000
committerAmaury Pouly <pamaury@rockbox.org>2011-09-05 11:29:32 +0000
commit7d4fed53cc1e8b0e5aa250ebea3a1b53fc3a50b2 (patch)
tree236a72d742675715fd599daaa98af8f4eeb45ad8
parent11e1f71612f6c1ef8c17f8ceea17f69fd4bc7b02 (diff)
downloadrockbox-7d4fed53cc1e8b0e5aa250ebea3a1b53fc3a50b2.tar.gz
rockbox-7d4fed53cc1e8b0e5aa250ebea3a1b53fc3a50b2.zip
imx233:fuze+: major memory and usb rework
- now identity map dram uncached and have a cached and buffered virtual alias - rework dma to handle virtual to physical pointers conversion - fix lcd frame pointer - implement usb detection properly - implement bootloader usb properly - allow the bootloader to disable MMC windowing (useful for recovery) git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30432 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--bootloader/imx233.c96
-rw-r--r--firmware/export/config.h2
-rw-r--r--firmware/export/config/sansafuzeplus.h2
-rw-r--r--firmware/export/imx233.h30
-rw-r--r--firmware/target/arm/imx233/boot.lds16
-rw-r--r--firmware/target/arm/imx233/crt0.S13
-rw-r--r--firmware/target/arm/imx233/dma-imx233.c27
-rw-r--r--firmware/target/arm/imx233/lcdif-imx233.c2
-rw-r--r--firmware/target/arm/imx233/mmc-imx233.c71
-rw-r--r--firmware/target/arm/imx233/power-imx233.c24
-rw-r--r--firmware/target/arm/imx233/power-imx233.h69
-rw-r--r--firmware/target/arm/imx233/sansa-fuzeplus/lcd-fuzeplus.c2
-rw-r--r--firmware/target/arm/imx233/sd-imx233.c6
-rw-r--r--firmware/target/arm/imx233/system-imx233.c8
-rw-r--r--firmware/target/arm/imx233/system-target.h36
-rw-r--r--firmware/target/arm/imx233/usb-imx233.c17
-rw-r--r--firmware/target/arm/imx233/usb-target.h36
17 files changed, 353 insertions, 104 deletions
diff --git a/bootloader/imx233.c b/bootloader/imx233.c
index f6c5ad9cf4..b160c79702 100644
--- a/bootloader/imx233.c
+++ b/bootloader/imx233.c
@@ -39,6 +39,69 @@
39#include "fmradio_i2c.h" 39#include "fmradio_i2c.h"
40 40
41#include "usb.h" 41#include "usb.h"
42#include "usb-target.h"
43
44#include "clkctrl-imx233.h"
45
46#ifdef HAVE_BOOTLOADER_USB_MODE
47static void usb_mode(int connect_timeout)
48{
49 int button;
50
51 usb_init();
52 usb_start_monitoring();
53
54 /* Wait for threads to connect or cable is pulled */
55 printf("USB: Connecting");
56
57 long end_tick = current_tick + connect_timeout;
58
59 while(1)
60 {
61 button = button_get_w_tmo(HZ/10);
62
63 if(button == SYS_USB_CONNECTED)
64 break; /* Hit */
65
66 if(TIME_AFTER(current_tick, end_tick))
67 {
68 /* Timed out waiting for the connect - will happen when connected
69 * to a charger through the USB port */
70 printf("USB: Timed out");
71 break;
72 }
73
74 if(!usb_plugged())
75 break; /* Cable pulled */
76 }
77
78 if(button == SYS_USB_CONNECTED)
79 {
80 /* Got the message - wait for disconnect */
81 printf("Bootloader USB mode");
82
83 usb_acknowledge(SYS_USB_CONNECTED_ACK);
84
85 while(1)
86 {
87 button = button_get_w_tmo(HZ/2);
88 if(button == SYS_USB_DISCONNECTED)
89 break;
90 }
91 }
92
93 /* Put drivers initialized for USB connection into a known state */
94 usb_close();
95
96 system_exception_wait();
97 power_off();
98}
99#else /* !HAVE_BOOTLOADER_USB_MODE */
100static void usb_mode(int connect_timeout)
101{
102 (void) connect_timeout;
103}
104#endif /* HAVE_BOOTLOADER_USB_MODE */
42 105
43void main(uint32_t arg) NORETURN_ATTR; 106void main(uint32_t arg) NORETURN_ATTR;
44void main(uint32_t arg) 107void main(uint32_t arg)
@@ -51,6 +114,7 @@ void main(uint32_t arg)
51 system_init(); 114 system_init();
52 kernel_init(); 115 kernel_init();
53 116
117 power_init();
54 enable_irq(); 118 enable_irq();
55 119
56 lcd_init(); 120 lcd_init();
@@ -59,32 +123,32 @@ void main(uint32_t arg)
59 123
60 backlight_init(); 124 backlight_init();
61 125
62 button_init_device(); 126 button_init();
63 127
64 //button_debug_screen(); 128 //button_debug_screen();
65 printf("arg=%c%c%c%c", arg >> 24, 129 printf("arg=%x", arg);
66 (arg >> 16) & 0xff, (arg >> 8) & 0xff, (arg & 0xff)); 130
131#ifdef SANSA_FUZEPLUS
132 extern void imx233_mmc_disable_window(void);
133 if(arg == 0xfee1dead)
134 {
135 printf("Disable MMC window.");
136 imx233_mmc_disable_window();
137 }
138#endif
67 139
68 ret = storage_init(); 140 ret = storage_init();
69 if(ret < 0) 141 if(ret < 0)
70 error(EATA, ret, true); 142 error(EATA, ret, true);
71 143
72 #ifdef HAVE_BOOTLOADER_USB_MODE 144 if(usb_plugged())
73 usb_init(); 145 usb_mode(HZ * 2);
74 usb_core_enable_driver(USB_DRIVER_SERIAL, true);
75 usb_attach();
76 while(!(button_read_device() & BUTTON_POWER))
77 yield();
78 power_off();
79 #endif /* HAVE_BOOTLOADER_USB_MODE */
80 146
81 while(!disk_init(IF_MV(0))) 147 while(!disk_init(IF_MV(0)))
82 panicf("disk_init failed!"); 148 printf("disk_init failed!");
83 149
84 while((ret = disk_mount_all()) <= 0) 150 if((ret = disk_mount_all()) <= 0)
85 { 151 error(EDISK, ret, false);
86 error(EDISK, ret, true);
87 }
88 152
89 if(button_read_device() & BUTTON_VOL_UP) 153 if(button_read_device() & BUTTON_VOL_UP)
90 printf("Booting from SD card required."); 154 printf("Booting from SD card required.");
diff --git a/firmware/export/config.h b/firmware/export/config.h
index 57e6bb8a59..e1ce15a562 100644
--- a/firmware/export/config.h
+++ b/firmware/export/config.h
@@ -937,7 +937,7 @@ Lyre prototype 1 */
937 937
938#endif /* CPU_PP */ 938#endif /* CPU_PP */
939 939
940#if CONFIG_CPU == IMX31L 940#if CONFIG_CPU == IMX31L || CONFIG_CPU == IMX233
941#define NOCACHEBSS_ATTR __attribute__((section(".ncbss"),nocommon)) 941#define NOCACHEBSS_ATTR __attribute__((section(".ncbss"),nocommon))
942#define NOCACHEDATA_ATTR __attribute__((section(".ncdata"),nocommon)) 942#define NOCACHEDATA_ATTR __attribute__((section(".ncdata"),nocommon))
943#endif 943#endif
diff --git a/firmware/export/config/sansafuzeplus.h b/firmware/export/config/sansafuzeplus.h
index 971ff019b6..13ad3af8ed 100644
--- a/firmware/export/config/sansafuzeplus.h
+++ b/firmware/export/config/sansafuzeplus.h
@@ -172,7 +172,7 @@
172#define USB_VENDOR_ID 0x0781 172#define USB_VENDOR_ID 0x0781
173#define USB_PRODUCT_ID 0x74e1 173#define USB_PRODUCT_ID 0x74e1
174#define HAVE_USB_HID_MOUSE 174#define HAVE_USB_HID_MOUSE
175//#define HAVE_BOOTLOADER_USB_MODE 175#define HAVE_BOOTLOADER_USB_MODE
176 176
177/* The fuze+ actually interesting partition table does not use 512-byte sector 177/* The fuze+ actually interesting partition table does not use 512-byte sector
178 * (usually 2048 logical sector size) */ 178 * (usually 2048 logical sector size) */
diff --git a/firmware/export/imx233.h b/firmware/export/imx233.h
index d9ea06a420..2a2097b5d7 100644
--- a/firmware/export/imx233.h
+++ b/firmware/export/imx233.h
@@ -21,17 +21,41 @@
21#ifndef __IMX233_H__ 21#ifndef __IMX233_H__
22#define __IMX233_H__ 22#define __IMX233_H__
23 23
24/*
25 * Chip Memory Map:
26 * 0x00000000 - 0x00007fff: on chip ram
27 * 0x40000000 - 0x5fffffff: dram (512Mb max)
28 * 0x80000000 - 0x80100000: memory mapped registers
29 * We use the following map:
30 * 0x60000000 - 0x7fffffff: dram (cached)
31 * 0x90000000 - 0xafffffff: dram (buffered)
32 * everything else : identity mapped (uncached)
33 *
34 * As a side note it's important to notice that uncached dram is identity mapped
35 */
36
24#define IRAM_ORIG 0 37#define IRAM_ORIG 0
25#define IRAM_SIZE 0x8000 38#define IRAM_SIZE 0x8000
26#define DRAM_ORIG 0x40000000 39#define DRAM_ORIG 0x40000000
27#define DRAM_SIZE (MEMORYSIZE * 0x100000) 40#define DRAM_SIZE (MEMORYSIZE * 0x100000)
28 41
42#define UNCACHED_DRAM_ADDR 0x40000000
43#define CACHED_DRAM_ADDR 0x60000000
44#define BUFFERED_DRAM_ADDR 0x90000000
45#define CACHEALIGN_SIZE 32
46
47#define PHYSICAL_ADDR(a) \
48 ((typeof(a))((uintptr_t)(a) >= CACHED_DRAM_ADDR ? \
49 ((uintptr_t)(a) - CACHED_DRAM_ADDR + UNCACHED_DRAM_ADDR) \
50 :(uintptr_t)(a)))
51#define UNCACHED_ADDR(a) PHYSICAL_ADDR(a)
52
29#define TTB_BASE_ADDR (DRAM_ORIG + DRAM_SIZE - TTB_SIZE) 53#define TTB_BASE_ADDR (DRAM_ORIG + DRAM_SIZE - TTB_SIZE)
30#define TTB_SIZE 0x4000 54#define TTB_SIZE 0x4000
31#define TTB_BASE ((unsigned long *)TTB_BASE_ADDR) 55#define TTB_BASE ((unsigned long *)TTB_BASE_ADDR)
32#define FRAME_SIZE (LCD_WIDTH * LCD_HEIGHT * LCD_DEPTH / 8) 56#define FRAME_SIZE (LCD_WIDTH * LCD_HEIGHT * LCD_DEPTH / 8)
33#define LCD_FRAME_ADDR (DRAM_ORIG + DRAM_SIZE - TTB_SIZE - FRAME_SIZE) 57#define FRAME_PHYS_ADDR (DRAM_ORIG + DRAM_SIZE - TTB_SIZE - FRAME_SIZE)
34#define FRAME ((unsigned short *)LCD_FRAME_ADDR) 58#define FRAME ((void *)(FRAME_PHYS_ADDR - UNCACHED_DRAM_ADDR + BUFFERED_DRAM_ADDR))
35 59
36/* USBOTG */ 60/* USBOTG */
37#define USB_QHARRAY_ATTR __attribute__((section(".qharray"),nocommon,aligned(2048))) 61#define USB_QHARRAY_ATTR __attribute__((section(".qharray"),nocommon,aligned(2048)))
@@ -52,5 +76,7 @@
52 76
53#define CACHEALIGN_BITS 4 77#define CACHEALIGN_BITS 4
54 78
79#define __XTRACT(reg, field) ((reg & reg##__##field##_BM) >> reg##__##field##_BP)
80#define __XTRACT_EX(val, field) (((val) & field##_BM) >> field##_BP)
55 81
56#endif /* __IMX233_H__ */ 82#endif /* __IMX233_H__ */
diff --git a/firmware/target/arm/imx233/boot.lds b/firmware/target/arm/imx233/boot.lds
index 8e4f2016df..fb6ffdcf23 100644
--- a/firmware/target/arm/imx233/boot.lds
+++ b/firmware/target/arm/imx233/boot.lds
@@ -9,7 +9,8 @@ STARTUP(target/arm/imx233/crt0.o)
9MEMORY 9MEMORY
10{ 10{
11 IRAM : ORIGIN = IRAM_ORIG, LENGTH = IRAM_SIZE 11 IRAM : ORIGIN = IRAM_ORIG, LENGTH = IRAM_SIZE
12 DRAM : ORIGIN = DRAM_ORIG, LENGTH = DRAM_SIZE - TTB_SIZE - FRAME_SIZE 12 DRAM : ORIGIN = CACHED_DRAM_ADDR, LENGTH = DRAM_SIZE - TTB_SIZE - FRAME_SIZE
13 UNCACHED_DRAM : ORIGIN = UNCACHED_DRAM_ADDR, LENGTH = DRAM_SIZE - TTB_SIZE - FRAME_SIZE
13} 14}
14 15
15SECTIONS 16SECTIONS
@@ -57,10 +58,23 @@ SECTIONS
57 stackend = .; 58 stackend = .;
58 } > DRAM 59 } > DRAM
59 60
61 /* treat .bss and .ncbss as a single section */
60 .bss (NOLOAD) : 62 .bss (NOLOAD) :
61 { 63 {
62 _edata = .; 64 _edata = .;
63 *(.bss*); 65 *(.bss*);
66 } > DRAM
67
68 /* align on cache size boundary to avoid mixing cached and noncached stuff */
69 .ncbss . - CACHED_DRAM_ADDR + UNCACHED_DRAM_ADDR (NOLOAD) :
70 {
71 . = ALIGN(CACHEALIGN_SIZE);
72 *(.ncbss*)
73 . = ALIGN(CACHEALIGN_SIZE);
74 } AT> DRAM
75
76 .bssendadr . - UNCACHED_DRAM_ADDR + CACHED_DRAM_ADDR (NOLOAD) :
77 {
64 _end = .; 78 _end = .;
65 } > DRAM 79 } > DRAM
66} 80}
diff --git a/firmware/target/arm/imx233/crt0.S b/firmware/target/arm/imx233/crt0.S
index a0f9ec270b..ab0250f6b6 100644
--- a/firmware/target/arm/imx233/crt0.S
+++ b/firmware/target/arm/imx233/crt0.S
@@ -33,6 +33,9 @@
33 ldr pc, =irq_handler 33 ldr pc, =irq_handler
34 ldr pc, =fiq_handler 34 ldr pc, =fiq_handler
35 35
36/* When starting, we are running at 0x40000000 but the code
37 * assumes DRAM is somewhere else (for caching) so we first need to
38 * setup the MMU and then jump to the right location */
36.text 39.text
37.global start 40.global start
38start: 41start:
@@ -46,6 +49,13 @@ start:
46 bic r0, r1 49 bic r0, r1
47 mcr p15, 0, r0, c1, c0, 0 50 mcr p15, 0, r0, c1, c0, 0
48 51
52 /* Enable MMU */
53 bl memory_init
54
55 /* Jump to real location */
56 ldr pc, =remap
57remap:
58
49 /* Zero out IBSS */ 59 /* Zero out IBSS */
50 ldr r2, =_iedata 60 ldr r2, =_iedata
51 ldr r3, =_iend 61 ldr r3, =_iend
@@ -114,9 +124,6 @@ start:
114 msr cpsr_c, #0xdb 124 msr cpsr_c, #0xdb
115 ldr sp, =irq_stack 125 ldr sp, =irq_stack
116 126
117 /* Enable MMU */
118 bl memory_init
119
120 /* Switch back to supervisor mode */ 127 /* Switch back to supervisor mode */
121 msr cpsr_c, #0xd3 128 msr cpsr_c, #0xd3
122 129
diff --git a/firmware/target/arm/imx233/dma-imx233.c b/firmware/target/arm/imx233/dma-imx233.c
index 8a42bd12da..eba41958a9 100644
--- a/firmware/target/arm/imx233/dma-imx233.c
+++ b/firmware/target/arm/imx233/dma-imx233.c
@@ -107,7 +107,8 @@ bool imx233_dma_is_channel_error_irq(unsigned chan)
107} 107}
108 108
109/* Commit and/or discard all DMA descriptors and buffers pointed by them, 109/* Commit and/or discard all DMA descriptors and buffers pointed by them,
110 * handle circular lists */ 110 * handle circular lists. At the same time, convert virtual pointers to
111 * real ones */
111static void imx233_dma_commit_and_discard(struct apb_dma_command_t *cmd) 112static void imx233_dma_commit_and_discard(struct apb_dma_command_t *cmd)
112{ 113{
113 /* We handle circular descriptors by using unused bits: 114 /* We handle circular descriptors by using unused bits:
@@ -121,13 +122,15 @@ static void imx233_dma_commit_and_discard(struct apb_dma_command_t *cmd)
121 { 122 {
122 cur->cmd = (cur->cmd & ~HW_APB_CHx_CMD__UNUSED_BM) | HW_APB_CHx_CMD__UNUSED_MAGIC; 123 cur->cmd = (cur->cmd & ~HW_APB_CHx_CMD__UNUSED_BM) | HW_APB_CHx_CMD__UNUSED_MAGIC;
123 int op = cur->cmd & HW_APB_CHx_CMD__COMMAND_BM; 124 int op = cur->cmd & HW_APB_CHx_CMD__COMMAND_BM;
124 int sz = (cur->cmd & HW_APB_CHx_CMD__XFER_COUNT_BM) >> HW_APB_CHx_CMD__XFER_COUNT_BP; 125 int sz = __XTRACT_EX(cur->cmd, HW_APB_CHx_CMD__XFER_COUNT);
125 /* device > host: discard */ 126 /* device > host: discard */
126 if(op == HW_APB_CHx_CMD__COMMAND__WRITE) 127 if(op == HW_APB_CHx_CMD__COMMAND__WRITE)
127 discard_dcache_range(cur->buffer, sz); 128 discard_dcache_range(cur->buffer, sz);
128 /* host > device: commit and discard */ 129 /* host > device: commit and discard */
129 else if(op == HW_APB_CHx_CMD__COMMAND__READ) 130 else if(op == HW_APB_CHx_CMD__COMMAND__READ)
130 commit_discard_dcache_range(cur->buffer, sz); 131 commit_discard_dcache_range(cur->buffer, sz);
132 /* Virtual to physical buffer pointer conversion */
133 cur->buffer = PHYSICAL_ADDR(cur->buffer);
131 /* chain ? */ 134 /* chain ? */
132 if(cur->cmd & HW_APB_CHx_CMD__CHAIN) 135 if(cur->cmd & HW_APB_CHx_CMD__CHAIN)
133 cur = cur->next; 136 cur = cur->next;
@@ -139,15 +142,21 @@ static void imx233_dma_commit_and_discard(struct apb_dma_command_t *cmd)
139 while((cur->cmd & HW_APB_CHx_CMD__UNUSED_BM) != 0) 142 while((cur->cmd & HW_APB_CHx_CMD__UNUSED_BM) != 0)
140 { 143 {
141 cur->cmd = cur->cmd & ~HW_APB_CHx_CMD__UNUSED_BM; 144 cur->cmd = cur->cmd & ~HW_APB_CHx_CMD__UNUSED_BM;
142 int sz = (cur->cmd & HW_APB_CHx_CMD__CMDWORDS_BM) >> HW_APB_CHx_CMD__CMDWORDS_BP; 145 int sz = __XTRACT_EX(cur->cmd, HW_APB_CHx_CMD__CMDWORDS) * sizeof(uint32_t);
143 /* commit descriptor (don't discard since we access it after) */ 146 /* commit descriptor and discard descriptor */
144 commit_dcache_range(cur,
145 sizeof(struct apb_dma_command_t) + sizeof(uint32_t) * sz);
146 /* chain ? */ 147 /* chain ? */
147 if(cur->cmd & HW_APB_CHx_CMD__CHAIN) 148 if(cur->cmd & HW_APB_CHx_CMD__CHAIN)
148 cur = cur->next; 149 {
150 struct apb_dma_command_t *next = cur->next;
151 cur->next = PHYSICAL_ADDR(cur->next);
152 commit_dcache_range(cur, sizeof(struct apb_dma_command_t) + sz);
153 cur = next;
154 }
149 else 155 else
156 {
157 commit_dcache_range(cur, sizeof(struct apb_dma_command_t) + sz);
150 break; 158 break;
159 }
151 } 160 }
152} 161}
153 162
@@ -156,12 +165,12 @@ void imx233_dma_start_command(unsigned chan, struct apb_dma_command_t *cmd)
156 imx233_dma_commit_and_discard(cmd); 165 imx233_dma_commit_and_discard(cmd);
157 if(APB_IS_APBX_CHANNEL(chan)) 166 if(APB_IS_APBX_CHANNEL(chan))
158 { 167 {
159 HW_APBX_CHx_NXTCMDAR(APB_GET_DMA_CHANNEL(chan)) = (uint32_t)cmd; 168 HW_APBX_CHx_NXTCMDAR(APB_GET_DMA_CHANNEL(chan)) = (uint32_t)PHYSICAL_ADDR(cmd);
160 HW_APBX_CHx_SEMA(APB_GET_DMA_CHANNEL(chan)) = 1; 169 HW_APBX_CHx_SEMA(APB_GET_DMA_CHANNEL(chan)) = 1;
161 } 170 }
162 else 171 else
163 { 172 {
164 HW_APBH_CHx_NXTCMDAR(APB_GET_DMA_CHANNEL(chan)) = (uint32_t)cmd; 173 HW_APBH_CHx_NXTCMDAR(APB_GET_DMA_CHANNEL(chan)) = (uint32_t)PHYSICAL_ADDR(cmd);
165 HW_APBH_CHx_SEMA(APB_GET_DMA_CHANNEL(chan)) = 1; 174 HW_APBH_CHx_SEMA(APB_GET_DMA_CHANNEL(chan)) = 1;
166 } 175 }
167} 176}
diff --git a/firmware/target/arm/imx233/lcdif-imx233.c b/firmware/target/arm/imx233/lcdif-imx233.c
index 0b96cbf2bc..9173b5761c 100644
--- a/firmware/target/arm/imx233/lcdif-imx233.c
+++ b/firmware/target/arm/imx233/lcdif-imx233.c
@@ -79,7 +79,7 @@ void imx233_lcdif_set_word_length(unsigned word_length)
79 79
80unsigned imx233_lcdif_enable_irqs(unsigned irq_bm) 80unsigned imx233_lcdif_enable_irqs(unsigned irq_bm)
81{ 81{
82 unsigned old_msk = (HW_LCDIF_CTRL1 & HW_LCDIF_CTRL1__IRQ_EN_BM) >>HW_LCDIF_CTRL1__IRQ_EN_BP ; 82 unsigned old_msk = __XTRACT(HW_LCDIF_CTRL1, IRQ_EN);
83 /* clear irq status */ 83 /* clear irq status */
84 __REG_CLR(HW_LCDIF_CTRL1) = irq_bm << HW_LCDIF_CTRL1__IRQ_BP; 84 __REG_CLR(HW_LCDIF_CTRL1) = irq_bm << HW_LCDIF_CTRL1__IRQ_BP;
85 /* disable irqs */ 85 /* disable irqs */
diff --git a/firmware/target/arm/imx233/mmc-imx233.c b/firmware/target/arm/imx233/mmc-imx233.c
index 889ba0cb82..d2e76e7f6c 100644
--- a/firmware/target/arm/imx233/mmc-imx233.c
+++ b/firmware/target/arm/imx233/mmc-imx233.c
@@ -41,9 +41,15 @@
41/** When set, this values restrict the windows of the read and writes */ 41/** When set, this values restrict the windows of the read and writes */
42static unsigned mmc_window_start = 0; 42static unsigned mmc_window_start = 0;
43static unsigned mmc_window_end = INT_MAX; 43static unsigned mmc_window_end = INT_MAX;
44static bool mmc_window_enable = true;
44 45
45static struct mutex mmc_mutex; 46static struct mutex mmc_mutex;
46 47
48void imx233_mmc_disable_window(void)
49{
50 mmc_window_enable = false;
51}
52
47int mmc_init(void) 53int mmc_init(void)
48{ 54{
49 mutex_init(&mmc_mutex); 55 mutex_init(&mmc_mutex);
@@ -123,34 +129,37 @@ int mmc_init(void)
123 imx233_ssp_set_timings(MMC_SSP, 2, 0, 0xffff); 129 imx233_ssp_set_timings(MMC_SSP, 2, 0, 0xffff);
124 130
125 #ifdef SANSA_FUZEPLUS 131 #ifdef SANSA_FUZEPLUS
126 /** 132 if(mmc_window_enable)
127 * The Fuze+ uses a strange layout: is has a first MBR at sector 0 with four entries: 133 {
128 * 1) Actual user partition 134 /**
129 * 2) Sigmatel boot partition 135 * The Fuze+ uses a strange layout: is has a first MBR at sector 0 with four entries:
130 * 3)4) Other (certificate related ?) partitions 136 * 1) Actual user partition
131 * The partition 1) has type 1 but it's actually a type 5 (logical partition) with 137 * 2) Sigmatel boot partition
132 * a second partition table with usually one entry which is the FAT32 one. 138 * 3)4) Other (certificate related ?) partitions
133 * The first table uses 512-byte sector size and the second one usually uses 139 * The partition 1) has type 1 but it's actually a type 5 (logical partition) with
134 * 2048-byte logical sector size. 140 * a second partition table with usually one entry which is the FAT32 one.
135 * 141 * The first table uses 512-byte sector size and the second one usually uses
136 * We restrict mmc window to the user partition */ 142 * 2048-byte logical sector size.
137 uint8_t mbr[512]; 143 *
138 mmc_window_start = 0; 144 * We restrict mmc window to the user partition */
139 mmc_window_end = INT_MAX; 145 uint8_t mbr[512];
140 ret = mmc_read_sectors(IF_MD2(0,) 0, 1, mbr); 146 mmc_window_start = 0;
141 if(ret != 0) 147 mmc_window_end = INT_MAX;
142 return -100; 148 ret = mmc_read_sectors(IF_MD2(0,) 0, 1, mbr);
143 if(mbr[510] != 0x55 || mbr[511] != 0xAA) 149 if(ret != 0)
144 return -101; /* invalid MBR */ 150 return -100;
145 /* sanity check that the first partition is greater than 2Gib */ 151 if(mbr[510] != 0x55 || mbr[511] != 0xAA)
146 uint8_t *ent = &mbr[446]; 152 return -101; /* invalid MBR */
147 mmc_window_start = ent[8] | ent[9] << 8 | ent[10] << 16 | ent[11] << 24; 153 /* sanity check that the first partition is greater than 2Gib */
148 mmc_window_end = (ent[12] | ent[13] << 8 | ent[14] << 16 | ent[15] << 24) + 154 uint8_t *ent = &mbr[446];
149 mmc_window_start; 155 mmc_window_start = ent[8] | ent[9] << 8 | ent[10] << 16 | ent[11] << 24;
150 if(ent[4] == 0x53) 156 mmc_window_end = (ent[12] | ent[13] << 8 | ent[14] << 16 | ent[15] << 24) +
151 return -102; /* sigmatel partition */ 157 mmc_window_start;
152 if((mmc_window_end - mmc_window_start) < 4 * 1024 * 1024) 158 if(ent[4] == 0x53)
153 return -103; /* partition too small */ 159 return -102; /* sigmatel partition */
160 if((mmc_window_end - mmc_window_start) < 4 * 1024 * 1024)
161 return -103; /* partition too small */
162 }
154 #endif 163 #endif
155 164
156 return 0; 165 return 0;
@@ -221,3 +230,9 @@ bool mmc_present(IF_MD(int drive))
221 IF_MD((void) drive); 230 IF_MD((void) drive);
222 return true; 231 return true;
223} 232}
233
234bool mmc_removable(IF_MD(int drive))
235{
236 IF_MD((void) drive);
237 return false;
238}
diff --git a/firmware/target/arm/imx233/power-imx233.c b/firmware/target/arm/imx233/power-imx233.c
index f01a4ad3f2..d9f390c985 100644
--- a/firmware/target/arm/imx233/power-imx233.c
+++ b/firmware/target/arm/imx233/power-imx233.c
@@ -23,9 +23,33 @@
23#include "system.h" 23#include "system.h"
24#include "power.h" 24#include "power.h"
25#include "system-target.h" 25#include "system-target.h"
26#include "usb-target.h"
27
28void INT_VDD5V(void)
29{
30 if(HW_POWER_CTRL & HW_POWER_CTRL__VBUSVALID_IRQ)
31 {
32 if(HW_POWER_STS & HW_POWER_STS__VBUSVALID)
33 usb_insert_int();
34 else
35 usb_remove_int();
36 /* reverse polarity */
37 __REG_TOG(HW_POWER_CTRL) = HW_POWER_CTRL__POLARITY_VBUSVALID;
38 /* enable int */
39 __REG_CLR(HW_POWER_CTRL) = HW_POWER_CTRL__VBUSVALID_IRQ;
40 }
41}
26 42
27void power_init(void) 43void power_init(void)
28{ 44{
45 /* clear vbusvalid irq and set correct polarity */
46 __REG_CLR(HW_POWER_CTRL) = HW_POWER_CTRL__VBUSVALID_IRQ;
47 if(HW_POWER_STS & HW_POWER_STS__VBUSVALID)
48 __REG_CLR(HW_POWER_CTRL) = HW_POWER_CTRL__POLARITY_VBUSVALID;
49 else
50 __REG_SET(HW_POWER_CTRL) = HW_POWER_CTRL__POLARITY_VBUSVALID;
51 __REG_SET(HW_POWER_CTRL) = HW_POWER_CTRL__ENIRQ_VBUS_VALID;
52 imx233_enable_interrupt(INT_SRC_VDD5V, true);
29} 53}
30 54
31void power_off(void) 55void power_off(void)
diff --git a/firmware/target/arm/imx233/power-imx233.h b/firmware/target/arm/imx233/power-imx233.h
new file mode 100644
index 0000000000..c37fdd60d9
--- /dev/null
+++ b/firmware/target/arm/imx233/power-imx233.h
@@ -0,0 +1,69 @@
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 __POWER_IMX233__
22#define __POWER_IMX233__
23
24#include "system.h"
25#include "system-target.h"
26#include "cpu.h"
27
28#define HW_POWER_BASE 0x80044000
29
30#define HW_POWER_CTRL (*(volatile uint32_t *)(HW_POWER_BASE + 0x0))
31#define HW_POWER_CTRL__ENIRQ_VBUS_VALID (1 << 3)
32#define HW_POWER_CTRL__VBUSVALID_IRQ (1 << 4)
33#define HW_POWER_CTRL__POLARITY_VBUSVALID (1 << 5)
34
35#define HW_POWER_5VCTRL (*(volatile uint32_t *)(HW_POWER_BASE + 0x10))
36#define HW_POWER_5VCTRL__VBUSVALID_5VDETECT (1 << 4)
37#define HW_POWER_5VCTRL__VBUSVALID_TRSH_BP 8
38#define HW_POWER_5VCTRL__VBUSVALID_TRSH_BM (0x7 << 8)
39
40#define HW_POWER_MINPWR (*(volatile uint32_t *)(HW_POWER_BASE + 0x20))
41
42#define HW_POWER_CHARGE (*(volatile uint32_t *)(HW_POWER_BASE + 0x30))
43
44#define HW_POWER_VDDDCTRL (*(volatile uint32_t *)(HW_POWER_BASE + 0x40))
45#define HW_POWER_VDDDCTRL__TRG_BP 0
46#define HW_POWER_VDDDCTRL__TRG_BM 0x1f
47#define HW_POWER_VDDDCTRL__TRG_STEP 25 /* mV */
48#define HW_POWER_VDDDCTRL__TRG_MIN 800 /* mV */
49
50#define HW_POWER_VDDACTRL (*(volatile uint32_t *)(HW_POWER_BASE + 0x50))
51
52#define HW_POWER_VDDIOCTRL (*(volatile uint32_t *)(HW_POWER_BASE + 0x60))
53
54#define HW_POWER_VDDMEMCTRL (*(volatile uint32_t *)(HW_POWER_BASE + 0x70))
55
56#define HW_POWER_MISC (*(volatile uint32_t *)(HW_POWER_BASE + 0x90))
57
58#define HW_POWER_STS (*(volatile uint32_t *)(HW_POWER_BASE + 0xc0))
59#define HW_POWER_STS__VBUSVALID (1 << 1)
60#define HW_POWER_STS__PSWITCH_BP 20
61#define HW_POWER_STS__PSWITCH_BM (3 << 20)
62
63#define HW_POWER_BATTMONITOR (*(volatile uint32_t *)(HW_POWER_BASE + 0xe0))
64
65#define HW_POWER_RESET (*(volatile uint32_t *)(HW_POWER_BASE + 0x100))
66#define HW_POWER_RESET__UNLOCK 0x3E770000
67#define HW_POWER_RESET__PWD 0x1
68
69#endif /* __POWER_IMX233__ */
diff --git a/firmware/target/arm/imx233/sansa-fuzeplus/lcd-fuzeplus.c b/firmware/target/arm/imx233/sansa-fuzeplus/lcd-fuzeplus.c
index 2e49e4d3d0..539229e59e 100644
--- a/firmware/target/arm/imx233/sansa-fuzeplus/lcd-fuzeplus.c
+++ b/firmware/target/arm/imx233/sansa-fuzeplus/lcd-fuzeplus.c
@@ -509,7 +509,7 @@ void lcd_update(void)
509 imx233_lcdif_set_data_format(false, false, false); /* RGB565, don't care, don't care */ 509 imx233_lcdif_set_data_format(false, false, false); /* RGB565, don't care, don't care */
510 lcd_copy_buffer_rect((fb_data *)FRAME, &lcd_framebuffer[0][0], 510 lcd_copy_buffer_rect((fb_data *)FRAME, &lcd_framebuffer[0][0],
511 LCD_WIDTH * LCD_HEIGHT, 1); 511 LCD_WIDTH * LCD_HEIGHT, 1);
512 imx233_lcdif_dma_send(FRAME, LCD_WIDTH, LCD_HEIGHT); 512 imx233_lcdif_dma_send((void *)FRAME_PHYS_ADDR, LCD_WIDTH, LCD_HEIGHT);
513} 513}
514 514
515void lcd_update_rect(int x, int y, int width, int height) 515void lcd_update_rect(int x, int y, int width, int height)
diff --git a/firmware/target/arm/imx233/sd-imx233.c b/firmware/target/arm/imx233/sd-imx233.c
index 16b7b91219..630797b8bc 100644
--- a/firmware/target/arm/imx233/sd-imx233.c
+++ b/firmware/target/arm/imx233/sd-imx233.c
@@ -227,3 +227,9 @@ bool sd_present(IF_MD(int drive))
227 return imx233_ssp_sdmmc_detect(SD_SSP); 227 return imx233_ssp_sdmmc_detect(SD_SSP);
228} 228}
229 229
230bool sd_removable(IF_MD(int drive))
231{
232 IF_MD((void) drive);
233 return true;
234}
235
diff --git a/firmware/target/arm/imx233/system-imx233.c b/firmware/target/arm/imx233/system-imx233.c
index c4a32dd46e..68f16bf860 100644
--- a/firmware/target/arm/imx233/system-imx233.c
+++ b/firmware/target/arm/imx233/system-imx233.c
@@ -57,6 +57,7 @@ default_interrupt(INT_I2C_ERROR);
57default_interrupt(INT_GPIO0); 57default_interrupt(INT_GPIO0);
58default_interrupt(INT_GPIO1); 58default_interrupt(INT_GPIO1);
59default_interrupt(INT_GPIO2); 59default_interrupt(INT_GPIO2);
60default_interrupt(INT_VDD5V);
60 61
61typedef void (*isr_t)(void); 62typedef void (*isr_t)(void);
62 63
@@ -78,6 +79,7 @@ static isr_t isr_table[INT_SRC_NR_SOURCES] =
78 [INT_SRC_GPIO0] = INT_GPIO0, 79 [INT_SRC_GPIO0] = INT_GPIO0,
79 [INT_SRC_GPIO1] = INT_GPIO1, 80 [INT_SRC_GPIO1] = INT_GPIO1,
80 [INT_SRC_GPIO2] = INT_GPIO2, 81 [INT_SRC_GPIO2] = INT_GPIO2,
82 [INT_SRC_VDD5V] = INT_VDD5V,
81}; 83};
82 84
83static void UIRQ(void) 85static void UIRQ(void)
@@ -147,10 +149,8 @@ static void set_page_tables(void)
147 map_section(0, 0, 0x1000, CACHE_NONE); 149 map_section(0, 0, 0x1000, CACHE_NONE);
148 150
149 /* map RAM and enable caching for it */ 151 /* map RAM and enable caching for it */
150 map_section(DRAM_ORIG, DRAM_ORIG, MEMORYSIZE, CACHE_ALL); 152 map_section(DRAM_ORIG, CACHED_DRAM_ADDR, MEMORYSIZE, CACHE_ALL);
151 153 map_section(DRAM_ORIG, BUFFERED_DRAM_ADDR, MEMORYSIZE, BUFFERED);
152 /* enable buffered writing for the framebuffer */
153 map_section((int)FRAME, (int)FRAME, 1, BUFFERED);
154} 154}
155 155
156void memory_init(void) 156void memory_init(void)
diff --git a/firmware/target/arm/imx233/system-target.h b/firmware/target/arm/imx233/system-target.h
index 399ab845fd..a5dc63d430 100644
--- a/firmware/target/arm/imx233/system-target.h
+++ b/firmware/target/arm/imx233/system-target.h
@@ -26,44 +26,11 @@
26#include "panic.h" 26#include "panic.h"
27 27
28#include "clock-target.h" /* CPUFREQ_* are defined here */ 28#include "clock-target.h" /* CPUFREQ_* are defined here */
29#include "power-imx233.h"
29 30
30#define HW_DIGCTL_BASE 0x8001C000 31#define HW_DIGCTL_BASE 0x8001C000
31#define HW_DIGCTL_MICROSECONDS (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0xC0)) 32#define HW_DIGCTL_MICROSECONDS (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0xC0))
32 33
33#define HW_POWER_BASE 0x80044000
34
35#define HW_POWER_CTRL (*(volatile uint32_t *)(HW_POWER_BASE + 0x0))
36
37#define HW_POWER_5VCTRL (*(volatile uint32_t *)(HW_POWER_BASE + 0x10))
38
39#define HW_POWER_MINPWR (*(volatile uint32_t *)(HW_POWER_BASE + 0x20))
40
41#define HW_POWER_CHARGE (*(volatile uint32_t *)(HW_POWER_BASE + 0x30))
42
43#define HW_POWER_VDDDCTRL (*(volatile uint32_t *)(HW_POWER_BASE + 0x40))
44#define HW_POWER_VDDDCTRL__TRG_BP 0
45#define HW_POWER_VDDDCTRL__TRG_BM 0x1f
46#define HW_POWER_VDDDCTRL__TRG_STEP 25 /* mV */
47#define HW_POWER_VDDDCTRL__TRG_MIN 800 /* mV */
48
49#define HW_POWER_VDDACTRL (*(volatile uint32_t *)(HW_POWER_BASE + 0x50))
50
51#define HW_POWER_VDDIOCTRL (*(volatile uint32_t *)(HW_POWER_BASE + 0x60))
52
53#define HW_POWER_VDDMEMCTRL (*(volatile uint32_t *)(HW_POWER_BASE + 0x70))
54
55#define HW_POWER_MISC (*(volatile uint32_t *)(HW_POWER_BASE + 0x90))
56
57#define HW_POWER_STS (*(volatile uint32_t *)(HW_POWER_BASE + 0xc0))
58#define HW_POWER_STS__PSWITCH_BP 20
59#define HW_POWER_STS__PSWITCH_BM (3 << 20)
60
61#define HW_POWER_BATTMONITOR (*(volatile uint32_t *)(HW_POWER_BASE + 0xe0))
62
63#define HW_POWER_RESET (*(volatile uint32_t *)(HW_POWER_BASE + 0x100))
64#define HW_POWER_RESET__UNLOCK 0x3E770000
65#define HW_POWER_RESET__PWD 0x1
66
67#define HW_ICOLL_BASE 0x80000000 34#define HW_ICOLL_BASE 0x80000000
68 35
69#define HW_ICOLL_VECTOR (*(volatile uint32_t *)(HW_ICOLL_BASE + 0x0)) 36#define HW_ICOLL_VECTOR (*(volatile uint32_t *)(HW_ICOLL_BASE + 0x0))
@@ -83,6 +50,7 @@
83#define HW_ICOLL_INTERRUPT__ENFIQ 0x10 50#define HW_ICOLL_INTERRUPT__ENFIQ 0x10
84 51
85#define INT_SRC_SSP2_ERROR 2 52#define INT_SRC_SSP2_ERROR 2
53#define INT_SRC_VDD5V 3
86#define INT_SRC_USB_CTRL 11 54#define INT_SRC_USB_CTRL 11
87#define INT_SRC_SSP1_DMA 14 55#define INT_SRC_SSP1_DMA 14
88#define INT_SRC_SSP1_ERROR 15 56#define INT_SRC_SSP1_ERROR 15
diff --git a/firmware/target/arm/imx233/usb-imx233.c b/firmware/target/arm/imx233/usb-imx233.c
index e3b540fd1e..8e05da0a95 100644
--- a/firmware/target/arm/imx233/usb-imx233.c
+++ b/firmware/target/arm/imx233/usb-imx233.c
@@ -29,10 +29,20 @@
29#include "system.h" 29#include "system.h"
30#include "system-target.h" 30#include "system-target.h"
31 31
32int usb_status = USB_EXTRACTED; 32
33void usb_insert_int(void)
34{
35 usb_status_event(USB_POWERED);
36}
37
38void usb_remove_int(void)
39{
40 usb_status_event(USB_UNPOWERED);
41}
33 42
34void usb_drv_usb_detect_event() 43void usb_drv_usb_detect_event()
35{ 44{
45 printf("usb_drv_usb_detect_event");
36 usb_status_event(USB_INSERTED); 46 usb_status_event(USB_INSERTED);
37} 47}
38 48
@@ -58,16 +68,17 @@ void usb_init_device(void)
58 68
59int usb_detect(void) 69int usb_detect(void)
60{ 70{
61 return usb_status; 71 return usb_plugged() ? USB_INSERTED : USB_EXTRACTED;
62} 72}
63 73
64bool usb_plugged(void) 74bool usb_plugged(void)
65{ 75{
66 return true; 76 return !!(HW_POWER_STS & HW_POWER_STS__VBUSVALID);
67} 77}
68 78
69void usb_enable(bool on) 79void usb_enable(bool on)
70{ 80{
81 /* FIXME: power up/down usb phy and pll usb */
71 if(on) 82 if(on)
72 usb_core_init(); 83 usb_core_init();
73 else 84 else
diff --git a/firmware/target/arm/imx233/usb-target.h b/firmware/target/arm/imx233/usb-target.h
new file mode 100644
index 0000000000..8d6c0af372
--- /dev/null
+++ b/firmware/target/arm/imx233/usb-target.h
@@ -0,0 +1,36 @@
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 USB_TARGET_H
22#define USB_TARGET_H
23
24#include "config.h"
25
26#ifdef HAVE_BOOTLOADER_USB_MODE
27#define USB_DRIVER_CLOSE
28#endif
29
30void usb_init_device(void);
31int usb_detect(void);
32void usb_insert_int(void);
33void usb_remove_int(void);
34bool usb_plugged(void);
35
36#endif /* USB_TARGET_H */