root/ar5315_microredboot/microredboot/ecos/packages/hal/mips/ar2316/current/src/plf_misc.c

Revision 12431, 12.3 kB (checked in by BrainSlayer, 5 months ago)

third proof way to reboot

Line 
1 //==========================================================================
2 //
3 //      plf_misc.c
4 //
5 //      HAL platform miscellaneous functions
6 //
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 2003 Atheros Communications, Inc.
12 //
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
16 //
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20 // for more details.
21 //
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 //
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
32 //
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
35 //
36 // Alternative licenses for eCos may be arranged by contacting the copyright
37 // holders.
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //==========================================================================
41 //#####DESCRIPTIONBEGIN####
42 //
43 // Author(s):    adrian
44 // Contributors: based on existing files for other OS
45 // Date:         2003-10-20
46 // Purpose:      HAL miscellaneous functions
47 // Description:  This file contains miscellaneous functions provided by the
48 //               HAL.
49 //
50 //####DESCRIPTIONEND####
51 //
52 //========================================================================*/
53
54 #define CYGARC_HAL_COMMON_EXPORT_CPU_MACROS
55 #include <pkgconf/hal.h>
56
57 #include <cyg/infra/cyg_type.h>         // Base types
58 #include <cyg/infra/cyg_trac.h>         // tracing macros
59 #include <cyg/infra/cyg_ass.h>          // assertion macros
60 #include <cyg/hal/hal_arch.h>           // architectural definitions
61 #include <cyg/hal/hal_intr.h>           // Interrupt handling
62 #include <cyg/hal/hal_cache.h>          // Cache handling
63 #include <cyg/hal/hal_if.h>
64
65 #include <cyg/hal/ar2316reg.h>
66
67 static void hal_ar2316_flash_setup(void);
68
69 typedef cyg_uint32 u32;
70 typedef cyg_uint16 u16;
71 typedef cyg_uint8  u8;
72
73 /*
74  * This is board-specific data that is stored in a "fixed" location in flash.
75  * It is shared across operating systems, so it should not be changed lightly.
76  * The main reason we need it is in order to extract the ethernet MAC
77  * address(es).
78  */
79 struct ar531x_boarddata {
80     u32 magic;                       /* board data is valid */
81 #define AR531X_BD_MAGIC 0x35333131   /* "5311", for all 531x platforms */
82     u16 cksum;                       /* checksum (starting with BD_REV 2) */
83     u16 rev;                         /* revision of this struct */
84 #define BD_REV  4
85     char   boardName[64];            /* Name of board */
86     u16 major;                       /* Board major number */
87     u16 minor;                       /* Board minor number */
88     u32 config;                      /* Board configuration */
89 #define BD_ENET0        0x00000001   /* ENET0 is stuffed */
90 #define BD_ENET1        0x00000002   /* ENET1 is stuffed */
91 #define BD_UART1        0x00000004   /* UART1 is stuffed */
92 #define BD_UART0        0x00000008   /* UART0 is stuffed (dma) */
93 #define BD_RSTFACTORY   0x00000010   /* Reset factory defaults stuffed */
94 #define BD_SYSLED       0x00000020   /* System LED stuffed */
95 #define BD_EXTUARTCLK   0x00000040   /* External UART clock */
96 #define BD_CPUFREQ      0x00000080   /* cpu freq is valid in nvram */
97 #define BD_SYSFREQ      0x00000100   /* sys freq is set in nvram */
98 #define BD_WLAN0        0x00000200   /* use WLAN0 */
99 #define BD_MEMCAP       0x00000400   /* CAP SDRAM @ memCap for testing */
100 #define BD_DISWATCHDOG  0x00000800   /* disable system watchdog */
101 #define BD_WLAN1        0x00001000   /* Enable WLAN1 (ar5212) */
102 #define BD_ISCASPER     0x00002000   /* FLAG for AR2312 */
103 #define BD_WLAN0_2G_EN  0x00004000   /* FLAG for radio0_2G */
104 #define BD_WLAN0_5G_EN  0x00008000   /* FLAG for radio0_2G */
105 #define BD_WLAN1_2G_EN  0x00020000   /* FLAG for radio0_2G */
106 #define BD_WLAN1_5G_EN  0x00040000   /* FLAG for radio0_2G */
107     u16 resetConfigGpio;             /* Reset factory GPIO pin */
108     u16 sysLedGpio;                  /* System LED GPIO pin */
109
110     u32 cpuFreq;                     /* CPU core frequency in Hz */
111     u32 sysFreq;                     /* System frequency in Hz */
112     u32 cntFreq;                     /* Calculated C0_COUNT frequency */
113
114     u8  wlan0Mac[6];
115     u8  enet0Mac[6];
116     u8  enet1Mac[6];
117
118     u16 pciId;                       /* Pseudo PCIID for common code */
119     u16 memCap;                      /* cap bank1 in MB */
120
121     /* version 3 */
122     u8  wlan1Mac[6];                 /* (ar5212) */
123 };
124
125 char *ar531x_board_configuration;
126 char *ar531x_radio_configuration;
127
128 //--------------------------------------------------------------------------
129
130
131 static void
132 sysGpioSet(int gpio, int val)
133 {
134     u32 reg;
135        
136     HAL_READ_UINT32(AR2316_GPIO_DO, reg);
137     reg &= ~(1 << gpio);
138     reg |= (val&1) << gpio;
139     HAL_WRITE_UINT32(AR2316_GPIO_DO, reg);
140     HAL_READ_UINT32(AR2316_GPIO_DO, reg); /* flush write to hardware */
141 }
142
143 void
144 hal_platform_init(void)
145 {
146     volatile u32 tmp;
147
148     HAL_WRITE_UINT32(AR2316_WDC, 0);
149
150     /* Setup the GPIO so we make sure the reset gpio is ok */
151     sysGpioSet(AR2316_RESET_GPIO, 1);
152     HAL_READ_UINT32(AR2316_GPIO_CR, tmp);
153     HAL_WRITE_UINT32(AR2316_GPIO_CR, (tmp | GPIO_CR_O(AR2316_RESET_GPIO)));
154     HAL_READ_UINT32(AR2316_GPIO_DO, tmp); /* flush write to hardware */
155
156     sysGpioSet(0, 1);
157     HAL_READ_UINT32(AR2316_GPIO_CR, tmp);
158     HAL_WRITE_UINT32(AR2316_GPIO_CR, (tmp | GPIO_CR_O(0)));
159     HAL_READ_UINT32(AR2316_GPIO_DO, tmp); /* flush write to hardware */
160
161     /* CPU owns AHB bus */
162     HAL_WRITE_UINT32(AR2316_AHB_ARB_CTL, ARB_CPU);
163
164     hal_if_init();
165     hal_ar2316_flash_setup();
166
167     HAL_ICACHE_INVALIDATE_ALL();   
168     HAL_ICACHE_ENABLE();
169     HAL_DCACHE_INVALIDATE_ALL();
170     HAL_DCACHE_ENABLE();
171 }
172
173 #define AR5315_DSLBASE          0xB1000000      /* RESET CONTROL MMR */
174 #define AR5315_PLLC_CTL         (AR5315_DSLBASE + 0x0064)
175 #define AR5315_CPUCLK           (AR5315_DSLBASE + 0x006c)
176 #define AR5315_AMBACLK          (AR5315_DSLBASE + 0x0070)
177 #define AR5315_RESET            (AR5315_DSLBASE + 0x0004)
178 #define AR5315_RESET_UART0                 0x00000100      /* warm reset UART0 */
179
180 /* PLLc Control fields */
181 #define PLLC_REF_DIV_M              0x00000003
182 #define PLLC_REF_DIV_S              0
183 #define PLLC_FDBACK_DIV_M           0x0000007C
184 #define PLLC_FDBACK_DIV_S           2
185 #define PLLC_ADD_FDBACK_DIV_M       0x00000080
186 #define PLLC_ADD_FDBACK_DIV_S       7
187 #define PLLC_CLKC_DIV_M             0x0001c000
188 #define PLLC_CLKC_DIV_S             14
189 #define PLLC_CLKM_DIV_M             0x00700000
190 #define PLLC_CLKM_DIV_S             20
191
192 /* CPU CLK Control fields */
193 #define CPUCLK_CLK_SEL_M            0x00000003
194 #define CPUCLK_CLK_SEL_S            0
195 #define CPUCLK_CLK_DIV_M            0x0000000c
196 #define CPUCLK_CLK_DIV_S            2
197
198
199
200
201 static const int CLOCKCTL1_PREDIVIDE_TABLE[4] = {
202     1,
203     2,
204     4,
205     5
206 };
207
208 static const int PLLC_DIVIDE_TABLE[5] = {
209     2,
210     3,
211     4,
212     6,
213     3
214 };
215
216 static unsigned int
217 ar5315_sys_clk(unsigned int clockCtl)
218 {
219     unsigned int pllcCtrl,cpuDiv;
220     unsigned int pllcOut,refdiv,fdiv,divby2;
221         unsigned int clkDiv;
222     HAL_READ_UINT32(AR5315_PLLC_CTL,pllcCtrl);
223     refdiv = (pllcCtrl & PLLC_REF_DIV_M) >> PLLC_REF_DIV_S;
224     refdiv = CLOCKCTL1_PREDIVIDE_TABLE[refdiv];
225     fdiv = (pllcCtrl & PLLC_FDBACK_DIV_M) >> PLLC_FDBACK_DIV_S;
226     divby2 = (pllcCtrl & PLLC_ADD_FDBACK_DIV_M) >> PLLC_ADD_FDBACK_DIV_S;
227     divby2 += 1;
228     pllcOut = (40000000/refdiv)*(2*divby2)*fdiv;
229
230
231     /* clkm input selected */
232         switch(clockCtl & CPUCLK_CLK_SEL_M) {
233                 case 0:
234                 case 1:
235                         clkDiv = PLLC_DIVIDE_TABLE[(pllcCtrl & PLLC_CLKM_DIV_M) >> PLLC_CLKM_DIV_S];
236                         break;
237                 case 2:
238                         clkDiv = PLLC_DIVIDE_TABLE[(pllcCtrl & PLLC_CLKC_DIV_M) >> PLLC_CLKC_DIV_S];
239                         break;
240                 default:
241                         pllcOut = 40000000;
242                         clkDiv = 1;
243                         break;
244         }
245         cpuDiv = (clockCtl & CPUCLK_CLK_DIV_M) >> CPUCLK_CLK_DIV_S; 
246         cpuDiv = cpuDiv * 2 ?: 1;
247         return pllcOut/(clkDiv * cpuDiv);
248 }
249                
250 unsigned int hal_ar2316_cpu_frequency(void)
251 {
252     unsigned int param;
253     HAL_READ_UINT32(AR5315_CPUCLK,param);
254     return ar5315_sys_clk(sysRegRead(param));
255 }
256
257 unsigned int hal_ar2316_sys_frequency(void)
258 {
259     unsigned int param;
260     HAL_READ_UINT32(AR5315_AMBACLK,param);
261     return ar5315_sys_clk(param);
262 }
263
264
265 static void
266 hal_ar2316_flash_setup(void)
267 {
268     int ar531x_flash_data_found;
269
270     /*
271      * Find start of Radio Configuration data, using heuristics:
272      * Search back from the (aliased) end of flash by 0x1000 bytes
273      * at a time until we find the string "5311", which marks the
274      * start of Board Configuration.  Give up if we've searched
275      * more than 500KB.
276      */
277     ar531x_flash_data_found = 0;
278     // eileen , for 8MB flash , 20080626
279 #if CYGNUM_FLASH_SIZE == 0x400000
280         for (ar531x_board_configuration = (char *)0xbfff0000;
281         ar531x_board_configuration > (char *)0xbff80000;
282 #elif CYGNUM_FLASH_SIZE == 0x800000
283     for (ar531x_board_configuration = (char *)0xa87f0000;
284          ar531x_board_configuration > (char *)0xa8180000;
285 #else
286 #Warning! Currently works for only 4MB and 8MB
287 #endif // CYGNUM_FLASH_SIZE
288          ar531x_board_configuration -= 0x1000) {
289         if ( *(int *)ar531x_board_configuration == AR531X_BD_MAGIC) {
290             ar531x_flash_data_found = 1;
291             break;
292         }
293     }
294
295     if (!ar531x_flash_data_found) {
296         diag_printf("No board config data found!\n");
297         return;
298     }
299
300     /*
301      * Now find the start of Board Configuration data, using heuristics:
302      * Search forward from Board Configuration data by 0x1000 bytes
303      * at a time until we find non-0xffffffff.
304      */
305     ar531x_flash_data_found = 0;
306     for (ar531x_radio_configuration = ar531x_board_configuration + 0xf8;
307 #if CYGNUM_FLASH_SIZE == 0x400000
308         ar531x_radio_configuration < (char *)0xbffff000;
309 #elif CYGNUM_FLASH_SIZE == 0x800000
310         ar531x_radio_configuration < (char *)0xa87ff000;
311 #else
312 #Warning! Currently works for only 4MB and 8MB
313 #endif // CYGNUM_FLASH_SIZE
314         ar531x_radio_configuration += 0x1000) {
315         if (*(int *)ar531x_radio_configuration != 0xffffffff) {
316             ar531x_flash_data_found = 1;
317             break;
318         }
319     }
320
321     if (!ar531x_flash_data_found) {
322         diag_printf("No radio config data found!\n");
323         return;
324     }
325 }
326
327 /*
328  * Fetch a pointer to an ethernet's MAC address
329  * in the Board Configuration data (in flash).
330  */
331 unsigned char *
332 enet_mac_address_get(int unit)
333 {
334     struct ar531x_boarddata *board_config_data =
335         (struct ar531x_boarddata *)ar531x_board_configuration;
336     unsigned char *mac_addr = NULL;
337
338     if (!board_config_data)
339         return NULL;
340
341     if (unit == 0) {
342         mac_addr = board_config_data->enet0Mac;
343     }
344
345     if (unit == 1) {
346         mac_addr = board_config_data->enet1Mac;
347     }
348
349     /* Small sanity check, mainly to deal with uninitialized board config */
350     if (mac_addr[0] != 0xff) {
351         return mac_addr;
352     }
353
354     return NULL;
355 }
356
357 /*------------------------------------------------------------------------*/
358 /* Reset support                                                          */
359
360 void
361 hal_ar2316_reset(void)
362 {
363         void (*mips_reset_vec)(void) = (void *) 0xbfc00000;
364     for(;;) {
365         HAL_WRITE_UINT32(AR2316_COLD_RESET,AR2317_RESET_SYSTEM);
366         udelay(100*1000);
367         sysGpioSet(AR2316_RESET_GPIO, 0);
368         udelay(100*1000);
369         sysGpioSet(0, 0);
370         udelay(100*1000);
371         mips_reset_vec();
372     }
373 }
374
375 /*------------------------------------------------------------------------*/
376 /* End of plf_misc.c                                                      */
Note: See TracBrowser for help on using the browser.