From 7d4fed53cc1e8b0e5aa250ebea3a1b53fc3a50b2 Mon Sep 17 00:00:00 2001 From: Amaury Pouly Date: Mon, 5 Sep 2011 11:29:32 +0000 Subject: [PATCH] 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 --- bootloader/imx233.c | 96 +++++++++++++++---- firmware/export/config.h | 2 +- firmware/export/config/sansafuzeplus.h | 2 +- firmware/export/imx233.h | 30 +++++- firmware/target/arm/imx233/boot.lds | 16 +++- firmware/target/arm/imx233/crt0.S | 13 ++- firmware/target/arm/imx233/dma-imx233.c | 27 ++++-- firmware/target/arm/imx233/lcdif-imx233.c | 2 +- firmware/target/arm/imx233/mmc-imx233.c | 71 ++++++++------ firmware/target/arm/imx233/power-imx233.c | 24 +++++ firmware/target/arm/imx233/power-imx233.h | 69 +++++++++++++ .../arm/imx233/sansa-fuzeplus/lcd-fuzeplus.c | 2 +- firmware/target/arm/imx233/sd-imx233.c | 6 ++ firmware/target/arm/imx233/system-imx233.c | 8 +- firmware/target/arm/imx233/system-target.h | 36 +------ firmware/target/arm/imx233/usb-imx233.c | 17 +++- firmware/target/arm/imx233/usb-target.h | 36 +++++++ 17 files changed, 353 insertions(+), 104 deletions(-) create mode 100644 firmware/target/arm/imx233/power-imx233.h create mode 100644 firmware/target/arm/imx233/usb-target.h 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 @@ #include "fmradio_i2c.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) @@ -51,6 +114,7 @@ void main(uint32_t arg) system_init(); kernel_init(); + power_init(); enable_irq(); lcd_init(); @@ -59,32 +123,32 @@ void main(uint32_t arg) backlight_init(); - button_init_device(); + button_init(); //button_debug_screen(); - printf("arg=%c%c%c%c", arg >> 24, - (arg >> 16) & 0xff, (arg >> 8) & 0xff, (arg & 0xff)); + printf("arg=%x", arg); + +#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(); if(ret < 0) error(EATA, ret, true); - #ifdef HAVE_BOOTLOADER_USB_MODE - usb_init(); - usb_core_enable_driver(USB_DRIVER_SERIAL, true); - usb_attach(); - while(!(button_read_device() & BUTTON_POWER)) - yield(); - power_off(); - #endif /* HAVE_BOOTLOADER_USB_MODE */ + if(usb_plugged()) + usb_mode(HZ * 2); while(!disk_init(IF_MV(0))) - panicf("disk_init failed!"); + printf("disk_init failed!"); - while((ret = disk_mount_all()) <= 0) - { - error(EDISK, ret, true); - } + if((ret = disk_mount_all()) <= 0) + error(EDISK, ret, false); if(button_read_device() & BUTTON_VOL_UP) 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 */ #endif /* CPU_PP */ -#if CONFIG_CPU == IMX31L +#if CONFIG_CPU == IMX31L || CONFIG_CPU == IMX233 #define NOCACHEBSS_ATTR __attribute__((section(".ncbss"),nocommon)) #define NOCACHEDATA_ATTR __attribute__((section(".ncdata"),nocommon)) #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 @@ #define USB_VENDOR_ID 0x0781 #define USB_PRODUCT_ID 0x74e1 #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 * (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 @@ #ifndef __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_SIZE 0x8000 #define DRAM_ORIG 0x40000000 #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_SIZE 0x4000 #define TTB_BASE ((unsigned long *)TTB_BASE_ADDR) #define FRAME_SIZE (LCD_WIDTH * LCD_HEIGHT * LCD_DEPTH / 8) -#define LCD_FRAME_ADDR (DRAM_ORIG + DRAM_SIZE - TTB_SIZE - FRAME_SIZE) -#define FRAME ((unsigned short *)LCD_FRAME_ADDR) +#define FRAME_PHYS_ADDR (DRAM_ORIG + DRAM_SIZE - TTB_SIZE - FRAME_SIZE) +#define FRAME ((void *)(FRAME_PHYS_ADDR - UNCACHED_DRAM_ADDR + BUFFERED_DRAM_ADDR)) /* USBOTG */ #define USB_QHARRAY_ATTR __attribute__((section(".qharray"),nocommon,aligned(2048))) @@ -52,5 +76,7 @@ #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__ */ 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) MEMORY { 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 @@ -57,10 +58,23 @@ SECTIONS stackend = .; } > DRAM + /* treat .bss and .ncbss as a single section */ .bss (NOLOAD) : { _edata = .; *(.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 = .; } > DRAM } 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 @@ ldr pc, =irq_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 .global start start: @@ -46,6 +49,13 @@ start: bic r0, r1 mcr p15, 0, r0, c1, c0, 0 + /* Enable MMU */ + bl memory_init + + /* Jump to real location */ + ldr pc, =remap +remap: + /* Zero out IBSS */ ldr r2, =_iedata ldr r3, =_iend @@ -114,9 +124,6 @@ start: msr cpsr_c, #0xdb ldr sp, =irq_stack - /* Enable MMU */ - bl memory_init - /* Switch back to supervisor mode */ msr cpsr_c, #0xd3 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) } /* 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) { /* 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; 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 */ if(op == HW_APB_CHx_CMD__COMMAND__WRITE) discard_dcache_range(cur->buffer, sz); /* host > device: commit and discard */ else if(op == HW_APB_CHx_CMD__COMMAND__READ) commit_discard_dcache_range(cur->buffer, sz); + /* Virtual to physical buffer pointer conversion */ + cur->buffer = PHYSICAL_ADDR(cur->buffer); /* chain ? */ if(cur->cmd & HW_APB_CHx_CMD__CHAIN) cur = cur->next; @@ -139,15 +142,21 @@ static void imx233_dma_commit_and_discard(struct apb_dma_command_t *cmd) while((cur->cmd & HW_APB_CHx_CMD__UNUSED_BM) != 0) { 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; - /* commit descriptor (don't discard since we access it after) */ - commit_dcache_range(cur, - sizeof(struct apb_dma_command_t) + sizeof(uint32_t) * sz); + int sz = __XTRACT_EX(cur->cmd, HW_APB_CHx_CMD__CMDWORDS) * sizeof(uint32_t); + /* commit descriptor and discard descriptor */ /* 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 + { + commit_dcache_range(cur, sizeof(struct apb_dma_command_t) + sz); break; + } } } @@ -156,12 +165,12 @@ void imx233_dma_start_command(unsigned chan, struct apb_dma_command_t *cmd) imx233_dma_commit_and_discard(cmd); 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; } 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; } } 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) 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 */ __REG_CLR(HW_LCDIF_CTRL1) = irq_bm << HW_LCDIF_CTRL1__IRQ_BP; /* 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 @@ /** When set, this values restrict the windows of the read and writes */ static unsigned mmc_window_start = 0; static unsigned mmc_window_end = INT_MAX; +static bool mmc_window_enable = true; static struct mutex mmc_mutex; +void imx233_mmc_disable_window(void) +{ + mmc_window_enable = false; +} + int mmc_init(void) { mutex_init(&mmc_mutex); @@ -123,34 +129,37 @@ int mmc_init(void) imx233_ssp_set_timings(MMC_SSP, 2, 0, 0xffff); #ifdef SANSA_FUZEPLUS - /** - * The Fuze+ uses a strange layout: is has a first MBR at sector 0 with four entries: - * 1) Actual user partition - * 2) Sigmatel boot partition - * 3)4) Other (certificate related ?) partitions - * The partition 1) has type 1 but it's actually a type 5 (logical partition) with - * a second partition table with usually one entry which is the FAT32 one. - * The first table uses 512-byte sector size and the second one usually uses - * 2048-byte logical sector size. - * - * We restrict mmc window to the user partition */ - uint8_t mbr[512]; - mmc_window_start = 0; - mmc_window_end = INT_MAX; - ret = mmc_read_sectors(IF_MD2(0,) 0, 1, mbr); - if(ret != 0) - return -100; - if(mbr[510] != 0x55 || mbr[511] != 0xAA) - return -101; /* invalid MBR */ - /* sanity check that the first partition is greater than 2Gib */ - uint8_t *ent = &mbr[446]; - mmc_window_start = ent[8] | ent[9] << 8 | ent[10] << 16 | ent[11] << 24; - mmc_window_end = (ent[12] | ent[13] << 8 | ent[14] << 16 | ent[15] << 24) + - mmc_window_start; - if(ent[4] == 0x53) - return -102; /* sigmatel partition */ - if((mmc_window_end - mmc_window_start) < 4 * 1024 * 1024) - return -103; /* partition too small */ + if(mmc_window_enable) + { + /** + * The Fuze+ uses a strange layout: is has a first MBR at sector 0 with four entries: + * 1) Actual user partition + * 2) Sigmatel boot partition + * 3)4) Other (certificate related ?) partitions + * The partition 1) has type 1 but it's actually a type 5 (logical partition) with + * a second partition table with usually one entry which is the FAT32 one. + * The first table uses 512-byte sector size and the second one usually uses + * 2048-byte logical sector size. + * + * We restrict mmc window to the user partition */ + uint8_t mbr[512]; + mmc_window_start = 0; + mmc_window_end = INT_MAX; + ret = mmc_read_sectors(IF_MD2(0,) 0, 1, mbr); + if(ret != 0) + return -100; + if(mbr[510] != 0x55 || mbr[511] != 0xAA) + return -101; /* invalid MBR */ + /* sanity check that the first partition is greater than 2Gib */ + uint8_t *ent = &mbr[446]; + mmc_window_start = ent[8] | ent[9] << 8 | ent[10] << 16 | ent[11] << 24; + mmc_window_end = (ent[12] | ent[13] << 8 | ent[14] << 16 | ent[15] << 24) + + mmc_window_start; + if(ent[4] == 0x53) + return -102; /* sigmatel partition */ + if((mmc_window_end - mmc_window_start) < 4 * 1024 * 1024) + return -103; /* partition too small */ + } #endif return 0; @@ -221,3 +230,9 @@ bool mmc_present(IF_MD(int drive)) IF_MD((void) drive); return true; } + +bool mmc_removable(IF_MD(int drive)) +{ + IF_MD((void) drive); + return false; +} 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 @@ #include "system.h" #include "power.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) { + /* 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) 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 @@ +/*************************************************************************** + * __________ __ ___. + * 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__ */ 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) 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_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) 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)) return imx233_ssp_sdmmc_detect(SD_SSP); } +bool sd_removable(IF_MD(int drive)) +{ + IF_MD((void) drive); + return true; +} + 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); default_interrupt(INT_GPIO0); default_interrupt(INT_GPIO1); default_interrupt(INT_GPIO2); +default_interrupt(INT_VDD5V); 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_GPIO1] = INT_GPIO1, [INT_SRC_GPIO2] = INT_GPIO2, + [INT_SRC_VDD5V] = INT_VDD5V, }; static void UIRQ(void) @@ -147,10 +149,8 @@ static void set_page_tables(void) map_section(0, 0, 0x1000, CACHE_NONE); /* map RAM and enable caching for it */ - map_section(DRAM_ORIG, DRAM_ORIG, MEMORYSIZE, CACHE_ALL); - - /* enable buffered writing for the framebuffer */ - map_section((int)FRAME, (int)FRAME, 1, BUFFERED); + map_section(DRAM_ORIG, CACHED_DRAM_ADDR, MEMORYSIZE, CACHE_ALL); + map_section(DRAM_ORIG, BUFFERED_DRAM_ADDR, MEMORYSIZE, BUFFERED); } void 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 @@ #include "panic.h" #include "clock-target.h" /* CPUFREQ_* are defined here */ +#include "power-imx233.h" #define HW_DIGCTL_BASE 0x8001C000 #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_VECTOR (*(volatile uint32_t *)(HW_ICOLL_BASE + 0x0)) @@ -83,6 +50,7 @@ #define HW_ICOLL_INTERRUPT__ENFIQ 0x10 #define INT_SRC_SSP2_ERROR 2 +#define INT_SRC_VDD5V 3 #define INT_SRC_USB_CTRL 11 #define INT_SRC_SSP1_DMA 14 #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 @@ #include "system.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() { + printf("usb_drv_usb_detect_event"); usb_status_event(USB_INSERTED); } @@ -58,16 +68,17 @@ void usb_init_device(void) int usb_detect(void) { - return usb_status; + return usb_plugged() ? USB_INSERTED : USB_EXTRACTED; } bool usb_plugged(void) { - return true; + return !!(HW_POWER_STS & HW_POWER_STS__VBUSVALID); } void usb_enable(bool on) { + /* FIXME: power up/down usb phy and pll usb */ if(on) usb_core_init(); 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 @@ +/*************************************************************************** + * __________ __ ___. + * 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 */