forked from len0rd/rockbox
M:Robe 500/M66591 USB improvements: Interrupts now work, a bug in odd-length transfers has been fixed. Buffers that are not initially short aligned are also now supported. Enable USB HID mouse mode.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23483 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
451f9d58f3
commit
02385cb5b0
6 changed files with 193 additions and 80 deletions
|
@ -310,6 +310,27 @@ static const struct button_mapping button_context_usb_hid_mode_browser[] = {
|
|||
|
||||
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_USB_HID)
|
||||
}; /* button_context_usb_hid_mode_browser */
|
||||
|
||||
#ifdef HAVE_USB_HID_MOUSE
|
||||
static const struct button_mapping button_context_usb_hid_mode_mouse[] = {
|
||||
{ ACTION_USB_HID_MOUSE_UP, BUTTON_TOPMIDDLE, BUTTON_NONE },
|
||||
{ ACTION_USB_HID_MOUSE_UP_REP, BUTTON_TOPMIDDLE|BUTTON_REPEAT, BUTTON_NONE },
|
||||
{ ACTION_USB_HID_MOUSE_DOWN, BUTTON_BOTTOMMIDDLE, BUTTON_NONE },
|
||||
{ ACTION_USB_HID_MOUSE_DOWN_REP, BUTTON_BOTTOMMIDDLE|BUTTON_REPEAT,BUTTON_NONE },
|
||||
{ ACTION_USB_HID_MOUSE_LEFT, BUTTON_MIDLEFT, BUTTON_NONE },
|
||||
{ ACTION_USB_HID_MOUSE_LEFT_REP, BUTTON_MIDLEFT|BUTTON_REPEAT, BUTTON_NONE },
|
||||
{ ACTION_USB_HID_MOUSE_RIGHT, BUTTON_MIDRIGHT, BUTTON_NONE },
|
||||
{ ACTION_USB_HID_MOUSE_RIGHT_REP, BUTTON_MIDRIGHT|BUTTON_REPEAT, BUTTON_NONE },
|
||||
{ ACTION_USB_HID_MOUSE_BUTTON_LEFT, BUTTON_CENTER, BUTTON_NONE },
|
||||
{ ACTION_USB_HID_MOUSE_BUTTON_LEFT_REL, BUTTON_CENTER|BUTTON_REL, BUTTON_NONE },
|
||||
{ ACTION_USB_HID_MOUSE_WHEEL_SCROLL_UP, BUTTON_TOPRIGHT, BUTTON_NONE },
|
||||
{ ACTION_USB_HID_MOUSE_WHEEL_SCROLL_UP, BUTTON_TOPRIGHT|BUTTON_REPEAT, BUTTON_NONE },
|
||||
{ ACTION_USB_HID_MOUSE_WHEEL_SCROLL_DOWN, BUTTON_BOTTOMRIGHT, BUTTON_NONE },
|
||||
{ ACTION_USB_HID_MOUSE_WHEEL_SCROLL_DOWN, BUTTON_BOTTOMRIGHT|BUTTON_REPEAT, BUTTON_NONE },
|
||||
|
||||
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_USB_HID)
|
||||
}; /* button_context_usb_hid_mode_mouse */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
const struct button_mapping* get_context_mapping(int context)
|
||||
|
@ -373,8 +394,13 @@ const struct button_mapping* get_context_mapping(int context)
|
|||
return button_context_usb_hid_mode_presentation;
|
||||
case CONTEXT_USB_HID_MODE_BROWSER:
|
||||
return button_context_usb_hid_mode_browser;
|
||||
#ifdef HAVE_USB_HID_MOUSE
|
||||
case CONTEXT_USB_HID_MODE_MOUSE:
|
||||
return button_context_usb_hid_mode_mouse;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
default:
|
||||
return button_context_standard;
|
||||
}
|
||||
return button_context_standard;
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#define LOGF_ENABLE
|
||||
//#define LOGF_ENABLE
|
||||
|
||||
#include "system.h"
|
||||
#include "config.h"
|
||||
|
@ -47,9 +47,10 @@
|
|||
*/
|
||||
#define HISPEED
|
||||
|
||||
/* Right now sending blocks till the full transfer has completed, this needs to
|
||||
* be fixed so that it does not require a block. (USB_TRAN_LOCK ideally would
|
||||
* not be set).
|
||||
/* Right now sending blocks till the full transfer has completed. The driver
|
||||
* will work without USB_TRAN_BLOCK set, but it is more than 50% slower.
|
||||
* The driver is more "Proper" without USB_TRAN_BLOCK defined so if you start
|
||||
* having freezeups or trouble using USB undefine this option.
|
||||
*/
|
||||
#define USB_TRAN_BLOCK
|
||||
|
||||
|
@ -69,7 +70,8 @@ static int pipe_maxpack_size (int pipe);
|
|||
static void control_received(void);
|
||||
static void transfer_complete(int endpoint);
|
||||
static int mxx_transmit_receive(int endpoint);
|
||||
static int mxx_queue(int endpoint, void * ptr, int length, bool send);
|
||||
static int mxx_queue(int endpoint, void * ptr, int length, bool send,
|
||||
bool wait);
|
||||
|
||||
struct M66591_epstat {
|
||||
unsigned char dir; /* endpoint direction */
|
||||
|
@ -91,6 +93,15 @@ static volatile unsigned short * pipe_ctrl_addr(int pipe) {
|
|||
}
|
||||
}
|
||||
|
||||
static void pipe_init(int pipe) {
|
||||
volatile unsigned short *pipe_cfg;
|
||||
pipe_cfg = pipe_ctrl_addr(pipe);
|
||||
|
||||
*pipe_cfg |= 1<<9; /* ACLR */
|
||||
*pipe_cfg &= ~(1<<9); /* Force de-assertion */
|
||||
*pipe_cfg |= 1<<8; /* SQCLR */
|
||||
}
|
||||
|
||||
/* This function sets the pipe/endpoint handshake */
|
||||
static void pipe_handshake(int pipe, int handshake) {
|
||||
handshake&=0x03;
|
||||
|
@ -125,7 +136,10 @@ static int pipe_buffer_size (int pipe) {
|
|||
return 256;
|
||||
case 1:
|
||||
case 2:
|
||||
return 1024;
|
||||
if(M66591_PIPE_CFGWND & (1<<9) )
|
||||
return 1024;
|
||||
else
|
||||
return 512;
|
||||
case 3:
|
||||
case 4:
|
||||
return 512;
|
||||
|
@ -206,7 +220,7 @@ static void transfer_complete(int endpoint) {
|
|||
logf("mxx: ep %d transfer complete", endpoint);
|
||||
int temp=M66591_eps[endpoint].dir ? USB_DIR_IN : USB_DIR_OUT;
|
||||
usb_core_transfer_complete(endpoint, temp, 0,
|
||||
M66591_eps[endpoint].length);
|
||||
M66591_eps[endpoint].count);
|
||||
}
|
||||
|
||||
/* This is the main transmit routine that is typically called from the interrupt
|
||||
|
@ -250,7 +264,8 @@ static int mxx_transmit_receive(int endpoint) {
|
|||
length = M66591_eps[endpoint].length;
|
||||
#else
|
||||
int bufsize=pipe_buffer_size(endpoint);
|
||||
length=MIN(M66591_eps[endpoint].length, bufsize);
|
||||
length=MIN(M66591_eps[endpoint].length - M66591_eps[endpoint].count,
|
||||
bufsize);
|
||||
#endif
|
||||
|
||||
/* Calculate the position in the buffer, all transfers should be 2-byte
|
||||
|
@ -259,32 +274,70 @@ static int mxx_transmit_receive(int endpoint) {
|
|||
ptrs = (unsigned short *)(M66591_eps[endpoint].buf
|
||||
+ M66591_eps[endpoint].count);
|
||||
|
||||
/* Start sending data in 16-bit words */
|
||||
for (i = 0; i < (length>>1); i++) {
|
||||
/* This wait is dangerous in the event that something happens to
|
||||
* the PHY pipe where it never becomes ready again, should probably
|
||||
* add a timeout, and ideally completely remove.
|
||||
*/
|
||||
while(!(M66591_CPORT_CTRL1&(1<<13))){};
|
||||
/* Check if the buffer is alligned */
|
||||
if( LIKELY(((int)ptrs) & 0x01) == 0 )
|
||||
{
|
||||
/* Start sending data in 16-bit words (fast) */
|
||||
for (i = 0; i < (length>>1); i++) {
|
||||
#if defined(USB_TRAN_BLOCK)
|
||||
/* This wait is dangerous in the event that something happens
|
||||
* to the PHY pipe where it never becomes ready again, should
|
||||
* probably add a timeout, and ideally completely remove.
|
||||
*/
|
||||
while(!(M66591_CPORT_CTRL1&(1<<13))){};
|
||||
#endif
|
||||
|
||||
M66591_CPORT = *ptrs++;
|
||||
M66591_eps[endpoint].count+=2;
|
||||
M66591_CPORT = *ptrs++;
|
||||
M66591_eps[endpoint].count+=2;
|
||||
}
|
||||
|
||||
/* If the length is odd, send the last byte after setting the byte
|
||||
* width of the FIFO.
|
||||
*/
|
||||
if(length & 0x01) {
|
||||
/* Unset MBW (8-bit transfer) */
|
||||
M66591_CPORT_CTRL0 &= ~(1<<10);
|
||||
M66591_CPORT = *((unsigned char *)ptrs);
|
||||
M66591_eps[endpoint].count++;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the length is odd, send the last byte after setting the byte width
|
||||
* of the FIFO.
|
||||
*/
|
||||
if(length & 0x01) {
|
||||
/* Unset MBW (8-bit transfer) */
|
||||
M66591_CPORT_CTRL0 &= ~(1<<10);
|
||||
M66591_CPORT = *((unsigned char *)ptrs - 1);
|
||||
M66591_eps[endpoint].count++;
|
||||
}
|
||||
|
||||
/* Set BVAL if length is not a multiple of the maximum packet size */
|
||||
if( (length == 0) || (length % maxpack != 0) ) {
|
||||
logf("mxx: do set BVAL");
|
||||
M66591_CPORT_CTRL1 |= (1<<15);
|
||||
else
|
||||
{
|
||||
/* The buffer is mis-aligned - data needs to be organized first.
|
||||
* This is slower than the above method.
|
||||
*/
|
||||
unsigned short sbuf;
|
||||
unsigned char *ptrc = (unsigned char*)ptrs;
|
||||
|
||||
/* Start sending data in 16-bit words */
|
||||
for (i = 0; i < (length>>1); i++) {
|
||||
#if defined(USB_TRAN_BLOCK)
|
||||
/* This wait is dangerous in the event that something happens
|
||||
* to the PHY pipe where it never becomes ready again, should
|
||||
* probably add a timeout, and ideally completely remove.
|
||||
*/
|
||||
while(!(M66591_CPORT_CTRL1&(1<<13))){};
|
||||
#endif
|
||||
|
||||
/* These are mis-aligned accesses so the data nees to be
|
||||
* arranged.
|
||||
*/
|
||||
sbuf = (*(ptrc+1) << 8) | *ptrc;
|
||||
ptrc += 2;
|
||||
|
||||
M66591_CPORT = sbuf;
|
||||
M66591_eps[endpoint].count+=2;
|
||||
}
|
||||
|
||||
/* If the length is odd, send the last byte after setting the byte
|
||||
* width of the FIFO.
|
||||
*/
|
||||
if(length & 0x01) {
|
||||
/* Unset MBW (8-bit transfer) */
|
||||
M66591_CPORT_CTRL0 &= ~(1<<10);
|
||||
M66591_CPORT = *ptrc;
|
||||
M66591_eps[endpoint].count++;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the transfer is complete set up interrupts to notify when FIFO is
|
||||
|
@ -302,6 +355,12 @@ static int mxx_transmit_receive(int endpoint) {
|
|||
/* There is still data to transfer, make sure READY is enabled */
|
||||
M66591_INTCFG_RDY |= 1 << endpoint;
|
||||
}
|
||||
|
||||
/* Set BVAL if length is not a multiple of the maximum packet size */
|
||||
if( (length == 0) || (length % maxpack != 0) ) {
|
||||
logf("mxx: do set BVAL");
|
||||
M66591_CPORT_CTRL1 |= (1<<15) | ((length == 0) << 14);
|
||||
}
|
||||
} else {
|
||||
/* Read data from FIFO */
|
||||
|
||||
|
@ -366,8 +425,17 @@ static int mxx_transmit_receive(int endpoint) {
|
|||
|
||||
/* This function is used to start transfers. It is a helper function for the
|
||||
* usb_drv_send_nonblocking, usb_drv_send, and usb_drv_receive functions.
|
||||
*
|
||||
* The functionality for wait needs to be added. Currently the driver is
|
||||
* always used in a blocking mode(USB_TRAN_BLOCK) so it is not required.
|
||||
*/
|
||||
static int mxx_queue(int endpoint, void * ptr, int length, bool send) {
|
||||
static int mxx_queue(int endpoint, void * ptr, int length, bool send,
|
||||
bool wait)
|
||||
{
|
||||
#if defined(USB_TRAN_BLOCK) && !defined(LOGF_ENABLE)
|
||||
(void) wait;
|
||||
#endif
|
||||
|
||||
/* Disable IRQs */
|
||||
int flags = disable_irq_save();
|
||||
|
||||
|
@ -384,7 +452,8 @@ static int mxx_queue(int endpoint, void * ptr, int length, bool send) {
|
|||
M66591_eps[endpoint].dir=send;
|
||||
M66591_eps[endpoint].waiting=true;
|
||||
|
||||
logf("mxx: queue ep %d %s, len: %d", endpoint, send ? "out" : "in", length);
|
||||
logf("mxx: queue ep %d %s, len: %d, wait: %d",
|
||||
endpoint, send ? "out" : "in", length, wait);
|
||||
|
||||
/* Pick the pipe that communications are happening on */
|
||||
pipe_c_select(endpoint, send);
|
||||
|
@ -436,9 +505,10 @@ static int mxx_queue(int endpoint, void * ptr, int length, bool send) {
|
|||
* This is the interrupt handler for this driver. It should be called from the
|
||||
* target interrupt handler routine (eg. GPIO3 on M:Robe 500).
|
||||
******************************************************************************/
|
||||
void USB_DEVICE(void) __attribute__ ((section(".icode")));
|
||||
void USB_DEVICE(void) {
|
||||
int pipe_restore=M66591_CPORT_CTRL0;
|
||||
logf("mxx: INT BEGIN tick: %d\n", (int) current_tick);
|
||||
logf("\nmxx: INT BEGIN tick: %d", (int) current_tick);
|
||||
|
||||
logf("mxx: sMAIN0: 0x%04x, sRDY: 0x%04x",
|
||||
M66591_INTSTAT_MAIN, M66591_INTSTAT_RDY);
|
||||
|
@ -548,7 +618,7 @@ void USB_DEVICE(void) {
|
|||
|
||||
/* Restore the pipe state before the interrupt occured */
|
||||
M66591_CPORT_CTRL0=pipe_restore;
|
||||
logf("\nmxx: INT END");
|
||||
logf("mxx: INT END\n");
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -576,7 +646,7 @@ int usb_drv_request_endpoint(int type, int dir) {
|
|||
|
||||
if (type == USB_ENDPOINT_XFER_BULK) {
|
||||
/* Enable double buffer mode (only used for ep 1 and 2) */
|
||||
pipecfg |= 1<<9;
|
||||
pipecfg |= 1<<9 | 1<<8;
|
||||
|
||||
/* Bulk endpoints must be between 1 and 4 inclusive */
|
||||
ep=1;
|
||||
|
@ -591,6 +661,8 @@ int usb_drv_request_endpoint(int type, int dir) {
|
|||
} else if (type == USB_ENDPOINT_XFER_INT) {
|
||||
ep=5;
|
||||
|
||||
pipecfg |= 1<<13;
|
||||
|
||||
while(M66591_eps[ep].busy && ep++<7);
|
||||
|
||||
/* If this reached 7 the endpoints were all busy */
|
||||
|
@ -612,14 +684,16 @@ int usb_drv_request_endpoint(int type, int dir) {
|
|||
|
||||
M66591_PIPE_CFGSEL=ep;
|
||||
|
||||
/* Enable pipe (15) and continuous transfer mode (8) */
|
||||
pipecfg |= 1<<15 | 1<<8;
|
||||
/* Enable pipe (15) */
|
||||
pipecfg |= 1<<15;
|
||||
|
||||
pipe_handshake(ep, PIPE_SHAKE_NAK);
|
||||
|
||||
/* Setup the flags */
|
||||
M66591_PIPE_CFGWND=pipecfg;
|
||||
|
||||
pipe_init(ep);
|
||||
|
||||
logf("mxx: ep req ep#: %d config: 0x%04x", ep, M66591_PIPE_CFGWND);
|
||||
|
||||
return ep | dir;
|
||||
|
@ -664,24 +738,13 @@ void usb_enable(bool on) {
|
|||
void usb_drv_init(void) {
|
||||
logf("mxx: Device Init");
|
||||
|
||||
/* State left behind by m:robe 500i original firmware */
|
||||
M66591_TRN_CTRL = 0x8001; /* External 48 MHz clock */
|
||||
M66591_TRN_LNSTAT = 0x0040; /* "Reserved. Set it to '1'." */
|
||||
|
||||
M66591_PIN_CFG0 = 0x0000;
|
||||
M66591_PIN_CFG1 = 0x8000; /* Drive Current: 3.3V setting */
|
||||
M66591_PIN_CFG2 = 0x0000;
|
||||
|
||||
M66591_INTCFG_MAIN = 0x0000; /* All Interrupts Disable for now */
|
||||
M66591_INTCFG_OUT = 0x0000; /* Sense is edge, polarity is low */
|
||||
M66591_INTCFG_RDY = 0x0000;
|
||||
M66591_INTCFG_NRDY = 0x0000;
|
||||
M66591_INTCFG_EMP = 0x0000;
|
||||
|
||||
M66591_INTSTAT_MAIN = 0;
|
||||
M66591_INTSTAT_RDY = 0;
|
||||
M66591_INTSTAT_NRDY = 0;
|
||||
M66591_INTSTAT_EMP = 0;
|
||||
M66591_TRN_CTRL = 0x8000; /* External 48 MHz clock */
|
||||
M66591_TRN_CTRL |=0x0001;
|
||||
|
||||
M66591_INTCFG_MAIN |=0x8000; /* Enable VBUS interrupt */
|
||||
}
|
||||
|
||||
/* fully enable driver */
|
||||
|
@ -713,17 +776,17 @@ void usb_attach(void) {
|
|||
M66591_TRN_CTRL &= ~(1<<7);
|
||||
#endif
|
||||
|
||||
/* Enable oscillation buffer */
|
||||
/* Enable oscillation buffer XCKE */
|
||||
M66591_TRN_CTRL |= (1<<13);
|
||||
|
||||
udelay(1500);
|
||||
|
||||
/* Enable reference clock, PLL */
|
||||
/* Enable reference clock, PLL RCKE */
|
||||
M66591_TRN_CTRL |= (3<<11);
|
||||
|
||||
udelay(9);
|
||||
|
||||
/* Enable internal clock supply */
|
||||
/* Enable internal clock supply SCKE */
|
||||
M66591_TRN_CTRL |= (1<<10);
|
||||
|
||||
/* Disable PIPE ready interrupts */
|
||||
|
@ -744,7 +807,7 @@ void usb_attach(void) {
|
|||
M66591_DCP_CNTMD |= (1<<8);
|
||||
|
||||
/* Set the threshold that the PHY will automatically transmit from EP0 */
|
||||
M66591_DCP_CTRLEN = 128;
|
||||
M66591_DCP_CTRLEN = 256;
|
||||
|
||||
pipe_handshake(0, PIPE_SHAKE_NAK);
|
||||
|
||||
|
@ -793,8 +856,7 @@ void usb_drv_exit(void) {
|
|||
*/
|
||||
int usb_drv_send_nonblocking(int endpoint, void* ptr, int length)
|
||||
{
|
||||
/* The last arguement for queue specifies the dir of data (true==send) */
|
||||
return mxx_queue(endpoint, ptr, length, true);
|
||||
return mxx_queue(endpoint, ptr, length, true, false);
|
||||
}
|
||||
|
||||
/* This function begins a transmit (on an IN endpoint), it does not block
|
||||
|
@ -802,8 +864,7 @@ int usb_drv_send_nonblocking(int endpoint, void* ptr, int length)
|
|||
*/
|
||||
int usb_drv_send(int endpoint, void* ptr, int length)
|
||||
{
|
||||
/* The last arguement for queue specifies the dir of data (true==send) */
|
||||
return mxx_queue(endpoint, ptr, length, true);
|
||||
return mxx_queue(endpoint, ptr, length, true, true);
|
||||
}
|
||||
|
||||
/* This function begins a receive (on an OUT endpoint), it should not block
|
||||
|
@ -811,8 +872,7 @@ int usb_drv_send(int endpoint, void* ptr, int length)
|
|||
*/
|
||||
int usb_drv_recv(int endpoint, void* ptr, int length)
|
||||
{
|
||||
/* Last arguement for queue specifies the dir of data (false==receive) */
|
||||
return mxx_queue(endpoint, ptr, length, false);
|
||||
return mxx_queue(endpoint, ptr, length, false, false);
|
||||
}
|
||||
|
||||
/* This function checks the reset handshake speed status
|
||||
|
|
|
@ -207,7 +207,7 @@
|
|||
/* enable these for the usb stack */
|
||||
#define CONFIG_USBOTG USBOTG_M66591
|
||||
#define USE_ROCKBOX_USB
|
||||
//#define USB_ENABLE_SERIAL
|
||||
|
||||
#define HAVE_USBSTACK
|
||||
//#define HAVE_USB_POWER
|
||||
//#define USBPOWER_BUTTON BUTTON_POWER
|
||||
|
@ -216,6 +216,7 @@
|
|||
#define USB_NUM_ENDPOINTS 7
|
||||
#define USB_VENDOR_ID 0x07b4
|
||||
#define USB_PRODUCT_ID 0x0281
|
||||
#define HAVE_USB_HID_MOUSE
|
||||
|
||||
/* Define this if hardware supports alternate blitting */
|
||||
#define HAVE_LCD_MODES LCD_MODE_RGB565 | LCD_MODE_YUV | LCD_MODE_PAL256
|
||||
|
|
|
@ -98,10 +98,18 @@ enum {
|
|||
#ifdef HAVE_USBSTACK
|
||||
/* USB class drivers */
|
||||
enum {
|
||||
#ifdef USB_ENABLE_STORAGE
|
||||
USB_DRIVER_MASS_STORAGE,
|
||||
#endif
|
||||
#ifdef USB_ENABLE_SERIAL
|
||||
USB_DRIVER_SERIAL,
|
||||
#endif
|
||||
#ifdef USB_ENABLE_CHARGING_ONLY
|
||||
USB_DRIVER_CHARGING_ONLY,
|
||||
#endif
|
||||
#ifdef USB_ENABLE_HID
|
||||
USB_DRIVER_HID,
|
||||
#endif
|
||||
USB_NUM_DRIVERS
|
||||
};
|
||||
|
||||
|
|
|
@ -30,32 +30,44 @@
|
|||
void usb_init_device(void) {
|
||||
logf("mxx: SOC Init");
|
||||
|
||||
/* The EMIF timing that is currently used may not be apropriate when the
|
||||
* device is boosted. The following values were used with sucess too:
|
||||
/* The following EMIF timing values are from the OF:
|
||||
* IO_EMIF_CS4CTRL1 = 0x66AB;
|
||||
* IO_EMIF_CS4CTRL2 = 0x4220;
|
||||
*
|
||||
* These EMIF timing values are more agressive, but appear to work as long
|
||||
* as USB_TRANS_BLOCK is defined in the USB driver:
|
||||
* IO_EMIF_CS4CTRL1 = 0x2245;
|
||||
* IO_EMIF_CS4CTRL2 = 0x4110;
|
||||
*
|
||||
* When USB_TRANS_BLOCK is not defined the USB driver does not work unless
|
||||
* the values from the OF are used.
|
||||
*/
|
||||
|
||||
IO_EMIF_CS4CTRL1 = 0x2245;
|
||||
IO_EMIF_CS4CTRL2 = 0x4110;
|
||||
|
||||
IO_GIO_DIR0 &= ~(1<<2);
|
||||
IO_GIO_INV0 &= ~(1<<2);
|
||||
IO_GIO_FSEL0 &= ~(0x03);
|
||||
/* Setup the m66591 reset signal */
|
||||
IO_GIO_DIR0 &= ~(1<<2); /* output */
|
||||
IO_GIO_INV0 &= ~(1<<2); /* non-inverted */
|
||||
IO_GIO_FSEL0 &= ~(0x03); /* normal pins */
|
||||
|
||||
/* Setup the m66591 interrupt signal */
|
||||
IO_GIO_DIR0 |= 1<<3; /* input */
|
||||
IO_GIO_INV0 &= ~(1<<3); /* non-inverted */
|
||||
IO_GIO_IRQPORT |= 1<<3; /* enable EIRQ */
|
||||
|
||||
udelay(100);
|
||||
|
||||
/* Drive the reset pin low */
|
||||
IO_GIO_BITCLR0 = 1<<2;
|
||||
IO_GIO_BITCLR0 = 1<<2;
|
||||
|
||||
/* Wait a bit */
|
||||
udelay(3);
|
||||
udelay(100);
|
||||
|
||||
/* Release the reset (drive it high) */
|
||||
IO_GIO_BITSET0 = 1<<2;
|
||||
IO_GIO_BITSET0 = 1<<2;
|
||||
|
||||
udelay(300);
|
||||
|
||||
IO_GIO_DIR0 |= 1<<3;
|
||||
IO_GIO_INV0 &= ~(1<<3);
|
||||
IO_GIO_IRQPORT |= 1<<3;
|
||||
udelay(500);
|
||||
|
||||
/* Enable the MXX interrupt */
|
||||
IO_INTC_EINT1 |= (1<<8); /* IRQ_GIO3 */
|
||||
|
|
|
@ -102,7 +102,7 @@ static const unsigned short const irqpriority[] =
|
|||
IRQ_ICE,IRQ_ARMCOM_RX,IRQ_ARMCOM_TX,IRQ_RESERVED
|
||||
}; /* IRQ priorities, ranging from highest to lowest */
|
||||
|
||||
static void (* const irqvector[])(void) =
|
||||
static void (* const irqvector[])(void) __attribute__ ((section(".idata"))) =
|
||||
{
|
||||
TIMER0,TIMER1,TIMER2,TIMER3,CCD_VD0,CCD_VD1,
|
||||
CCD_WEN,VENC,SERIAL0,SERIAL1,EXT_HOST,DSPHINT,
|
||||
|
@ -222,11 +222,16 @@ void system_init(void)
|
|||
|
||||
/* setup the clocks */
|
||||
IO_CLK_DIV0=0x0003;
|
||||
|
||||
/* SDRAM Divide by 3 */
|
||||
IO_CLK_DIV1=0x0102;
|
||||
IO_CLK_DIV2=0x021F;
|
||||
IO_CLK_DIV3=0x1FFF;
|
||||
IO_CLK_DIV4=0x1F00;
|
||||
|
||||
/* 27 MHz input clock:
|
||||
* PLLA = 27*11/1
|
||||
*/
|
||||
IO_CLK_PLLA=0x80A0;
|
||||
IO_CLK_PLLB=0x80C0;
|
||||
|
||||
|
@ -286,6 +291,7 @@ void system_init(void)
|
|||
ttb_init();
|
||||
/* Make sure everything is mapped on itself */
|
||||
map_section(0, 0, 0x1000, CACHE_NONE);
|
||||
|
||||
/* Enable caching for RAM */
|
||||
map_section(CONFIG_SDRAM_START, CONFIG_SDRAM_START, MEM, CACHE_ALL);
|
||||
/* enable buffered writing for the framebuffer */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue