Simulate the effects of sector caching a bit. Bypass I/O yield if a byte counter...
[Rockbox.git] / firmware / drivers / isp1362.c
blob473c9dc3db7d3407095579ff94a1ed0ac9843ffa
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2006 Jens Arnold
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
20 #include "system.h"
21 #include "kernel.h"
22 #include "isp1362.h"
24 #define HC_DATA (*((volatile unsigned short*)0xc0000000))
25 #define HC_CMD (*((volatile unsigned short*)0xc0000002))
26 #define DC_DATA (*((volatile unsigned short*)0xc0000004))
27 #define DC_CMD (*((volatile unsigned short*)0xc0000006))
29 /* host controller access */
31 unsigned isp1362_read_hc_reg16(unsigned reg)
33 HC_CMD = reg;
35 asm ("nop\n nop\n nop\n nop\n");
36 asm ("nop\n nop\n nop\n nop\n");
37 asm ("nop\n nop\n nop\n nop\n");
39 return HC_DATA;
42 unsigned isp1362_read_hc_reg32(unsigned reg)
44 unsigned data;
46 HC_CMD = reg;
48 asm ("nop\n nop\n nop\n nop\n");
49 asm ("nop\n nop\n nop\n nop\n");
50 asm ("nop\n nop\n nop\n nop\n");
52 data = HC_DATA;
53 data |= HC_DATA << 16;
54 return data;
57 void isp1362_write_hc_reg16(unsigned reg, unsigned data)
59 HC_CMD = reg | 0x80;
61 asm ("nop\n nop\n nop\n");
63 HC_DATA = data;
66 void isp1362_write_hc_reg32(unsigned reg, unsigned data)
68 HC_CMD = reg | 0x80;
70 asm ("nop\n nop\n nop\n");
72 HC_DATA = data;
73 HC_DATA = data >> 16;
76 /* device controller access */
78 unsigned isp1362_read_dc_reg16(unsigned reg)
80 DC_CMD = reg;
82 asm ("nop\n nop\n nop\n nop\n");
83 asm ("nop\n nop\n nop\n nop\n");
84 asm ("nop\n nop\n nop\n nop\n");
86 return DC_DATA;
89 unsigned isp1362_read_dc_reg32(unsigned reg)
91 unsigned data;
93 DC_CMD = reg;
95 asm ("nop\n nop\n nop\n nop\n");
96 asm ("nop\n nop\n nop\n nop\n");
97 asm ("nop\n nop\n nop\n nop\n");
99 data = DC_DATA;
100 data |= DC_DATA << 16;
101 return data;
104 void isp1362_write_dc_reg16(unsigned reg, unsigned data)
106 DC_CMD = reg;
108 asm ("nop\n nop\n nop\n");
110 DC_DATA = data;
113 void isp1362_write_dc_reg32(unsigned reg, unsigned data)
115 DC_CMD = reg;
117 asm ("nop\n nop\n nop\n");
119 DC_DATA = data;
120 DC_DATA = data >> 16;
123 static void isp1362_suspend(void)
125 unsigned data;
127 data = isp1362_read_hc_reg16(ISP1362_OTG_CONTROL);
128 data &= ~0x0001; /* DRV_VBUS = 0 */
129 isp1362_write_hc_reg16(ISP1362_OTG_CONTROL, data);
131 /* prepare the DC */
132 data = isp1362_read_dc_reg16(ISP1362_DC_HARDWARE_CONFIG_R);
133 data &= ~0x1008; /* CLKRUN = WKUPCS = 0. Wakeup is still possible via /D_WAKEUP */
134 isp1362_write_dc_reg16(ISP1362_DC_HARDWARE_CONFIG_W, data);
136 /* send the DC to sleep */
137 data = isp1362_read_dc_reg16(ISP1362_DC_MODE_R);
138 data |= 0x20; /* GOSUSP = 1 */
139 isp1362_write_dc_reg16(ISP1362_DC_MODE_W, data);
140 data &= ~0x20; /* GOSUSP = 0 */
141 isp1362_write_dc_reg16(ISP1362_DC_MODE_W, data);
143 /* prepare the HC */
144 data = isp1362_read_hc_reg16(ISP1362_HC_HARDWARE_CONFIG);
145 data &= ~0x0800; /* SuspendClkNotStop = 0 */
146 data |= 0x4001; /* GlobalPowerDown = InterruptPinEnable = 1 */
147 isp1362_write_hc_reg16(ISP1362_HC_HARDWARE_CONFIG, data);
149 /* TODO: OTG wake-up cfg */
150 /* TODO: Interrupt setup */
152 /* set the HC to operational */
153 isp1362_write_hc_reg32(ISP1362_HC_CONTROL, 0x0680);
154 /* RWE = RWC = 1, HCFS = 0b10 (USBOperational) */
155 /* ..then send it to sleep */
156 isp1362_write_hc_reg32(ISP1362_HC_CONTROL, 0x06c0);
157 /* RWE = RWC = 1, HCFS = 0b11 (USBSuspend) */
160 /* init */
162 void isp1362_init(void)
164 and_l(~0x00200080, &GPIO1_OUT); /* disable 5V USB host power and ??? */
165 or_l( 0x00200080, &GPIO1_ENABLE);
166 or_l( 0x00200080, &GPIO1_FUNCTION);
168 or_l( 0x20600000, &GPIO_OUT); /* ID = D_SUSPEND = /OTGMODE = 1 */
169 and_l(~0x04000000, &GPIO_OUT); /* ?R26? = 0 */
170 or_l( 0x24600000, &GPIO_ENABLE); /* ID, ?R26?, D_SUSPEND, /OTGMODE outputs */
171 and_l(~0x000000a8, &GPIO_ENABLE); /* /INT2, /INT1, /RESET inputs */
172 or_l( 0x246000a8, &GPIO_FUNCTION); /* GPIO for these pins */
174 sleep(HZ/5);
176 isp1362_suspend();