1/* 2 * BCM63XX specific implementation parts 3 * 4 * Copyright (C) 2014 Jonas Gorski <jogo@openwrt.org> 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 as published 8 * by the Free Software Foundation. 9 */ 10 11#include <stddef.h> 12#include "config.h" 13#include "cp0regdef.h" 14 15#define READREG(r) *(volatile unsigned int *)(r) 16#define WRITEREG(r,v) *(volatile unsigned int *)(r) = v 17 18#define UART_IR_REG 0x10 19#define UART_FIFO_REG 0x14 20 21unsigned long uart_base; 22 23static void wait_xfered(void) 24{ 25 unsigned int val; 26 27 do { 28 val = READREG(uart_base + UART_IR_REG); 29 if (val & (1 << 5)) 30 break; 31 } while (1); 32} 33 34void board_putc(int ch) 35{ 36 if (!uart_base) 37 return; 38 39 wait_xfered(); 40 WRITEREG(uart_base + UART_FIFO_REG, ch); 41 wait_xfered(); 42} 43 44#define PRID_IMP_BMIPS32_REV4 0x4000 45#define PRID_IMP_BMIPS32_REV8 0x8000 46#define PRID_IMP_BMIPS3300 0x9000 47#define PRID_IMP_BMIPS3300_ALT 0x9100 48#define PRID_IMP_BMIPS3300_BUG 0x0000 49#define PRID_IMP_BMIPS43XX 0xa000 50 51void board_init(void) 52{ 53 unsigned long prid, chipid, chipid_reg; 54 55 prid = read_32bit_c0_register($15, 0); 56 57 switch (prid & 0xff00) { 58 case PRID_IMP_BMIPS32_REV4: 59 case PRID_IMP_BMIPS32_REV8: 60 case PRID_IMP_BMIPS3300_ALT: 61 case PRID_IMP_BMIPS3300_BUG: 62 chipid_reg = 0xfffe0000; 63 break; 64 case PRID_IMP_BMIPS3300: 65 if ((prid & 0xff) >= 0x33) 66 chipid_reg = 0xb0000000; 67 else 68 chipid_reg = 0xfffe0000; 69 break; 70 case PRID_IMP_BMIPS43XX: 71 if ((prid & 0xff) == 0x04) 72 chipid_reg = 0xfff8c000; 73 else if ((prid & 0xff) == 0x70) 74 chipid_reg = 0xb4e00000; 75 else if ((prid & 0xff) >= 0x30) 76 chipid_reg = 0xb0000000; 77 else 78 chipid_reg = 0xfffe0000; 79 break; 80 default: 81 return; 82 } 83 84 chipid = READREG(chipid_reg); 85 86 switch (chipid >> 16) { 87 case 0x3368: 88 case 0x6318: 89 case 0x6328: 90 case 0x6358: 91 case 0x6362: 92 case 0x6368: 93 case 0x6369: 94 uart_base = chipid_reg + 0x100; 95 break; 96 case 0x6316: 97 case 0x6326: 98 uart_base = chipid_reg + 0x180; 99 break; 100 case 0x3380: 101 uart_base = chipid_reg + 0x200; 102 break; 103 case 0x6338: 104 case 0x6345: 105 case 0x6348: 106 uart_base = chipid_reg + 0x300; 107 break; 108 default: 109 return; 110 } 111} 112