1 | //============================================================================= |
---|
2 | // |
---|
3 | // cpuio.c |
---|
4 | // |
---|
5 | // CPU/Board Specific IO |
---|
6 | // |
---|
7 | // Author(s): Luis Torrico, Cogent Computer Systems, Inc. |
---|
8 | // Date: 12/04/2008 |
---|
9 | // Description: This file contains the IO functions required by Micro Monitor |
---|
10 | // that are unique to the CSB740 |
---|
11 | // |
---|
12 | // |
---|
13 | //============================================================================= |
---|
14 | |
---|
15 | #include "config.h" |
---|
16 | #include "cpuio.h" |
---|
17 | #include "genlib.h" |
---|
18 | #include "ether.h" |
---|
19 | #include "stddefs.h" |
---|
20 | #include "warmstart.h" |
---|
21 | #include "omap3530.h" |
---|
22 | #include "omap3530_mem.h" |
---|
23 | #include "cpu_gpio.h" |
---|
24 | #include "fb_draw.h" |
---|
25 | #include "uart16550.h" |
---|
26 | #include "umongpio.h" |
---|
27 | #include "ad7843.h" |
---|
28 | |
---|
29 | #define __raw_readl(a) (*(volatile unsigned int *)(a)) |
---|
30 | |
---|
31 | extern ulong i2c_init(void); |
---|
32 | extern ulong getpsr(void); |
---|
33 | extern void putpsr(ulong); |
---|
34 | |
---|
35 | uchar bcolor=0; // vga black |
---|
36 | |
---|
37 | /****************************************************** |
---|
38 | // Delay for some usecs. - Not accurate, assumes ROM mode |
---|
39 | // and no Cache |
---|
40 | ******************************************************/ |
---|
41 | void udelay(int delay) |
---|
42 | { |
---|
43 | volatile int i; |
---|
44 | for ( i = LOOPS_PER_USEC * delay; i ; i--); |
---|
45 | } |
---|
46 | |
---|
47 | /****************************************************** |
---|
48 | * Routine: wait_for_command_complete |
---|
49 | * Description: Wait for posting to finish on watchdog |
---|
50 | ******************************************************/ |
---|
51 | void wait_for_command_complete(unsigned int wd_base) |
---|
52 | { |
---|
53 | int pending = 1; |
---|
54 | do { |
---|
55 | pending = __raw_readl(wd_base + WD_WWPS); |
---|
56 | } while (pending); |
---|
57 | } |
---|
58 | |
---|
59 | /****************************************************** |
---|
60 | // getUARTDivisor is called from UART16550.c |
---|
61 | ******************************************************/ |
---|
62 | int |
---|
63 | getUartDivisor(int baud, unsigned char *hi, unsigned char *lo) |
---|
64 | { |
---|
65 | *lo = ((48000000/16)/baud) & 0x00ff; |
---|
66 | *hi = (((48000000/16)/baud) & 0xff00) >> 8; |
---|
67 | return(0); |
---|
68 | } |
---|
69 | |
---|
70 | /****************************************************** |
---|
71 | // Set pads (pins) to correct mode. Refer to section 7.4.4 |
---|
72 | in TI omap35xx_tech_ref_manual for bit defines. |
---|
73 | ******************************************************/ |
---|
74 | void pads_init() |
---|
75 | { |
---|
76 | // Set up chip selects |
---|
77 | SCM_REG(PADCONFS_GPMC_NCS3) = 0x00180018; // NCS3[15:0], NCS4[31:16] |
---|
78 | SCM_REG(PADCONFS_GPMC_NCS5) = 0x011C0018; // NCS5[15:0], EXP_INTX[31:16] |
---|
79 | |
---|
80 | // Set LCD_BKL_X to output, pullup enabled, mode 4 |
---|
81 | // Set LCLK to output, no pull-type and disabled, mode 0 |
---|
82 | SCM_REG(PADCONFS_GPMC_NCS7) = 0x0000001C; // LCD_BKL_X[15:0], LCLK(or GPIO_59)[31:16] |
---|
83 | |
---|
84 | // Set LCD pads to outputs, pull-type = up, pullud disabled, mode 0 |
---|
85 | SCM_REG(PADCONFS_DSS_PCLK) = 0x00100010; // LCD_PCLK_X[15:0], LCD_HS_X[31:16] |
---|
86 | SCM_REG(PADCONFS_DSS_VSYNC) = 0x00100010; // LCD_VS_X[15:0], LCD_OE_X[31:16] |
---|
87 | SCM_REG(PADCONFS_DSS_DATA0) = 0x00100010; // LCD_B0_X[15:0], LCD_B1_X[31:16] |
---|
88 | SCM_REG(PADCONFS_DSS_DATA2) = 0x00100010; // LCD_B2_X[15:0], LCD_B3_X[31:16] |
---|
89 | SCM_REG(PADCONFS_DSS_DATA4) = 0x00100010; // LCD_B4_X[15:0], LCD_B5_X[31:16] |
---|
90 | SCM_REG(PADCONFS_DSS_DATA6) = 0x00100010; // LCD_G0_X[15:0], LCD_G1_X[31:16] |
---|
91 | SCM_REG(PADCONFS_DSS_DATA8) = 0x00100010; // LCD_G2_X[15:0], LCD_G3_X[31:16] |
---|
92 | SCM_REG(PADCONFS_DSS_DATA10) = 0x00100010; // LCD_G4_X[15:0], LCD_G5_X[31:16] |
---|
93 | SCM_REG(PADCONFS_DSS_DATA12) = 0x00100010; // LCD_R0_X[15:0], LCD_R1_X[31:16] |
---|
94 | SCM_REG(PADCONFS_DSS_DATA14) = 0x00100010; // LCD_R2_X[15:0], LCD_R3_X[31:16] |
---|
95 | SCM_REG(PADCONFS_DSS_DATA16) = 0x00100010; // LCD_R4_X[15:0], LCD_R5_X[31:16] |
---|
96 | |
---|
97 | // Set D_TXD for output and D_RXD for input. Set both to pullup enabled and mode 1 |
---|
98 | SCM_REG(PADCONFS_MCBSP3_CLKX) = 0x01190019; // D_TXD[15:0], D_RXD[31:16] |
---|
99 | |
---|
100 | #ifdef AD7843_GPIOMODE |
---|
101 | // Depending on AD7843_GPIOMODE setting, we either configure the SPI |
---|
102 | // interface to the AD7843 as a real SPI device using the OMAP's SPI |
---|
103 | // controller, or we set it up with GPIO bits... |
---|
104 | SCM_REG(PADCONFS_DSS_DATA18) = 0x00040004; |
---|
105 | SCM_REG(PADCONFS_DSS_DATA20) = 0x00040104; |
---|
106 | #else |
---|
107 | SCM_REG(PADCONFS_DSS_DATA18) = 0x0002011A; // SPI1_CLK_X[15:0], SPI1_MOSI_X[31:16] |
---|
108 | SCM_REG(PADCONFS_DSS_DATA20) = 0x001A011A; // SPI1_MISO_X[15:0], *SPI1_CS0_X[31:16] |
---|
109 | #endif |
---|
110 | |
---|
111 | // Set PIRQ for ADS7843 touch interrupt. Set both to pullup enabled and mode 4 |
---|
112 | SCM_REG(PADCONFS_MMC1_DAT4) = 0x01040104; // *I2C_INT_X[15:0], *PIRQ_X[31:16] |
---|
113 | |
---|
114 | // GPIO1 is the push button on CSB703(set as input), GPIO0 is is LED on CSB703(set as output) |
---|
115 | SCM_REG(PADCONFS_MMC1_DAT6) = 0x01040004; // GPIO0_X[15:0], GPIO1_X[31:16] |
---|
116 | |
---|
117 | // Set E_INT* to be an input in GPIO mode |
---|
118 | SCM_REG(PADCONFS_GPMC_WAIT2) = 0x011C011f; // NA[15:0], E_INTX[31:16] |
---|
119 | |
---|
120 | // Set SYS_CLKOUT1 for USB_CLK |
---|
121 | SCM_REG(PADCONFS_SYS_OFF_MODE) = 0x0000010f; // OFF_MODE_X[15:0], SYS_CLKOUT1[31:16] |
---|
122 | |
---|
123 | // Set SYS_CLKOUT2 for debug purposes |
---|
124 | SCM_REG(PADCONFS_SYS_NIRQ) = 0x0000011f; // FIQ[15:0], SYS_CLK2[31:16] |
---|
125 | |
---|
126 | } |
---|
127 | |
---|
128 | int |
---|
129 | devInit(int baud) |
---|
130 | { |
---|
131 | // Initialize pads |
---|
132 | pads_init(); |
---|
133 | |
---|
134 | // Disable MPU Watchdog WDT2 |
---|
135 | WD2_REG(WD_WSPR) = 0x0000aaaa; |
---|
136 | wait_for_command_complete(WD2_BASE_ADD); |
---|
137 | WD2_REG(WD_WSPR) = 0x00005555; |
---|
138 | |
---|
139 | // Initialize GPIO |
---|
140 | GPIO_init(); |
---|
141 | |
---|
142 | // Setup UART pins to UART mode before calling InitUART from uart16550.c |
---|
143 | UART2_REG(UART_MDR1) = 0x0000; |
---|
144 | // Initialize the UART |
---|
145 | InitUART(baud); |
---|
146 | |
---|
147 | // Setup CS0 for 110ns Spansion Flash |
---|
148 | GPMC_REG(GPMC_CS0_CONFIG7) = 0x00000c48; // Base addr 0x08000000, 64M |
---|
149 | GPMC_REG(GPMC_CS0_CONFIG1) = 0x00001210; |
---|
150 | //GPMC_REG(GPMC_CS0_CONFIG5) = 0x00080808; // Config5 |
---|
151 | |
---|
152 | // Setup CS4 for LAN9211, on the CSB740 it is refered to as CS2 |
---|
153 | // and mapped to E_CS |
---|
154 | GPMC_REG(GPMC_CS4_CONFIG7) = 0x00000F6C; // Base addr 0x2C000000, 16M |
---|
155 | GPMC_REG(GPMC_CS4_CONFIG1) = 0x00001200; |
---|
156 | |
---|
157 | return 0; |
---|
158 | } |
---|
159 | |
---|
160 | /* Referring to table 25-10 of the TRM, install |
---|
161 | * the RAM exception vectors... |
---|
162 | */ |
---|
163 | void |
---|
164 | ram_vector_install(void) |
---|
165 | { |
---|
166 | extern unsigned long abort_data; |
---|
167 | extern unsigned long abort_prefetch; |
---|
168 | extern unsigned long undefined_instruction; |
---|
169 | extern unsigned long software_interrupt; |
---|
170 | extern unsigned long interrupt_request; |
---|
171 | extern unsigned long fast_interrupt_request; |
---|
172 | extern unsigned long not_assigned; |
---|
173 | |
---|
174 | *(ulong **)0x4020ffe4 = &undefined_instruction; |
---|
175 | *(ulong **)0x4020ffe8 = &software_interrupt; |
---|
176 | *(ulong **)0x4020ffec = &abort_prefetch; |
---|
177 | *(ulong **)0x4020fff0 = &abort_data; |
---|
178 | *(ulong **)0x4020fff4 = ¬_assigned; |
---|
179 | *(ulong **)0x4020fff8 = &interrupt_request; |
---|
180 | *(ulong **)0x4020fffc = &fast_interrupt_request; |
---|
181 | } |
---|
182 | |
---|
183 | void |
---|
184 | initCPUio() |
---|
185 | { |
---|
186 | volatile unsigned register cntens; |
---|
187 | volatile unsigned register usren; |
---|
188 | volatile unsigned register pmnc; |
---|
189 | |
---|
190 | ram_vector_install(); |
---|
191 | |
---|
192 | /* Do this stuff to enable the cycle counter |
---|
193 | * (for use by target_timer)... |
---|
194 | */ |
---|
195 | /* Allow user mode to have access to performance monitor registers: |
---|
196 | */ |
---|
197 | asm volatile (" MRC p15, 0, %0, c9, c14, 0" : "=r" (usren)); |
---|
198 | usren |= 1; |
---|
199 | asm volatile (" MCR p15, 0, %0, c9, c14, 0" : : "r" (usren)); |
---|
200 | |
---|
201 | /* Enable all counters, and reset Cycle counter... |
---|
202 | */ |
---|
203 | asm volatile (" MRC p15, 0, %0, c9, c12, 0" : "=r" (pmnc)); |
---|
204 | pmnc |= 5; |
---|
205 | asm volatile (" MCR p15, 0, %0, c9, c12, 0" : : "r" (pmnc)); |
---|
206 | |
---|
207 | /* Enable all performance counter registers... |
---|
208 | */ |
---|
209 | asm volatile (" MRC p15, 0, %0, c9, c12, 1" : "=r" (cntens)); |
---|
210 | cntens |= 0x8000000f; |
---|
211 | asm volatile (" MCR p15, 0, %0, c9, c12, 1" : : "r" (cntens)); |
---|
212 | } |
---|
213 | |
---|
214 | /* target_reset(): |
---|
215 | * Set the counter to 16 ticks before trigger, then enable the |
---|
216 | * watchdog timer (WDT2) and wait... |
---|
217 | */ |
---|
218 | void |
---|
219 | target_reset(void) |
---|
220 | { |
---|
221 | // Preload the count-up register... |
---|
222 | WD2_REG(WD_WCRR) = 0xfffffff0; |
---|
223 | |
---|
224 | // Start MPU Watchdog WDT2 |
---|
225 | WD2_REG(WD_WSPR) = 0x0000bbbb; |
---|
226 | wait_for_command_complete(WD2_BASE_ADD); |
---|
227 | WD2_REG(WD_WSPR) = 0x00004444; |
---|
228 | |
---|
229 | // Now just wait... |
---|
230 | while(1); |
---|
231 | } |
---|
232 | |
---|
233 | void |
---|
234 | intsrestore(psr) |
---|
235 | ulong psr; |
---|
236 | { |
---|
237 | putpsr(psr); |
---|
238 | } |
---|
239 | |
---|
240 | /* |
---|
241 | * Read the program status register (CPSR) |
---|
242 | * and set the FIQ and IRQ bits. |
---|
243 | */ |
---|
244 | ulong |
---|
245 | intsoff(void) |
---|
246 | { |
---|
247 | ulong psr; |
---|
248 | |
---|
249 | psr = getpsr(); |
---|
250 | |
---|
251 | /* |
---|
252 | * Set bit 6, bit 7 to disable interrupts. |
---|
253 | */ |
---|
254 | putpsr(psr | 0x000000c0); |
---|
255 | return(psr); |
---|
256 | } |
---|
257 | |
---|
258 | /* show_revision(): |
---|
259 | * Called when the system banner is printed... |
---|
260 | */ |
---|
261 | void |
---|
262 | show_revision(int center) |
---|
263 | { |
---|
264 | int (*pfunc)(char *, ...); |
---|
265 | volatile unsigned register main_id; |
---|
266 | volatile unsigned register silicon_id; |
---|
267 | |
---|
268 | if (center) |
---|
269 | pfunc = cprintf; |
---|
270 | else |
---|
271 | pfunc = printf; |
---|
272 | |
---|
273 | asm(" MRC p15, 0, %0, c0, c0, 0" : "=r" (main_id)); |
---|
274 | asm(" MRC p15, 1, %0, c0, c0, 7" : "=r" (silicon_id)); |
---|
275 | |
---|
276 | pfunc("Silicon ID: %d.%d\n", |
---|
277 | ((silicon_id & 0xf0)>>4),(silicon_id & 0xf)); |
---|
278 | |
---|
279 | pfunc("CPU Rev: %d, Variant: %d\n", |
---|
280 | main_id & 0xf,(main_id & 0x00f00000) >> 20); |
---|
281 | |
---|
282 | pfunc("CM Rev: %d.%d, PRM Rev: %d.%d\n", |
---|
283 | CM_REV_MAJ(),CM_REV_MIN(),PRM_REV_MAJ(),PRM_REV_MIN()); |
---|
284 | } |
---|
285 | |
---|
286 | /* target_timer(): |
---|
287 | * Used in conjunction with INCLUDE_HWTMR and TIMER_TICKS_PER_MSEC |
---|
288 | * to set up a hardware based time base. |
---|
289 | */ |
---|
290 | unsigned long |
---|
291 | target_timer(void) |
---|
292 | { |
---|
293 | volatile unsigned register ccr; |
---|
294 | |
---|
295 | asm(" MRC p15, 0, %0, c9, c13, 0" : "=r" (ccr)); |
---|
296 | |
---|
297 | return(ccr); |
---|
298 | } |
---|
299 | |
---|
300 | /* cacheInitForTarget(): |
---|
301 | Enable instruction cache only... |
---|
302 | */ |
---|
303 | void |
---|
304 | cacheInitForTarget() |
---|
305 | { |
---|
306 | asm(" MRC p15, 0, r0, c1, c0, 0"); |
---|
307 | asm(" ORR r0, r0, #0x1000"); /* bit 12 is ICACHE enable*/ |
---|
308 | asm(" MCR p15, 0, r0, c1, c0, 0"); |
---|
309 | |
---|
310 | /* Flush instruction cache */ |
---|
311 | asm(" MCR p15, 0, r0, c7, c5, 0"); |
---|
312 | } |
---|
313 | |
---|