diff options
Diffstat (limited to 'sys/mips/broadcom')
-rw-r--r-- | sys/mips/broadcom/bcm_machdep.c | 81 | ||||
-rw-r--r-- | sys/mips/broadcom/bcm_socinfo.c | 25 | ||||
-rw-r--r-- | sys/mips/broadcom/bcm_socinfo.h | 7 | ||||
-rw-r--r-- | sys/mips/broadcom/std.broadcom | 4 | ||||
-rw-r--r-- | sys/mips/broadcom/uart_cpu_chipc.c | 63 |
5 files changed, 132 insertions, 48 deletions
diff --git a/sys/mips/broadcom/bcm_machdep.c b/sys/mips/broadcom/bcm_machdep.c index d535db3..9cba6f2 100644 --- a/sys/mips/broadcom/bcm_machdep.c +++ b/sys/mips/broadcom/bcm_machdep.c @@ -71,7 +71,6 @@ __FBSDID("$FreeBSD$"); #include <machine/trap.h> #include <machine/vmparam.h> -#include <mips/sentry5/s5reg.h> #include "bcm_socinfo.h" #ifdef CFE @@ -79,7 +78,9 @@ __FBSDID("$FreeBSD$"); #endif #if 0 -#define BROADCOM_TRACE 0 +#define BCM_TRACE(_fmt, ...) printf(_fmt, ##__VA_ARGS__) +#else +#define BCM_TRACE(_fmt, ...) #endif extern int *edata; @@ -109,16 +110,12 @@ mips_init(void) result = cfe_enummem(i / 2, 0, &addr, &len, &type); if (result < 0) { -#ifdef BROADCOM_TRACE - printf("There is no phys memory for: %d\n", i); -#endif + BCM_TRACE("There is no phys memory for: %d\n", i); phys_avail[i] = phys_avail[i + 1] = 0; break; } - if (type != CFE_MI_AVAILABLE){ -#ifdef BROADCOM_TRACE - printf("phys memory is not available: %d\n", i); -#endif + if (type != CFE_MI_AVAILABLE) { + BCM_TRACE("phys memory is not available: %d\n", i); continue; } @@ -131,19 +128,16 @@ mips_init(void) */ phys_avail[i] += MIPS_KSEG0_TO_PHYS(kernel_kseg0_end); } -#ifdef BROADCOM_TRACE - printf("phys memory is available for: %d\n", i); - printf(" => addr = %jx\n", addr); - printf(" => len = %jd\n", len); -#endif + + BCM_TRACE("phys memory is available for: %d\n", i); + BCM_TRACE(" => addr = %jx\n", addr); + BCM_TRACE(" => len = %jd\n", len); + phys_avail[i + 1] = addr + len; physmem += len; } -#ifdef BROADCOM_TRACE - printf("Total phys memory is : %ld\n", physmem); -#endif - + BCM_TRACE("Total phys memory is : %ld\n", physmem); realmem = btoc(physmem); #endif @@ -165,15 +159,25 @@ mips_init(void) #endif } -#define BCM_REG_CHIPC 0x18000000 - - void platform_reset(void) { printf("bcm::platform_reset()\n"); intr_disable(); + +#if defined(CFE) + cfe_exit(0, 0); +#else + /* PMU watchdog reset */ BCM_WRITE_REG32(BCM_REG_CHIPC_PMUWD_OFFS, 2); /* PMU watchdog */ +#endif + +#if 0 + /* Non-PMU reset + * XXX: Need chipc capability flags */ + *((volatile uint8_t *)MIPS_PHYS_TO_KSEG1(SENTRY5_EXTIFADR)) = 0x80; +#endif + for (;;); } @@ -194,6 +198,37 @@ platform_start(__register_t a0, __register_t a1, __register_t a2, /* Initialize pcpu stuff */ mips_pcpu0_init(); +#if 0 + /* + * Probe the Broadcom on-chip PLL clock registers + * and discover the CPU pipeline clock and bus clock + * multipliers from this. + * XXX: Wrong place. You have to ask the ChipCommon + * or External Interface cores on the SiBa. + */ + uint32_t busmult, cpumult, refclock, clkcfg1; +#define S5_CLKCFG1_REFCLOCK_MASK 0x0000001F +#define S5_CLKCFG1_BUSMULT_MASK 0x000003E0 +#define S5_CLKCFG1_BUSMULT_SHIFT 5 +#define S5_CLKCFG1_CPUMULT_MASK 0xFFFFFC00 +#define S5_CLKCFG1_CPUMULT_SHIFT 10 + + counter_freq = 100000000; /* XXX */ + + clkcfg1 = s5_rd_clkcfg1(); + printf("clkcfg1 = 0x%08x\n", clkcfg1); + + refclock = clkcfg1 & 0x1F; + busmult = ((clkcfg1 & 0x000003E0) >> 5) + 1; + cpumult = ((clkcfg1 & 0xFFFFFC00) >> 10) + 1; + + printf("refclock = %u\n", refclock); + printf("busmult = %u\n", busmult); + printf("cpumult = %u\n", cpumult); + + counter_freq = cpumult * refclock; +#endif + socinfo = bcm_get_socinfo(); platform_counter_freq = socinfo->cpurate * 1000 * 1000; /* BCM4718 is 480MHz */ @@ -212,10 +247,10 @@ platform_start(__register_t a0, __register_t a1, __register_t a2, if (a3 == CFE_EPTSEAL) cfe_init(a0, a2); #endif + cninit(); mips_init(); - /* BCM471x timer is 1/2 of Clk */ - mips_timer_init_params(platform_counter_freq, 1); + mips_timer_init_params(platform_counter_freq, socinfo->double_count); } diff --git a/sys/mips/broadcom/bcm_socinfo.c b/sys/mips/broadcom/bcm_socinfo.c index 7e5fa04..9ea41a1 100644 --- a/sys/mips/broadcom/bcm_socinfo.c +++ b/sys/mips/broadcom/bcm_socinfo.c @@ -33,22 +33,23 @@ __FBSDID("$FreeBSD$"); /* found on https://wireless.wiki.kernel.org/en/users/drivers/b43/soc */ struct bcm_socinfo bcm_socinfos[] = { - {0x00005300, 600, 25000000}, /* BCM4706 to check */ - {0x0022B83A, 300, 20000000}, /* BCM4716B0 ASUS RT-N12 */ - {0x00914716, 354, 20000000}, /* BCM4717A1 to check */ - {0x00A14716, 480, 20000000}, /* BCM4718A1 ASUS RT-N16 */ - {0x00435356, 300, 25000000}, /* BCM5356A1 (RT-N10, WNR1000v3) */ - {0x00825357, 500, 20000000}, /* BCM5358UB0 ASUS RT-N53A1 */ - {0x00845357, 300, 20000000}, /* BCM5357B0 to check */ - {0x00945357, 500, 20000000}, /* BCM5358 */ - {0x00A45357, 500, 20000000}, /* BCM47186B0 Tenda N60 */ - {0x0085D144, 300, 20000000}, /* BCM5356C0 */ - {0x00B5D144, 300, 20000000}, /* BCM5357C0 */ + {0x00005300, 600, 25000000, 1}, /* BCM4706 to check */ + {0x0022B83A, 300, 20000000, 1}, /* BCM4716B0 ASUS RT-N12 */ + {0x00914716, 354, 20000000, 1}, /* BCM4717A1 to check */ + {0x00A14716, 480, 20000000, 1}, /* BCM4718A1 ASUS RT-N16 */ + {0x00435356, 300, 25000000, 1}, /* BCM5356A1 (RT-N10, WNR1000v3) */ + {0x00825357, 500, 20000000, 1}, /* BCM5358UB0 ASUS RT-N53A1 */ + {0x00845357, 300, 20000000, 1}, /* BCM5357B0 to check */ + {0x00945357, 500, 20000000, 1}, /* BCM5358 */ + {0x00A45357, 500, 20000000, 1}, /* BCM47186B0 Tenda N60 */ + {0x0085D144, 300, 20000000, 1}, /* BCM5356C0 */ + {0x00B5D144, 300, 20000000, 1}, /* BCM5357C0 */ + {0x00015365, 200, 0, 1}, /* BCM5365 */ {0,0,0} }; /* Most popular BCM SoC info */ -struct bcm_socinfo BCM_DEFAULT_SOCINFO = {0x0, 300, 20000000}; +struct bcm_socinfo BCM_DEFAULT_SOCINFO = {0x0, 300, 20000000, 0}; struct bcm_socinfo* bcm_get_socinfo_by_socid(uint32_t key) diff --git a/sys/mips/broadcom/bcm_socinfo.h b/sys/mips/broadcom/bcm_socinfo.h index adf4124..cdac486 100644 --- a/sys/mips/broadcom/bcm_socinfo.h +++ b/sys/mips/broadcom/bcm_socinfo.h @@ -35,9 +35,10 @@ #include <machine/cpuregs.h> struct bcm_socinfo { - uint32_t id; - uint32_t cpurate; /* in MHz */ - uint32_t uartrate; /* in Hz */ + uint32_t id; + uint32_t cpurate; /* in MHz */ + uint32_t uartrate; /* in Hz */ + int double_count; }; struct bcm_socinfo* bcm_get_socinfo_by_socid(uint32_t key); diff --git a/sys/mips/broadcom/std.broadcom b/sys/mips/broadcom/std.broadcom index 448a094..68aa974 100644 --- a/sys/mips/broadcom/std.broadcom +++ b/sys/mips/broadcom/std.broadcom @@ -3,5 +3,7 @@ machine mips mipsel -cpu CPU_MIPS74K +makeoptions INTRNG +options INTRNG + files "../broadcom/files.broadcom" diff --git a/sys/mips/broadcom/uart_cpu_chipc.c b/sys/mips/broadcom/uart_cpu_chipc.c index 14cc9f3..9b91a2b 100644 --- a/sys/mips/broadcom/uart_cpu_chipc.c +++ b/sys/mips/broadcom/uart_cpu_chipc.c @@ -39,6 +39,8 @@ __FBSDID("$FreeBSD$"); #include <machine/bus.h> +#include <dev/bhnd/cores/chipc/chipcreg.h> + #include <dev/uart/uart.h> #include <dev/uart/uart_bus.h> #include <dev/uart/uart_cpu.h> @@ -48,31 +50,74 @@ __FBSDID("$FreeBSD$"); bus_space_tag_t uart_bus_space_io; bus_space_tag_t uart_bus_space_mem; +static struct uart_class *chipc_uart_class = &uart_ns8250_class; + +#define CHIPC_UART_BAUDRATE 115200 + int uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2) { return ((b1->bsh == b2->bsh && b1->bst == b2->bst) ? 1 : 0); } -int -uart_cpu_getdev(int devtype, struct uart_devinfo *di) +static int +uart_cpu_init(struct uart_devinfo *di, int uart, int baudrate) { - struct uart_class *class; struct bcm_socinfo *socinfo; + if (uart >= CHIPC_UART_MAX) + return (EINVAL); + socinfo = bcm_get_socinfo(); - class = &uart_ns8250_class; - di->ops = uart_getops(class); + di->ops = uart_getops(chipc_uart_class); di->bas.chan = 0; - di->bas.bst = mips_bus_space_generic; - di->bas.bsh = (bus_space_handle_t)BCM_SOCREG(BCM_REG_CHIPC_UART); + di->bas.bst = uart_bus_space_mem; + di->bas.bsh = (bus_space_handle_t) BCM_SOCREG(CHIPC_UART(uart)); di->bas.regshft = 0; di->bas.rclk = socinfo->uartrate; /* in Hz */ - di->baudrate = 115200; + di->baudrate = baudrate; di->databits = 8; di->stopbits = 1; di->parity = UART_PARITY_NONE; + + return (0); +} + +int +uart_cpu_getdev(int devtype, struct uart_devinfo *di) +{ + int ivar; + uart_bus_space_io = NULL; uart_bus_space_mem = mips_bus_space_generic; - return (0); + + /* Check the environment. */ + if (uart_getenv(devtype, di, chipc_uart_class) == 0) + return (0); + + /* Scan the device hints for the first matching device */ + for (int i = 0; i < CHIPC_UART_MAX; i++) { + if (resource_int_value("uart", i, "flags", &ivar)) + continue; + + /* Check usability */ + if (devtype == UART_DEV_CONSOLE && !UART_FLAGS_CONSOLE(ivar)) + continue; + + if (devtype == UART_DEV_DBGPORT && !UART_FLAGS_DBGPORT(ivar)) + continue; + + if (resource_int_value("uart", i, "disabled", &ivar) == 0 && + ivar == 0) + continue; + + /* Found */ + if (resource_int_value("uart", i, "baud", &ivar) != 0) + ivar = CHIPC_UART_BAUDRATE; + + return (uart_cpu_init(di, i, ivar)); + } + + /* Default to uart0/115200 */ + return (uart_cpu_init(di, 0, CHIPC_UART_BAUDRATE)); } |