gth2.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. /*
  2. * (C) Copyright 2005
  3. * Thomas.Lange@corelatus.se
  4. *
  5. * See file CREDITS for list of people who contributed to this
  6. * project.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation; either version 2 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21. * MA 02111-1307 USA
  22. */
  23. #include <common.h>
  24. #include <command.h>
  25. #include <asm/au1x00.h>
  26. #include <asm/addrspace.h>
  27. #include <asm/mipsregs.h>
  28. #include <asm/io.h>
  29. #include <watchdog.h>
  30. #include "ee_access.h"
  31. static int wdi_status = 0;
  32. #define SDRAM_SIZE ((64*1024*1024)-(12*4096))
  33. #define SERIAL_LOG_BUFFER CKSEG1ADDR(SDRAM_SIZE + (8*4096))
  34. void inline log_serial_char(char c){
  35. char *serial_log_buffer = (char*)SERIAL_LOG_BUFFER;
  36. int serial_log_offset;
  37. u32 *serial_log_offsetp = (u32*)SERIAL_LOG_BUFFER;
  38. serial_log_offset = *serial_log_offsetp;
  39. *(serial_log_buffer + serial_log_offset) = c;
  40. serial_log_offset++;
  41. if(serial_log_offset >= 4096){
  42. serial_log_offset = 4;
  43. }
  44. *serial_log_offsetp = serial_log_offset;
  45. }
  46. void init_log_serial(void){
  47. char *serial_log_buffer = (char*)SERIAL_LOG_BUFFER;
  48. u32 *serial_log_offsetp = (u32*)SERIAL_LOG_BUFFER;
  49. /* Copy buffer from last run */
  50. memcpy(serial_log_buffer + 4096,
  51. serial_log_buffer,
  52. 4096);
  53. memset(serial_log_buffer, 0, 4096);
  54. *serial_log_offsetp = 4;
  55. }
  56. void hw_watchdog_reset(void){
  57. volatile u32 *sys_outputset = (volatile u32*)SYS_OUTPUTSET;
  58. volatile u32 *sys_outputclear = (volatile u32*)SYS_OUTPUTCLR;
  59. if(wdi_status){
  60. *sys_outputset = GPIO_CPU_LED|GPIO_WDI;
  61. wdi_status = 0;
  62. }
  63. else{
  64. *sys_outputclear = GPIO_CPU_LED|GPIO_WDI;
  65. wdi_status = 1;
  66. }
  67. }
  68. phys_size_t initdram(int board_type)
  69. {
  70. /* Sdram is setup by assembler code */
  71. /* If memory could be changed, we should return the true value here */
  72. WATCHDOG_RESET();
  73. return (SDRAM_SIZE);
  74. }
  75. /* In arch/mips/cpu/cpu.c */
  76. void write_one_tlb( int index, u32 pagemask, u32 hi, u32 low0, u32 low1 );
  77. void set_ledcard(u32 value){
  78. /* Clock 24 bits to led card */
  79. int i;
  80. volatile u32 *sys_outputset = (volatile u32*)SYS_OUTPUTSET;
  81. volatile u32 *sys_outputclr = (volatile u32*)SYS_OUTPUTCLR;
  82. /* Start with known values */
  83. *sys_outputclr = GPIO_LEDCLK|GPIO_LEDD;
  84. for(i=0;i<24;i++){
  85. if(value&0x00800000){
  86. *sys_outputset = GPIO_LEDD;
  87. }
  88. else{
  89. *sys_outputclr = GPIO_LEDD;
  90. }
  91. udelay(1);
  92. *sys_outputset = GPIO_LEDCLK;
  93. udelay(1);
  94. *sys_outputclr = GPIO_LEDCLK;
  95. udelay(1);
  96. value<<=1;
  97. }
  98. /* Data is enable output */
  99. *sys_outputset = GPIO_LEDD;
  100. }
  101. int checkboard (void)
  102. {
  103. volatile u32 *sys_counter = (volatile u32*)SYS_COUNTER_CNTRL;
  104. volatile u32 *sys_outputset = (volatile u32*)SYS_OUTPUTSET;
  105. volatile u32 *sys_outputclr = (volatile u32*)SYS_OUTPUTCLR;
  106. u32 proc_id;
  107. WATCHDOG_RESET();
  108. *sys_counter = 0x100; /* Enable 32 kHz oscillator for RTC/TOY */
  109. proc_id = read_c0_prid();
  110. switch (proc_id >> 24) {
  111. case 0:
  112. puts ("Board: GTH2\n");
  113. printf ("CPU: Au1000 500 MHz, id: 0x%02x, rev: 0x%02x\n",
  114. (proc_id >> 8) & 0xFF, proc_id & 0xFF);
  115. break;
  116. default:
  117. printf ("Unsupported cpu %d, proc_id=0x%x\n", proc_id >> 24, proc_id);
  118. }
  119. set_io_port_base(0);
  120. #ifdef CONFIG_IDE_PCMCIA
  121. /* PCMCIA is on a 36 bit physical address.
  122. We need to map it into a 32 bit addresses */
  123. write_one_tlb(20, /* index */
  124. 0x01ffe000, /* Pagemask, 16 MB pages */
  125. CONFIG_SYS_PCMCIA_IO_BASE, /* Hi */
  126. 0x3C000017, /* Lo0 */
  127. 0x3C200017); /* Lo1 */
  128. write_one_tlb(21, /* index */
  129. 0x01ffe000, /* Pagemask, 16 MB pages */
  130. CONFIG_SYS_PCMCIA_ATTR_BASE, /* Hi */
  131. 0x3D000017, /* Lo0 */
  132. 0x3D200017); /* Lo1 */
  133. write_one_tlb(22, /* index */
  134. 0x01ffe000, /* Pagemask, 16 MB pages */
  135. CONFIG_SYS_PCMCIA_MEM_ADDR, /* Hi */
  136. 0x3E000017, /* Lo0 */
  137. 0x3E200017); /* Lo1 */
  138. #endif /* CONFIG_IDE_PCMCIA */
  139. /* Wait for GPIO ports to become stable */
  140. udelay(5000); /* FIXME */
  141. /* Release reset of ethernet PHY chips */
  142. /* Always do this, because linux does not know about it */
  143. *sys_outputset = GPIO_ERESET;
  144. /* Kill FPGA:s */
  145. *sys_outputclr = GPIO_CACONFIG|GPIO_DPACONFIG;
  146. udelay(2);
  147. *sys_outputset = GPIO_CACONFIG|GPIO_DPACONFIG;
  148. /* Turn front led yellow */
  149. set_ledcard(0x00100000);
  150. return 0;
  151. }
  152. #define POWER_OFFSET 0xF0000
  153. #define SW_WATCHDOG_REASON 13
  154. #define BOOTDATA_OFFSET 0xF8000
  155. #define MAX_ATTEMPTS 5
  156. #define FAILSAFE_BOOT 1
  157. #define SYSTEM_BOOT 2
  158. #define SYSTEM2_BOOT 3
  159. #define WRITE_FLASH16(a, d) \
  160. do \
  161. { \
  162. *((volatile u16 *) (a)) = (d);\
  163. } while(0)
  164. static void write_bootdata (volatile u16 * addr, u8 System, u8 Count)
  165. {
  166. u16 data;
  167. volatile u16 *flash = (u16 *) (CONFIG_SYS_FLASH_BASE);
  168. switch(System){
  169. case FAILSAFE_BOOT:
  170. printf ("Setting failsafe boot in flash\n");
  171. break;
  172. case SYSTEM_BOOT:
  173. printf ("Setting system boot in flash\n");
  174. break;
  175. case SYSTEM2_BOOT:
  176. printf ("Setting system2 boot in flash\n");
  177. break;
  178. default:
  179. printf ("Invalid system data %u, setting failsafe\n", System);
  180. System = FAILSAFE_BOOT;
  181. }
  182. if ((Count < 1) | (Count > MAX_ATTEMPTS)) {
  183. printf ("Invalid boot count %u, setting 1\n", Count);
  184. Count = 1;
  185. }
  186. printf ("Boot attempt %d\n", Count);
  187. data = (System << 8) | Count;
  188. /* AMD 16 bit */
  189. WRITE_FLASH16 (&flash[0x555], 0xAAAA);
  190. WRITE_FLASH16 (&flash[0x2AA], 0x5555);
  191. WRITE_FLASH16 (&flash[0x555], 0xA0A0);
  192. WRITE_FLASH16 (addr, data);
  193. }
  194. static int random_system(void){
  195. /* EEPROM read failed. Just try to choose one
  196. system release and hope it works */
  197. /* FIXME */
  198. return(SYSTEM_BOOT);
  199. }
  200. static int switch_system(int old_system){
  201. u8 Rx[10];
  202. u8 Tx[5];
  203. int valid_release;
  204. if(old_system==FAILSAFE_BOOT){
  205. /* Find out which system release to use */
  206. /* Copy from nvram to scratchpad */
  207. Tx[0] = RECALL_MEMORY;
  208. Tx[1] = 7; /* Page */
  209. if (ee_do_cpu_command (Tx, 2, NULL, 0, 1)) {
  210. printf ("EE user page 7 recall failed\n");
  211. return (random_system());
  212. }
  213. Tx[0] = READ_SCRATCHPAD;
  214. if (ee_do_cpu_command (Tx, 2, Rx, 9, 1)) {
  215. printf ("EE user page 7 read failed\n");
  216. return (random_system());
  217. }
  218. /* Crc in 9:th byte */
  219. if (!ee_crc_ok (Rx, 8, *(Rx + 8))) {
  220. printf ("EE read failed, page 7. CRC error\n");
  221. return (random_system());
  222. }
  223. valid_release = Rx[7];
  224. if((valid_release==0xFF)|
  225. ((valid_release&1) == 0)){
  226. return(SYSTEM_BOOT);
  227. }
  228. else{
  229. return(SYSTEM2_BOOT);
  230. }
  231. }
  232. else{
  233. return(FAILSAFE_BOOT);
  234. }
  235. }
  236. static void check_boot_tries (void)
  237. {
  238. /* Count the number of boot attemps
  239. switch system if too many */
  240. int i;
  241. volatile u16 *addr;
  242. volatile u16 data;
  243. u8 system = FAILSAFE_BOOT;
  244. u8 count;
  245. addr = (u16 *) (CONFIG_SYS_FLASH_BASE + BOOTDATA_OFFSET);
  246. if (*addr == 0xFFFF) {
  247. printf ("*** No bootdata exists. ***\n");
  248. write_bootdata (addr, FAILSAFE_BOOT, 1);
  249. } else {
  250. /* Search for latest written bootdata */
  251. i = 0;
  252. while ((*(addr + 1) != 0xFFFF) & (i < 8000)) {
  253. addr++;
  254. i++;
  255. }
  256. if (i >= 8000) {
  257. /* Whoa, dont write any more */
  258. printf ("*** No bootdata found. Not updating flash***\n");
  259. } else {
  260. /* See how many times we have tried to boot real system */
  261. data = *addr;
  262. system = data >> 8;
  263. count = data & 0xFF;
  264. if ((system != SYSTEM_BOOT) &
  265. (system != SYSTEM2_BOOT) &
  266. (system != FAILSAFE_BOOT)) {
  267. printf ("*** Wrong system %d\n", system);
  268. system = FAILSAFE_BOOT;
  269. count = 1;
  270. } else {
  271. switch (count) {
  272. case 0:
  273. case 1:
  274. case 2:
  275. case 3:
  276. case 4:
  277. /* Try same system again if needed */
  278. count++;
  279. break;
  280. case 5:
  281. /* Switch system and reset tries */
  282. count = 1;
  283. system = switch_system(system);
  284. printf ("***Too many boot attempts, switching system***\n");
  285. break;
  286. default:
  287. /* Switch system, start over and hope it works */
  288. printf ("***Unexpected data on addr 0x%x, %u***\n",
  289. (u32) addr, data);
  290. count = 1;
  291. system = switch_system(system);
  292. }
  293. }
  294. write_bootdata (addr + 1, system, count);
  295. }
  296. }
  297. switch(system){
  298. case FAILSAFE_BOOT:
  299. printf ("Booting failsafe system\n");
  300. setenv ("bootargs", "panic=1 root=/dev/hda7");
  301. setenv ("bootcmd", "ide reset;disk 0x81000000 0:5;run addmisc;bootm");
  302. break;
  303. case SYSTEM_BOOT:
  304. printf ("Using normal system\n");
  305. setenv ("bootargs", "panic=1 root=/dev/hda4");
  306. setenv ("bootcmd", "ide reset;disk 0x81000000 0:2;run addmisc;bootm");
  307. break;
  308. case SYSTEM2_BOOT:
  309. printf ("Using normal system2\n");
  310. setenv ("bootargs", "panic=1 root=/dev/hda9");
  311. setenv ("bootcmd", "ide reset;disk 0x81000000 0:8;run addmisc;bootm");
  312. break;
  313. default:
  314. printf ("Invalid system %d\n", system);
  315. printf ("Hanging\n");
  316. while(1);
  317. }
  318. }
  319. int misc_init_r(void){
  320. u8 Rx[80];
  321. u8 Tx[5];
  322. int page;
  323. int read = 0;
  324. WATCHDOG_RESET();
  325. if (ee_init_cpu_data ()) {
  326. printf ("EEPROM init failed\n");
  327. return (0);
  328. }
  329. /* Check which release to boot */
  330. check_boot_tries ();
  331. /* Read the pages where ethernet address is stored */
  332. for (page = EE_USER_PAGE_0; page <= EE_USER_PAGE_0 + 2; page++) {
  333. /* Copy from nvram to scratchpad */
  334. Tx[0] = RECALL_MEMORY;
  335. Tx[1] = page;
  336. if (ee_do_cpu_command (Tx, 2, NULL, 0, 1)) {
  337. printf ("EE user page %d recall failed\n", page);
  338. return (0);
  339. }
  340. Tx[0] = READ_SCRATCHPAD;
  341. if (ee_do_cpu_command (Tx, 2, Rx + read, 9, 1)) {
  342. printf ("EE user page %d read failed\n", page);
  343. return (0);
  344. }
  345. /* Crc in 9:th byte */
  346. if (!ee_crc_ok (Rx + read, 8, *(Rx + read + 8))) {
  347. printf ("EE read failed, page %d. CRC error\n", page);
  348. return (0);
  349. }
  350. read += 8;
  351. }
  352. /* Add eos after eth addr */
  353. Rx[17] = 0;
  354. printf ("Ethernet addr read from eeprom: %s\n\n", Rx);
  355. if ((Rx[2] != ':') |
  356. (Rx[5] != ':') |
  357. (Rx[8] != ':') | (Rx[11] != ':') | (Rx[14] != ':')) {
  358. printf ("*** ethernet addr invalid, using default ***\n");
  359. } else {
  360. setenv ("ethaddr", (char *)Rx);
  361. }
  362. return (0);
  363. }