forked from len0rd/rockbox
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
This commit is contained in:
parent
11e1f71612
commit
7d4fed53cc
17 changed files with 353 additions and 104 deletions
|
@ -39,6 +39,69 @@
|
||||||
#include "fmradio_i2c.h"
|
#include "fmradio_i2c.h"
|
||||||
|
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
|
#include "usb-target.h"
|
||||||
|
|
||||||
|
#include "clkctrl-imx233.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_BOOTLOADER_USB_MODE
|
||||||
|
static void usb_mode(int connect_timeout)
|
||||||
|
{
|
||||||
|
int button;
|
||||||
|
|
||||||
|
usb_init();
|
||||||
|
usb_start_monitoring();
|
||||||
|
|
||||||
|
/* Wait for threads to connect or cable is pulled */
|
||||||
|
printf("USB: Connecting");
|
||||||
|
|
||||||
|
long end_tick = current_tick + connect_timeout;
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
button = button_get_w_tmo(HZ/10);
|
||||||
|
|
||||||
|
if(button == SYS_USB_CONNECTED)
|
||||||
|
break; /* Hit */
|
||||||
|
|
||||||
|
if(TIME_AFTER(current_tick, end_tick))
|
||||||
|
{
|
||||||
|
/* Timed out waiting for the connect - will happen when connected
|
||||||
|
* to a charger through the USB port */
|
||||||
|
printf("USB: Timed out");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!usb_plugged())
|
||||||
|
break; /* Cable pulled */
|
||||||
|
}
|
||||||
|
|
||||||
|
if(button == SYS_USB_CONNECTED)
|
||||||
|
{
|
||||||
|
/* Got the message - wait for disconnect */
|
||||||
|
printf("Bootloader USB mode");
|
||||||
|
|
||||||
|
usb_acknowledge(SYS_USB_CONNECTED_ACK);
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
button = button_get_w_tmo(HZ/2);
|
||||||
|
if(button == SYS_USB_DISCONNECTED)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Put drivers initialized for USB connection into a known state */
|
||||||
|
usb_close();
|
||||||
|
|
||||||
|
system_exception_wait();
|
||||||
|
power_off();
|
||||||
|
}
|
||||||
|
#else /* !HAVE_BOOTLOADER_USB_MODE */
|
||||||
|
static void usb_mode(int connect_timeout)
|
||||||
|
{
|
||||||
|
(void) connect_timeout;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_BOOTLOADER_USB_MODE */
|
||||||
|
|
||||||
void main(uint32_t arg) NORETURN_ATTR;
|
void main(uint32_t arg) NORETURN_ATTR;
|
||||||
void main(uint32_t arg)
|
void main(uint32_t arg)
|
||||||
|
@ -51,6 +114,7 @@ void main(uint32_t arg)
|
||||||
system_init();
|
system_init();
|
||||||
kernel_init();
|
kernel_init();
|
||||||
|
|
||||||
|
power_init();
|
||||||
enable_irq();
|
enable_irq();
|
||||||
|
|
||||||
lcd_init();
|
lcd_init();
|
||||||
|
@ -59,32 +123,32 @@ void main(uint32_t arg)
|
||||||
|
|
||||||
backlight_init();
|
backlight_init();
|
||||||
|
|
||||||
button_init_device();
|
button_init();
|
||||||
|
|
||||||
//button_debug_screen();
|
//button_debug_screen();
|
||||||
printf("arg=%c%c%c%c", arg >> 24,
|
printf("arg=%x", arg);
|
||||||
(arg >> 16) & 0xff, (arg >> 8) & 0xff, (arg & 0xff));
|
|
||||||
|
#ifdef SANSA_FUZEPLUS
|
||||||
|
extern void imx233_mmc_disable_window(void);
|
||||||
|
if(arg == 0xfee1dead)
|
||||||
|
{
|
||||||
|
printf("Disable MMC window.");
|
||||||
|
imx233_mmc_disable_window();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
ret = storage_init();
|
ret = storage_init();
|
||||||
if(ret < 0)
|
if(ret < 0)
|
||||||
error(EATA, ret, true);
|
error(EATA, ret, true);
|
||||||
|
|
||||||
#ifdef HAVE_BOOTLOADER_USB_MODE
|
if(usb_plugged())
|
||||||
usb_init();
|
usb_mode(HZ * 2);
|
||||||
usb_core_enable_driver(USB_DRIVER_SERIAL, true);
|
|
||||||
usb_attach();
|
|
||||||
while(!(button_read_device() & BUTTON_POWER))
|
|
||||||
yield();
|
|
||||||
power_off();
|
|
||||||
#endif /* HAVE_BOOTLOADER_USB_MODE */
|
|
||||||
|
|
||||||
while(!disk_init(IF_MV(0)))
|
while(!disk_init(IF_MV(0)))
|
||||||
panicf("disk_init failed!");
|
printf("disk_init failed!");
|
||||||
|
|
||||||
while((ret = disk_mount_all()) <= 0)
|
if((ret = disk_mount_all()) <= 0)
|
||||||
{
|
error(EDISK, ret, false);
|
||||||
error(EDISK, ret, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(button_read_device() & BUTTON_VOL_UP)
|
if(button_read_device() & BUTTON_VOL_UP)
|
||||||
printf("Booting from SD card required.");
|
printf("Booting from SD card required.");
|
||||||
|
|
|
@ -937,7 +937,7 @@ Lyre prototype 1 */
|
||||||
|
|
||||||
#endif /* CPU_PP */
|
#endif /* CPU_PP */
|
||||||
|
|
||||||
#if CONFIG_CPU == IMX31L
|
#if CONFIG_CPU == IMX31L || CONFIG_CPU == IMX233
|
||||||
#define NOCACHEBSS_ATTR __attribute__((section(".ncbss"),nocommon))
|
#define NOCACHEBSS_ATTR __attribute__((section(".ncbss"),nocommon))
|
||||||
#define NOCACHEDATA_ATTR __attribute__((section(".ncdata"),nocommon))
|
#define NOCACHEDATA_ATTR __attribute__((section(".ncdata"),nocommon))
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -172,7 +172,7 @@
|
||||||
#define USB_VENDOR_ID 0x0781
|
#define USB_VENDOR_ID 0x0781
|
||||||
#define USB_PRODUCT_ID 0x74e1
|
#define USB_PRODUCT_ID 0x74e1
|
||||||
#define HAVE_USB_HID_MOUSE
|
#define HAVE_USB_HID_MOUSE
|
||||||
//#define HAVE_BOOTLOADER_USB_MODE
|
#define HAVE_BOOTLOADER_USB_MODE
|
||||||
|
|
||||||
/* The fuze+ actually interesting partition table does not use 512-byte sector
|
/* The fuze+ actually interesting partition table does not use 512-byte sector
|
||||||
* (usually 2048 logical sector size) */
|
* (usually 2048 logical sector size) */
|
||||||
|
|
|
@ -21,17 +21,41 @@
|
||||||
#ifndef __IMX233_H__
|
#ifndef __IMX233_H__
|
||||||
#define __IMX233_H__
|
#define __IMX233_H__
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Chip Memory Map:
|
||||||
|
* 0x00000000 - 0x00007fff: on chip ram
|
||||||
|
* 0x40000000 - 0x5fffffff: dram (512Mb max)
|
||||||
|
* 0x80000000 - 0x80100000: memory mapped registers
|
||||||
|
* We use the following map:
|
||||||
|
* 0x60000000 - 0x7fffffff: dram (cached)
|
||||||
|
* 0x90000000 - 0xafffffff: dram (buffered)
|
||||||
|
* everything else : identity mapped (uncached)
|
||||||
|
*
|
||||||
|
* As a side note it's important to notice that uncached dram is identity mapped
|
||||||
|
*/
|
||||||
|
|
||||||
#define IRAM_ORIG 0
|
#define IRAM_ORIG 0
|
||||||
#define IRAM_SIZE 0x8000
|
#define IRAM_SIZE 0x8000
|
||||||
#define DRAM_ORIG 0x40000000
|
#define DRAM_ORIG 0x40000000
|
||||||
#define DRAM_SIZE (MEMORYSIZE * 0x100000)
|
#define DRAM_SIZE (MEMORYSIZE * 0x100000)
|
||||||
|
|
||||||
|
#define UNCACHED_DRAM_ADDR 0x40000000
|
||||||
|
#define CACHED_DRAM_ADDR 0x60000000
|
||||||
|
#define BUFFERED_DRAM_ADDR 0x90000000
|
||||||
|
#define CACHEALIGN_SIZE 32
|
||||||
|
|
||||||
|
#define PHYSICAL_ADDR(a) \
|
||||||
|
((typeof(a))((uintptr_t)(a) >= CACHED_DRAM_ADDR ? \
|
||||||
|
((uintptr_t)(a) - CACHED_DRAM_ADDR + UNCACHED_DRAM_ADDR) \
|
||||||
|
:(uintptr_t)(a)))
|
||||||
|
#define UNCACHED_ADDR(a) PHYSICAL_ADDR(a)
|
||||||
|
|
||||||
#define TTB_BASE_ADDR (DRAM_ORIG + DRAM_SIZE - TTB_SIZE)
|
#define TTB_BASE_ADDR (DRAM_ORIG + DRAM_SIZE - TTB_SIZE)
|
||||||
#define TTB_SIZE 0x4000
|
#define TTB_SIZE 0x4000
|
||||||
#define TTB_BASE ((unsigned long *)TTB_BASE_ADDR)
|
#define TTB_BASE ((unsigned long *)TTB_BASE_ADDR)
|
||||||
#define FRAME_SIZE (LCD_WIDTH * LCD_HEIGHT * LCD_DEPTH / 8)
|
#define FRAME_SIZE (LCD_WIDTH * LCD_HEIGHT * LCD_DEPTH / 8)
|
||||||
#define LCD_FRAME_ADDR (DRAM_ORIG + DRAM_SIZE - TTB_SIZE - FRAME_SIZE)
|
#define FRAME_PHYS_ADDR (DRAM_ORIG + DRAM_SIZE - TTB_SIZE - FRAME_SIZE)
|
||||||
#define FRAME ((unsigned short *)LCD_FRAME_ADDR)
|
#define FRAME ((void *)(FRAME_PHYS_ADDR - UNCACHED_DRAM_ADDR + BUFFERED_DRAM_ADDR))
|
||||||
|
|
||||||
/* USBOTG */
|
/* USBOTG */
|
||||||
#define USB_QHARRAY_ATTR __attribute__((section(".qharray"),nocommon,aligned(2048)))
|
#define USB_QHARRAY_ATTR __attribute__((section(".qharray"),nocommon,aligned(2048)))
|
||||||
|
@ -52,5 +76,7 @@
|
||||||
|
|
||||||
#define CACHEALIGN_BITS 4
|
#define CACHEALIGN_BITS 4
|
||||||
|
|
||||||
|
#define __XTRACT(reg, field) ((reg & reg##__##field##_BM) >> reg##__##field##_BP)
|
||||||
|
#define __XTRACT_EX(val, field) (((val) & field##_BM) >> field##_BP)
|
||||||
|
|
||||||
#endif /* __IMX233_H__ */
|
#endif /* __IMX233_H__ */
|
||||||
|
|
|
@ -9,7 +9,8 @@ STARTUP(target/arm/imx233/crt0.o)
|
||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
IRAM : ORIGIN = IRAM_ORIG, LENGTH = IRAM_SIZE
|
IRAM : ORIGIN = IRAM_ORIG, LENGTH = IRAM_SIZE
|
||||||
DRAM : ORIGIN = DRAM_ORIG, LENGTH = DRAM_SIZE - TTB_SIZE - FRAME_SIZE
|
DRAM : ORIGIN = CACHED_DRAM_ADDR, LENGTH = DRAM_SIZE - TTB_SIZE - FRAME_SIZE
|
||||||
|
UNCACHED_DRAM : ORIGIN = UNCACHED_DRAM_ADDR, LENGTH = DRAM_SIZE - TTB_SIZE - FRAME_SIZE
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
|
@ -57,10 +58,23 @@ SECTIONS
|
||||||
stackend = .;
|
stackend = .;
|
||||||
} > DRAM
|
} > DRAM
|
||||||
|
|
||||||
|
/* treat .bss and .ncbss as a single section */
|
||||||
.bss (NOLOAD) :
|
.bss (NOLOAD) :
|
||||||
{
|
{
|
||||||
_edata = .;
|
_edata = .;
|
||||||
*(.bss*);
|
*(.bss*);
|
||||||
|
} > DRAM
|
||||||
|
|
||||||
|
/* align on cache size boundary to avoid mixing cached and noncached stuff */
|
||||||
|
.ncbss . - CACHED_DRAM_ADDR + UNCACHED_DRAM_ADDR (NOLOAD) :
|
||||||
|
{
|
||||||
|
. = ALIGN(CACHEALIGN_SIZE);
|
||||||
|
*(.ncbss*)
|
||||||
|
. = ALIGN(CACHEALIGN_SIZE);
|
||||||
|
} AT> DRAM
|
||||||
|
|
||||||
|
.bssendadr . - UNCACHED_DRAM_ADDR + CACHED_DRAM_ADDR (NOLOAD) :
|
||||||
|
{
|
||||||
_end = .;
|
_end = .;
|
||||||
} > DRAM
|
} > DRAM
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,9 @@
|
||||||
ldr pc, =irq_handler
|
ldr pc, =irq_handler
|
||||||
ldr pc, =fiq_handler
|
ldr pc, =fiq_handler
|
||||||
|
|
||||||
|
/* When starting, we are running at 0x40000000 but the code
|
||||||
|
* assumes DRAM is somewhere else (for caching) so we first need to
|
||||||
|
* setup the MMU and then jump to the right location */
|
||||||
.text
|
.text
|
||||||
.global start
|
.global start
|
||||||
start:
|
start:
|
||||||
|
@ -46,6 +49,13 @@ start:
|
||||||
bic r0, r1
|
bic r0, r1
|
||||||
mcr p15, 0, r0, c1, c0, 0
|
mcr p15, 0, r0, c1, c0, 0
|
||||||
|
|
||||||
|
/* Enable MMU */
|
||||||
|
bl memory_init
|
||||||
|
|
||||||
|
/* Jump to real location */
|
||||||
|
ldr pc, =remap
|
||||||
|
remap:
|
||||||
|
|
||||||
/* Zero out IBSS */
|
/* Zero out IBSS */
|
||||||
ldr r2, =_iedata
|
ldr r2, =_iedata
|
||||||
ldr r3, =_iend
|
ldr r3, =_iend
|
||||||
|
@ -114,9 +124,6 @@ start:
|
||||||
msr cpsr_c, #0xdb
|
msr cpsr_c, #0xdb
|
||||||
ldr sp, =irq_stack
|
ldr sp, =irq_stack
|
||||||
|
|
||||||
/* Enable MMU */
|
|
||||||
bl memory_init
|
|
||||||
|
|
||||||
/* Switch back to supervisor mode */
|
/* Switch back to supervisor mode */
|
||||||
msr cpsr_c, #0xd3
|
msr cpsr_c, #0xd3
|
||||||
|
|
||||||
|
|
|
@ -107,7 +107,8 @@ bool imx233_dma_is_channel_error_irq(unsigned chan)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Commit and/or discard all DMA descriptors and buffers pointed by them,
|
/* Commit and/or discard all DMA descriptors and buffers pointed by them,
|
||||||
* handle circular lists */
|
* handle circular lists. At the same time, convert virtual pointers to
|
||||||
|
* real ones */
|
||||||
static void imx233_dma_commit_and_discard(struct apb_dma_command_t *cmd)
|
static void imx233_dma_commit_and_discard(struct apb_dma_command_t *cmd)
|
||||||
{
|
{
|
||||||
/* We handle circular descriptors by using unused bits:
|
/* 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)
|
||||||
{
|
{
|
||||||
cur->cmd = (cur->cmd & ~HW_APB_CHx_CMD__UNUSED_BM) | HW_APB_CHx_CMD__UNUSED_MAGIC;
|
cur->cmd = (cur->cmd & ~HW_APB_CHx_CMD__UNUSED_BM) | HW_APB_CHx_CMD__UNUSED_MAGIC;
|
||||||
int op = cur->cmd & HW_APB_CHx_CMD__COMMAND_BM;
|
int op = cur->cmd & HW_APB_CHx_CMD__COMMAND_BM;
|
||||||
int sz = (cur->cmd & HW_APB_CHx_CMD__XFER_COUNT_BM) >> HW_APB_CHx_CMD__XFER_COUNT_BP;
|
int sz = __XTRACT_EX(cur->cmd, HW_APB_CHx_CMD__XFER_COUNT);
|
||||||
/* device > host: discard */
|
/* device > host: discard */
|
||||||
if(op == HW_APB_CHx_CMD__COMMAND__WRITE)
|
if(op == HW_APB_CHx_CMD__COMMAND__WRITE)
|
||||||
discard_dcache_range(cur->buffer, sz);
|
discard_dcache_range(cur->buffer, sz);
|
||||||
/* host > device: commit and discard */
|
/* host > device: commit and discard */
|
||||||
else if(op == HW_APB_CHx_CMD__COMMAND__READ)
|
else if(op == HW_APB_CHx_CMD__COMMAND__READ)
|
||||||
commit_discard_dcache_range(cur->buffer, sz);
|
commit_discard_dcache_range(cur->buffer, sz);
|
||||||
|
/* Virtual to physical buffer pointer conversion */
|
||||||
|
cur->buffer = PHYSICAL_ADDR(cur->buffer);
|
||||||
/* chain ? */
|
/* chain ? */
|
||||||
if(cur->cmd & HW_APB_CHx_CMD__CHAIN)
|
if(cur->cmd & HW_APB_CHx_CMD__CHAIN)
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
|
@ -139,16 +142,22 @@ static void imx233_dma_commit_and_discard(struct apb_dma_command_t *cmd)
|
||||||
while((cur->cmd & HW_APB_CHx_CMD__UNUSED_BM) != 0)
|
while((cur->cmd & HW_APB_CHx_CMD__UNUSED_BM) != 0)
|
||||||
{
|
{
|
||||||
cur->cmd = cur->cmd & ~HW_APB_CHx_CMD__UNUSED_BM;
|
cur->cmd = cur->cmd & ~HW_APB_CHx_CMD__UNUSED_BM;
|
||||||
int sz = (cur->cmd & HW_APB_CHx_CMD__CMDWORDS_BM) >> HW_APB_CHx_CMD__CMDWORDS_BP;
|
int sz = __XTRACT_EX(cur->cmd, HW_APB_CHx_CMD__CMDWORDS) * sizeof(uint32_t);
|
||||||
/* commit descriptor (don't discard since we access it after) */
|
/* commit descriptor and discard descriptor */
|
||||||
commit_dcache_range(cur,
|
|
||||||
sizeof(struct apb_dma_command_t) + sizeof(uint32_t) * sz);
|
|
||||||
/* chain ? */
|
/* chain ? */
|
||||||
if(cur->cmd & HW_APB_CHx_CMD__CHAIN)
|
if(cur->cmd & HW_APB_CHx_CMD__CHAIN)
|
||||||
cur = cur->next;
|
{
|
||||||
|
struct apb_dma_command_t *next = cur->next;
|
||||||
|
cur->next = PHYSICAL_ADDR(cur->next);
|
||||||
|
commit_dcache_range(cur, sizeof(struct apb_dma_command_t) + sz);
|
||||||
|
cur = next;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
commit_dcache_range(cur, sizeof(struct apb_dma_command_t) + sz);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void imx233_dma_start_command(unsigned chan, struct apb_dma_command_t *cmd)
|
void imx233_dma_start_command(unsigned chan, struct apb_dma_command_t *cmd)
|
||||||
|
@ -156,12 +165,12 @@ void imx233_dma_start_command(unsigned chan, struct apb_dma_command_t *cmd)
|
||||||
imx233_dma_commit_and_discard(cmd);
|
imx233_dma_commit_and_discard(cmd);
|
||||||
if(APB_IS_APBX_CHANNEL(chan))
|
if(APB_IS_APBX_CHANNEL(chan))
|
||||||
{
|
{
|
||||||
HW_APBX_CHx_NXTCMDAR(APB_GET_DMA_CHANNEL(chan)) = (uint32_t)cmd;
|
HW_APBX_CHx_NXTCMDAR(APB_GET_DMA_CHANNEL(chan)) = (uint32_t)PHYSICAL_ADDR(cmd);
|
||||||
HW_APBX_CHx_SEMA(APB_GET_DMA_CHANNEL(chan)) = 1;
|
HW_APBX_CHx_SEMA(APB_GET_DMA_CHANNEL(chan)) = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HW_APBH_CHx_NXTCMDAR(APB_GET_DMA_CHANNEL(chan)) = (uint32_t)cmd;
|
HW_APBH_CHx_NXTCMDAR(APB_GET_DMA_CHANNEL(chan)) = (uint32_t)PHYSICAL_ADDR(cmd);
|
||||||
HW_APBH_CHx_SEMA(APB_GET_DMA_CHANNEL(chan)) = 1;
|
HW_APBH_CHx_SEMA(APB_GET_DMA_CHANNEL(chan)) = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,7 +79,7 @@ void imx233_lcdif_set_word_length(unsigned word_length)
|
||||||
|
|
||||||
unsigned imx233_lcdif_enable_irqs(unsigned irq_bm)
|
unsigned imx233_lcdif_enable_irqs(unsigned irq_bm)
|
||||||
{
|
{
|
||||||
unsigned old_msk = (HW_LCDIF_CTRL1 & HW_LCDIF_CTRL1__IRQ_EN_BM) >>HW_LCDIF_CTRL1__IRQ_EN_BP ;
|
unsigned old_msk = __XTRACT(HW_LCDIF_CTRL1, IRQ_EN);
|
||||||
/* clear irq status */
|
/* clear irq status */
|
||||||
__REG_CLR(HW_LCDIF_CTRL1) = irq_bm << HW_LCDIF_CTRL1__IRQ_BP;
|
__REG_CLR(HW_LCDIF_CTRL1) = irq_bm << HW_LCDIF_CTRL1__IRQ_BP;
|
||||||
/* disable irqs */
|
/* disable irqs */
|
||||||
|
|
|
@ -41,9 +41,15 @@
|
||||||
/** When set, this values restrict the windows of the read and writes */
|
/** When set, this values restrict the windows of the read and writes */
|
||||||
static unsigned mmc_window_start = 0;
|
static unsigned mmc_window_start = 0;
|
||||||
static unsigned mmc_window_end = INT_MAX;
|
static unsigned mmc_window_end = INT_MAX;
|
||||||
|
static bool mmc_window_enable = true;
|
||||||
|
|
||||||
static struct mutex mmc_mutex;
|
static struct mutex mmc_mutex;
|
||||||
|
|
||||||
|
void imx233_mmc_disable_window(void)
|
||||||
|
{
|
||||||
|
mmc_window_enable = false;
|
||||||
|
}
|
||||||
|
|
||||||
int mmc_init(void)
|
int mmc_init(void)
|
||||||
{
|
{
|
||||||
mutex_init(&mmc_mutex);
|
mutex_init(&mmc_mutex);
|
||||||
|
@ -123,6 +129,8 @@ int mmc_init(void)
|
||||||
imx233_ssp_set_timings(MMC_SSP, 2, 0, 0xffff);
|
imx233_ssp_set_timings(MMC_SSP, 2, 0, 0xffff);
|
||||||
|
|
||||||
#ifdef SANSA_FUZEPLUS
|
#ifdef SANSA_FUZEPLUS
|
||||||
|
if(mmc_window_enable)
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* The Fuze+ uses a strange layout: is has a first MBR at sector 0 with four entries:
|
* The Fuze+ uses a strange layout: is has a first MBR at sector 0 with four entries:
|
||||||
* 1) Actual user partition
|
* 1) Actual user partition
|
||||||
|
@ -151,6 +159,7 @@ int mmc_init(void)
|
||||||
return -102; /* sigmatel partition */
|
return -102; /* sigmatel partition */
|
||||||
if((mmc_window_end - mmc_window_start) < 4 * 1024 * 1024)
|
if((mmc_window_end - mmc_window_start) < 4 * 1024 * 1024)
|
||||||
return -103; /* partition too small */
|
return -103; /* partition too small */
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -221,3 +230,9 @@ bool mmc_present(IF_MD(int drive))
|
||||||
IF_MD((void) drive);
|
IF_MD((void) drive);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool mmc_removable(IF_MD(int drive))
|
||||||
|
{
|
||||||
|
IF_MD((void) drive);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -23,9 +23,33 @@
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
#include "power.h"
|
#include "power.h"
|
||||||
#include "system-target.h"
|
#include "system-target.h"
|
||||||
|
#include "usb-target.h"
|
||||||
|
|
||||||
|
void INT_VDD5V(void)
|
||||||
|
{
|
||||||
|
if(HW_POWER_CTRL & HW_POWER_CTRL__VBUSVALID_IRQ)
|
||||||
|
{
|
||||||
|
if(HW_POWER_STS & HW_POWER_STS__VBUSVALID)
|
||||||
|
usb_insert_int();
|
||||||
|
else
|
||||||
|
usb_remove_int();
|
||||||
|
/* reverse polarity */
|
||||||
|
__REG_TOG(HW_POWER_CTRL) = HW_POWER_CTRL__POLARITY_VBUSVALID;
|
||||||
|
/* enable int */
|
||||||
|
__REG_CLR(HW_POWER_CTRL) = HW_POWER_CTRL__VBUSVALID_IRQ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void power_init(void)
|
void power_init(void)
|
||||||
{
|
{
|
||||||
|
/* clear vbusvalid irq and set correct polarity */
|
||||||
|
__REG_CLR(HW_POWER_CTRL) = HW_POWER_CTRL__VBUSVALID_IRQ;
|
||||||
|
if(HW_POWER_STS & HW_POWER_STS__VBUSVALID)
|
||||||
|
__REG_CLR(HW_POWER_CTRL) = HW_POWER_CTRL__POLARITY_VBUSVALID;
|
||||||
|
else
|
||||||
|
__REG_SET(HW_POWER_CTRL) = HW_POWER_CTRL__POLARITY_VBUSVALID;
|
||||||
|
__REG_SET(HW_POWER_CTRL) = HW_POWER_CTRL__ENIRQ_VBUS_VALID;
|
||||||
|
imx233_enable_interrupt(INT_SRC_VDD5V, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void power_off(void)
|
void power_off(void)
|
||||||
|
|
69
firmware/target/arm/imx233/power-imx233.h
Normal file
69
firmware/target/arm/imx233/power-imx233.h
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* __________ __ ___.
|
||||||
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||||
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||||
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||||
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||||
|
* \/ \/ \/ \/ \/
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011 by Amaury Pouly
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef __POWER_IMX233__
|
||||||
|
#define __POWER_IMX233__
|
||||||
|
|
||||||
|
#include "system.h"
|
||||||
|
#include "system-target.h"
|
||||||
|
#include "cpu.h"
|
||||||
|
|
||||||
|
#define HW_POWER_BASE 0x80044000
|
||||||
|
|
||||||
|
#define HW_POWER_CTRL (*(volatile uint32_t *)(HW_POWER_BASE + 0x0))
|
||||||
|
#define HW_POWER_CTRL__ENIRQ_VBUS_VALID (1 << 3)
|
||||||
|
#define HW_POWER_CTRL__VBUSVALID_IRQ (1 << 4)
|
||||||
|
#define HW_POWER_CTRL__POLARITY_VBUSVALID (1 << 5)
|
||||||
|
|
||||||
|
#define HW_POWER_5VCTRL (*(volatile uint32_t *)(HW_POWER_BASE + 0x10))
|
||||||
|
#define HW_POWER_5VCTRL__VBUSVALID_5VDETECT (1 << 4)
|
||||||
|
#define HW_POWER_5VCTRL__VBUSVALID_TRSH_BP 8
|
||||||
|
#define HW_POWER_5VCTRL__VBUSVALID_TRSH_BM (0x7 << 8)
|
||||||
|
|
||||||
|
#define HW_POWER_MINPWR (*(volatile uint32_t *)(HW_POWER_BASE + 0x20))
|
||||||
|
|
||||||
|
#define HW_POWER_CHARGE (*(volatile uint32_t *)(HW_POWER_BASE + 0x30))
|
||||||
|
|
||||||
|
#define HW_POWER_VDDDCTRL (*(volatile uint32_t *)(HW_POWER_BASE + 0x40))
|
||||||
|
#define HW_POWER_VDDDCTRL__TRG_BP 0
|
||||||
|
#define HW_POWER_VDDDCTRL__TRG_BM 0x1f
|
||||||
|
#define HW_POWER_VDDDCTRL__TRG_STEP 25 /* mV */
|
||||||
|
#define HW_POWER_VDDDCTRL__TRG_MIN 800 /* mV */
|
||||||
|
|
||||||
|
#define HW_POWER_VDDACTRL (*(volatile uint32_t *)(HW_POWER_BASE + 0x50))
|
||||||
|
|
||||||
|
#define HW_POWER_VDDIOCTRL (*(volatile uint32_t *)(HW_POWER_BASE + 0x60))
|
||||||
|
|
||||||
|
#define HW_POWER_VDDMEMCTRL (*(volatile uint32_t *)(HW_POWER_BASE + 0x70))
|
||||||
|
|
||||||
|
#define HW_POWER_MISC (*(volatile uint32_t *)(HW_POWER_BASE + 0x90))
|
||||||
|
|
||||||
|
#define HW_POWER_STS (*(volatile uint32_t *)(HW_POWER_BASE + 0xc0))
|
||||||
|
#define HW_POWER_STS__VBUSVALID (1 << 1)
|
||||||
|
#define HW_POWER_STS__PSWITCH_BP 20
|
||||||
|
#define HW_POWER_STS__PSWITCH_BM (3 << 20)
|
||||||
|
|
||||||
|
#define HW_POWER_BATTMONITOR (*(volatile uint32_t *)(HW_POWER_BASE + 0xe0))
|
||||||
|
|
||||||
|
#define HW_POWER_RESET (*(volatile uint32_t *)(HW_POWER_BASE + 0x100))
|
||||||
|
#define HW_POWER_RESET__UNLOCK 0x3E770000
|
||||||
|
#define HW_POWER_RESET__PWD 0x1
|
||||||
|
|
||||||
|
#endif /* __POWER_IMX233__ */
|
|
@ -509,7 +509,7 @@ void lcd_update(void)
|
||||||
imx233_lcdif_set_data_format(false, false, false); /* RGB565, don't care, don't care */
|
imx233_lcdif_set_data_format(false, false, false); /* RGB565, don't care, don't care */
|
||||||
lcd_copy_buffer_rect((fb_data *)FRAME, &lcd_framebuffer[0][0],
|
lcd_copy_buffer_rect((fb_data *)FRAME, &lcd_framebuffer[0][0],
|
||||||
LCD_WIDTH * LCD_HEIGHT, 1);
|
LCD_WIDTH * LCD_HEIGHT, 1);
|
||||||
imx233_lcdif_dma_send(FRAME, LCD_WIDTH, LCD_HEIGHT);
|
imx233_lcdif_dma_send((void *)FRAME_PHYS_ADDR, LCD_WIDTH, LCD_HEIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_update_rect(int x, int y, int width, int height)
|
void lcd_update_rect(int x, int y, int width, int height)
|
||||||
|
|
|
@ -227,3 +227,9 @@ bool sd_present(IF_MD(int drive))
|
||||||
return imx233_ssp_sdmmc_detect(SD_SSP);
|
return imx233_ssp_sdmmc_detect(SD_SSP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool sd_removable(IF_MD(int drive))
|
||||||
|
{
|
||||||
|
IF_MD((void) drive);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,7 @@ default_interrupt(INT_I2C_ERROR);
|
||||||
default_interrupt(INT_GPIO0);
|
default_interrupt(INT_GPIO0);
|
||||||
default_interrupt(INT_GPIO1);
|
default_interrupt(INT_GPIO1);
|
||||||
default_interrupt(INT_GPIO2);
|
default_interrupt(INT_GPIO2);
|
||||||
|
default_interrupt(INT_VDD5V);
|
||||||
|
|
||||||
typedef void (*isr_t)(void);
|
typedef void (*isr_t)(void);
|
||||||
|
|
||||||
|
@ -78,6 +79,7 @@ static isr_t isr_table[INT_SRC_NR_SOURCES] =
|
||||||
[INT_SRC_GPIO0] = INT_GPIO0,
|
[INT_SRC_GPIO0] = INT_GPIO0,
|
||||||
[INT_SRC_GPIO1] = INT_GPIO1,
|
[INT_SRC_GPIO1] = INT_GPIO1,
|
||||||
[INT_SRC_GPIO2] = INT_GPIO2,
|
[INT_SRC_GPIO2] = INT_GPIO2,
|
||||||
|
[INT_SRC_VDD5V] = INT_VDD5V,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void UIRQ(void)
|
static void UIRQ(void)
|
||||||
|
@ -147,10 +149,8 @@ static void set_page_tables(void)
|
||||||
map_section(0, 0, 0x1000, CACHE_NONE);
|
map_section(0, 0, 0x1000, CACHE_NONE);
|
||||||
|
|
||||||
/* map RAM and enable caching for it */
|
/* map RAM and enable caching for it */
|
||||||
map_section(DRAM_ORIG, DRAM_ORIG, MEMORYSIZE, CACHE_ALL);
|
map_section(DRAM_ORIG, CACHED_DRAM_ADDR, MEMORYSIZE, CACHE_ALL);
|
||||||
|
map_section(DRAM_ORIG, BUFFERED_DRAM_ADDR, MEMORYSIZE, BUFFERED);
|
||||||
/* enable buffered writing for the framebuffer */
|
|
||||||
map_section((int)FRAME, (int)FRAME, 1, BUFFERED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void memory_init(void)
|
void memory_init(void)
|
||||||
|
|
|
@ -26,44 +26,11 @@
|
||||||
#include "panic.h"
|
#include "panic.h"
|
||||||
|
|
||||||
#include "clock-target.h" /* CPUFREQ_* are defined here */
|
#include "clock-target.h" /* CPUFREQ_* are defined here */
|
||||||
|
#include "power-imx233.h"
|
||||||
|
|
||||||
#define HW_DIGCTL_BASE 0x8001C000
|
#define HW_DIGCTL_BASE 0x8001C000
|
||||||
#define HW_DIGCTL_MICROSECONDS (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0xC0))
|
#define HW_DIGCTL_MICROSECONDS (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0xC0))
|
||||||
|
|
||||||
#define HW_POWER_BASE 0x80044000
|
|
||||||
|
|
||||||
#define HW_POWER_CTRL (*(volatile uint32_t *)(HW_POWER_BASE + 0x0))
|
|
||||||
|
|
||||||
#define HW_POWER_5VCTRL (*(volatile uint32_t *)(HW_POWER_BASE + 0x10))
|
|
||||||
|
|
||||||
#define HW_POWER_MINPWR (*(volatile uint32_t *)(HW_POWER_BASE + 0x20))
|
|
||||||
|
|
||||||
#define HW_POWER_CHARGE (*(volatile uint32_t *)(HW_POWER_BASE + 0x30))
|
|
||||||
|
|
||||||
#define HW_POWER_VDDDCTRL (*(volatile uint32_t *)(HW_POWER_BASE + 0x40))
|
|
||||||
#define HW_POWER_VDDDCTRL__TRG_BP 0
|
|
||||||
#define HW_POWER_VDDDCTRL__TRG_BM 0x1f
|
|
||||||
#define HW_POWER_VDDDCTRL__TRG_STEP 25 /* mV */
|
|
||||||
#define HW_POWER_VDDDCTRL__TRG_MIN 800 /* mV */
|
|
||||||
|
|
||||||
#define HW_POWER_VDDACTRL (*(volatile uint32_t *)(HW_POWER_BASE + 0x50))
|
|
||||||
|
|
||||||
#define HW_POWER_VDDIOCTRL (*(volatile uint32_t *)(HW_POWER_BASE + 0x60))
|
|
||||||
|
|
||||||
#define HW_POWER_VDDMEMCTRL (*(volatile uint32_t *)(HW_POWER_BASE + 0x70))
|
|
||||||
|
|
||||||
#define HW_POWER_MISC (*(volatile uint32_t *)(HW_POWER_BASE + 0x90))
|
|
||||||
|
|
||||||
#define HW_POWER_STS (*(volatile uint32_t *)(HW_POWER_BASE + 0xc0))
|
|
||||||
#define HW_POWER_STS__PSWITCH_BP 20
|
|
||||||
#define HW_POWER_STS__PSWITCH_BM (3 << 20)
|
|
||||||
|
|
||||||
#define HW_POWER_BATTMONITOR (*(volatile uint32_t *)(HW_POWER_BASE + 0xe0))
|
|
||||||
|
|
||||||
#define HW_POWER_RESET (*(volatile uint32_t *)(HW_POWER_BASE + 0x100))
|
|
||||||
#define HW_POWER_RESET__UNLOCK 0x3E770000
|
|
||||||
#define HW_POWER_RESET__PWD 0x1
|
|
||||||
|
|
||||||
#define HW_ICOLL_BASE 0x80000000
|
#define HW_ICOLL_BASE 0x80000000
|
||||||
|
|
||||||
#define HW_ICOLL_VECTOR (*(volatile uint32_t *)(HW_ICOLL_BASE + 0x0))
|
#define HW_ICOLL_VECTOR (*(volatile uint32_t *)(HW_ICOLL_BASE + 0x0))
|
||||||
|
@ -83,6 +50,7 @@
|
||||||
#define HW_ICOLL_INTERRUPT__ENFIQ 0x10
|
#define HW_ICOLL_INTERRUPT__ENFIQ 0x10
|
||||||
|
|
||||||
#define INT_SRC_SSP2_ERROR 2
|
#define INT_SRC_SSP2_ERROR 2
|
||||||
|
#define INT_SRC_VDD5V 3
|
||||||
#define INT_SRC_USB_CTRL 11
|
#define INT_SRC_USB_CTRL 11
|
||||||
#define INT_SRC_SSP1_DMA 14
|
#define INT_SRC_SSP1_DMA 14
|
||||||
#define INT_SRC_SSP1_ERROR 15
|
#define INT_SRC_SSP1_ERROR 15
|
||||||
|
|
|
@ -29,10 +29,20 @@
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
#include "system-target.h"
|
#include "system-target.h"
|
||||||
|
|
||||||
int usb_status = USB_EXTRACTED;
|
|
||||||
|
void usb_insert_int(void)
|
||||||
|
{
|
||||||
|
usb_status_event(USB_POWERED);
|
||||||
|
}
|
||||||
|
|
||||||
|
void usb_remove_int(void)
|
||||||
|
{
|
||||||
|
usb_status_event(USB_UNPOWERED);
|
||||||
|
}
|
||||||
|
|
||||||
void usb_drv_usb_detect_event()
|
void usb_drv_usb_detect_event()
|
||||||
{
|
{
|
||||||
|
printf("usb_drv_usb_detect_event");
|
||||||
usb_status_event(USB_INSERTED);
|
usb_status_event(USB_INSERTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,16 +68,17 @@ void usb_init_device(void)
|
||||||
|
|
||||||
int usb_detect(void)
|
int usb_detect(void)
|
||||||
{
|
{
|
||||||
return usb_status;
|
return usb_plugged() ? USB_INSERTED : USB_EXTRACTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool usb_plugged(void)
|
bool usb_plugged(void)
|
||||||
{
|
{
|
||||||
return true;
|
return !!(HW_POWER_STS & HW_POWER_STS__VBUSVALID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void usb_enable(bool on)
|
void usb_enable(bool on)
|
||||||
{
|
{
|
||||||
|
/* FIXME: power up/down usb phy and pll usb */
|
||||||
if(on)
|
if(on)
|
||||||
usb_core_init();
|
usb_core_init();
|
||||||
else
|
else
|
||||||
|
|
36
firmware/target/arm/imx233/usb-target.h
Normal file
36
firmware/target/arm/imx233/usb-target.h
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* __________ __ ___.
|
||||||
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||||
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||||
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||||
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||||
|
* \/ \/ \/ \/ \/
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011 by Amaury Pouly
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef USB_TARGET_H
|
||||||
|
#define USB_TARGET_H
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_BOOTLOADER_USB_MODE
|
||||||
|
#define USB_DRIVER_CLOSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void usb_init_device(void);
|
||||||
|
int usb_detect(void);
|
||||||
|
void usb_insert_int(void);
|
||||||
|
void usb_remove_int(void);
|
||||||
|
bool usb_plugged(void);
|
||||||
|
|
||||||
|
#endif /* USB_TARGET_H */
|
Loading…
Add table
Add a link
Reference in a new issue