Module Name: src Committed By: jmcneill Date: Sun Apr 26 22:04:28 UTC 2015
Modified Files: src/sys/arch/arm/nvidia: soc_tegra124.c tegra_pmc.c tegra_pmcreg.h tegra_reg.h tegra_soc.c tegra_var.h src/sys/arch/evbarm/tegra: tegra_machdep.c tegra_start.S Log Message: add Tegra124 MP support To generate a diff of this commit: cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/nvidia/soc_tegra124.c \ src/sys/arch/arm/nvidia/tegra_pmcreg.h cvs rdiff -u -r1.2 -r1.3 src/sys/arch/arm/nvidia/tegra_pmc.c \ src/sys/arch/arm/nvidia/tegra_reg.h src/sys/arch/arm/nvidia/tegra_soc.c \ src/sys/arch/arm/nvidia/tegra_var.h cvs rdiff -u -r1.5 -r1.6 src/sys/arch/evbarm/tegra/tegra_machdep.c cvs rdiff -u -r1.2 -r1.3 src/sys/arch/evbarm/tegra/tegra_start.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/nvidia/soc_tegra124.c diff -u src/sys/arch/arm/nvidia/soc_tegra124.c:1.1 src/sys/arch/arm/nvidia/soc_tegra124.c:1.2 --- src/sys/arch/arm/nvidia/soc_tegra124.c:1.1 Sun Mar 29 10:41:59 2015 +++ src/sys/arch/arm/nvidia/soc_tegra124.c Sun Apr 26 22:04:28 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: soc_tegra124.c,v 1.1 2015/03/29 10:41:59 jmcneill Exp $ */ +/* $NetBSD: soc_tegra124.c,v 1.2 2015/04/26 22:04:28 jmcneill Exp $ */ /*- * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca> @@ -30,7 +30,7 @@ #include "opt_multiprocessor.h" #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: soc_tegra124.c,v 1.1 2015/03/29 10:41:59 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: soc_tegra124.c,v 1.2 2015/04/26 22:04:28 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -42,16 +42,38 @@ __KERNEL_RCSID(0, "$NetBSD: soc_tegra124 #include <arm/cpufunc.h> #include <arm/nvidia/tegra_reg.h> +#include <arm/nvidia/tegra_pmcreg.h> #include <arm/nvidia/tegra_var.h> +#define EVP_RESET_VECTOR_0_REG 0x100 + void tegra124_mpinit(void) { #if defined(MULTIPROCESSOR) extern void cortex_mpstart(void); + bus_space_tag_t bst = &armv7_generic_bs_tag; + bus_space_handle_t bsh; + u_int i; + + bus_space_subregion(bst, tegra_ppsb_bsh, + TEGRA_EVP_OFFSET, TEGRA_EVP_SIZE, &bsh); arm_cpu_max = 1 + __SHIFTOUT(armreg_l2ctrl_read(), L2CTRL_NUMCPU); + KASSERT(arm_cpu_max == 4); - /* TODO */ + bus_space_write_4(bst, bsh, EVP_RESET_VECTOR_0_REG, (uint32_t)cortex_mpstart); + bus_space_barrier(bst, bsh, EVP_RESET_VECTOR_0_REG, 4, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); + + tegra_pmc_power(PMC_PARTID_CPU1, true); + tegra_pmc_power(PMC_PARTID_CPU2, true); + tegra_pmc_power(PMC_PARTID_CPU3, true); + + for (i = 0x10000000; i > 0; i--) { + __asm __volatile("dmb" ::: "memory"); + if (arm_cpu_hatched == 0xe) + break; + } #endif } Index: src/sys/arch/arm/nvidia/tegra_pmcreg.h diff -u src/sys/arch/arm/nvidia/tegra_pmcreg.h:1.1 src/sys/arch/arm/nvidia/tegra_pmcreg.h:1.2 --- src/sys/arch/arm/nvidia/tegra_pmcreg.h:1.1 Sun Mar 29 10:41:59 2015 +++ src/sys/arch/arm/nvidia/tegra_pmcreg.h Sun Apr 26 22:04:28 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: tegra_pmcreg.h,v 1.1 2015/03/29 10:41:59 jmcneill Exp $ */ +/* $NetBSD: tegra_pmcreg.h,v 1.2 2015/04/26 22:04:28 jmcneill Exp $ */ /*- * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca> @@ -53,4 +53,36 @@ #define PMC_CNTRL_0_RTC_CLK_DIS __BIT(1) #define PMC_CNTRL_0_KBC_CLK_DIS __BIT(0) +#define PMC_PWRGATE_TOGGLE_0_REG 0x30 + +#define PMC_PWRGATE_TOGGLE_0_START __BIT(8) +#define PMC_PWRGATE_TOGGLE_0_PARTID __BITS(4,0) + +#define PMC_PWRGATE_STATUS_0_REG 0x38 + +#define PMC_PARTID_IRAM 24 +#define PMC_PARTID_VIC 23 +#define PMC_PARTID_XUSBC 22 +#define PMC_PARTID_XUSBB 21 +#define PMC_PARTID_XUSBA 20 +#define PMC_PARTID_DISB 19 +#define PMC_PARTID_DIS 18 +#define PMC_PARTID_SOR 17 +#define PMC_PARTID_C1NC 16 +#define PMC_PARTID_C0NC 15 +#define PMC_PARTID_CE0 14 +#define PMC_PARTID_A9LP 12 +#define PMC_PARTID_CPU3 11 +#define PMC_PARTID_CPU2 10 +#define PMC_PARTID_CPU1 9 +#define PMC_PARTID_SAX 8 +#define PMC_PARTID_HEG 7 +#define PMC_PARTID_MPE 6 +#define PMC_PARTID_L2C 5 +#define PMC_PARTID_VDE 4 +#define PMC_PARTID_PCX 3 +#define PMC_PARTID_VE 2 +#define PMC_PARTID_TD 1 +#define PMC_PARTID_CPU0 0 + #endif /* _ARM_TEGRA_PMCREG_H */ Index: src/sys/arch/arm/nvidia/tegra_pmc.c diff -u src/sys/arch/arm/nvidia/tegra_pmc.c:1.2 src/sys/arch/arm/nvidia/tegra_pmc.c:1.3 --- src/sys/arch/arm/nvidia/tegra_pmc.c:1.2 Sun Mar 29 22:27:04 2015 +++ src/sys/arch/arm/nvidia/tegra_pmc.c Sun Apr 26 22:04:28 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: tegra_pmc.c,v 1.2 2015/03/29 22:27:04 jmcneill Exp $ */ +/* $NetBSD: tegra_pmc.c,v 1.3 2015/04/26 22:04:28 jmcneill Exp $ */ /*- * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca> @@ -29,7 +29,7 @@ #include "locators.h" #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: tegra_pmc.c,v 1.2 2015/03/29 22:27:04 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tegra_pmc.c,v 1.3 2015/04/26 22:04:28 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -81,6 +81,19 @@ tegra_pmc_attach(device_t parent, device aprint_normal(": PMC\n"); } +static void +tegra_pmc_get_bs(bus_space_tag_t *pbst, bus_space_handle_t *pbsh) +{ + if (pmc_softc) { + *pbst = pmc_softc->sc_bst; + *pbsh = pmc_softc->sc_bsh; + } else { + *pbst = &armv7_generic_bs_tag; + bus_space_subregion(*pbst, tegra_apb_bsh, + TEGRA_PMC_OFFSET, TEGRA_PMC_SIZE, pbsh); + } +} + void tegra_pmc_reset(void) { @@ -88,14 +101,7 @@ tegra_pmc_reset(void) bus_space_handle_t bsh; uint32_t cntrl; - if (pmc_softc) { - bst = pmc_softc->sc_bst; - bsh = pmc_softc->sc_bsh; - } else { - bst = &armv7_generic_bs_tag; - bus_space_subregion(bst, tegra_apb_bsh, - TEGRA_PMC_OFFSET, TEGRA_PMC_SIZE, &bsh); - } + tegra_pmc_get_bs(&bst, &bsh); cntrl = bus_space_read_4(bst, bsh, PMC_CNTRL_0_REG); cntrl |= PMC_CNTRL_0_MAIN_RST; @@ -105,3 +111,23 @@ tegra_pmc_reset(void) __asm("wfi"); } } + +void +tegra_pmc_power(u_int partid, bool enable) +{ + bus_space_tag_t bst; + bus_space_handle_t bsh; + uint32_t status; + bool state; + + tegra_pmc_get_bs(&bst, &bsh); + + status = bus_space_read_4(bst, bsh, PMC_PWRGATE_STATUS_0_REG); + state = !!(status & __BIT(partid)); + if (state == enable) + return; + + bus_space_write_4(bst, bsh, PMC_PWRGATE_TOGGLE_0_REG, + __SHIFTIN(partid, PMC_PWRGATE_TOGGLE_0_PARTID) | + PMC_PWRGATE_TOGGLE_0_START); +} Index: src/sys/arch/arm/nvidia/tegra_reg.h diff -u src/sys/arch/arm/nvidia/tegra_reg.h:1.2 src/sys/arch/arm/nvidia/tegra_reg.h:1.3 --- src/sys/arch/arm/nvidia/tegra_reg.h:1.2 Sun Apr 26 16:24:01 2015 +++ src/sys/arch/arm/nvidia/tegra_reg.h Sun Apr 26 22:04:28 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: tegra_reg.h,v 1.2 2015/04/26 16:24:01 jmcneill Exp $ */ +/* $NetBSD: tegra_reg.h,v 1.3 2015/04/26 22:04:28 jmcneill Exp $ */ /*- * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca> @@ -42,7 +42,8 @@ #define TEGRA_AHB_A2_BASE 0x7c000000 #define TEGRA_AHB_A2_SIZE 0x02000000 -#define TEGRA_HOST1X_VBASE 0xfb000000 +#define TEGRA_HOST1X_VBASE 0xfaf00000 +#define TEGRA_PPSB_VBASE 0xfb000000 #define TEGRA_APB_VBASE 0xfc000000 #define TEGRA_AHB_A2_VBASE 0xfd000000 @@ -85,6 +86,10 @@ #define TEGRA_XUSB_DEV_OFFSET 0x000d0000 #define TEGRA_XUSB_DEV_SIZE 0xa000 +/* PPSB */ +#define TEGRA_EVP_OFFSET 0x0000f000 +#define TEGRA_EVP_SIZE 0x1000 + /* AHB_A2 */ #define TEGRA_USB1_OFFSET 0x01000000 #define TEGRA_USB1_SIZE 0x1800 Index: src/sys/arch/arm/nvidia/tegra_soc.c diff -u src/sys/arch/arm/nvidia/tegra_soc.c:1.2 src/sys/arch/arm/nvidia/tegra_soc.c:1.3 --- src/sys/arch/arm/nvidia/tegra_soc.c:1.2 Sun Mar 29 22:27:04 2015 +++ src/sys/arch/arm/nvidia/tegra_soc.c Sun Apr 26 22:04:28 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: tegra_soc.c,v 1.2 2015/03/29 22:27:04 jmcneill Exp $ */ +/* $NetBSD: tegra_soc.c,v 1.3 2015/04/26 22:04:28 jmcneill Exp $ */ /*- * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca> @@ -30,7 +30,7 @@ #include "opt_multiprocessor.h" #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: tegra_soc.c,v 1.2 2015/03/29 22:27:04 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tegra_soc.c,v 1.3 2015/04/26 22:04:28 jmcneill Exp $"); #define _ARM32_BUS_DMA_PRIVATE #include <sys/param.h> @@ -49,6 +49,7 @@ __KERNEL_RCSID(0, "$NetBSD: tegra_soc.c, #include <arm/nvidia/tegra_var.h> bus_space_handle_t tegra_host1x_bsh; +bus_space_handle_t tegra_ppsb_bsh; bus_space_handle_t tegra_apb_bsh; bus_space_handle_t tegra_ahb_a2_bsh; @@ -58,34 +59,37 @@ struct arm32_bus_dma_tag tegra_dma_tag = _BUS_DMATAG_FUNCS, }; -#if defined(MULTIPROCESSOR) static void tegra_mpinit(void); -#endif void tegra_bootstrap(void) { - bus_space_map(&armv7_generic_bs_tag, + if (bus_space_map(&armv7_generic_bs_tag, TEGRA_HOST1X_BASE, TEGRA_HOST1X_SIZE, 0, - &tegra_host1x_bsh); - bus_space_map(&armv7_generic_bs_tag, + &tegra_host1x_bsh) != 0) + panic("couldn't map HOST1X"); + if (bus_space_map(&armv7_generic_bs_tag, + TEGRA_PPSB_BASE, TEGRA_PPSB_SIZE, 0, + &tegra_ppsb_bsh) != 0) + panic("couldn't map PPSB"); + if (bus_space_map(&armv7_generic_bs_tag, TEGRA_APB_BASE, TEGRA_APB_SIZE, 0, - &tegra_apb_bsh); - bus_space_map(&armv7_generic_bs_tag, + &tegra_apb_bsh) != 0) + panic("couldn't map APB"); + if (bus_space_map(&armv7_generic_bs_tag, TEGRA_AHB_A2_BASE, TEGRA_AHB_A2_SIZE, 0, - &tegra_ahb_a2_bsh); + &tegra_ahb_a2_bsh) != 0) + panic("couldn't map AHB A2"); curcpu()->ci_data.cpu_cc_freq = 696000000; /* XXX */ -#if defined(MULTIPROCESSOR) tegra_mpinit(); -#endif } -#if defined(MULTIPROCESSOR) static void tegra_mpinit(void) { +#if defined(MULTIPROCESSOR) switch (tegra_chip_id()) { #ifdef SOC_TEGRA124 case CHIP_ID_TEGRA124: @@ -95,8 +99,8 @@ tegra_mpinit(void) default: panic("Unsupported SOC ID %#x", tegra_chip_id()); } -} #endif +} u_int tegra_chip_id(void) Index: src/sys/arch/arm/nvidia/tegra_var.h diff -u src/sys/arch/arm/nvidia/tegra_var.h:1.2 src/sys/arch/arm/nvidia/tegra_var.h:1.3 --- src/sys/arch/arm/nvidia/tegra_var.h:1.2 Sun Mar 29 22:27:04 2015 +++ src/sys/arch/arm/nvidia/tegra_var.h Sun Apr 26 22:04:28 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: tegra_var.h,v 1.2 2015/03/29 22:27:04 jmcneill Exp $ */ +/* $NetBSD: tegra_var.h,v 1.3 2015/04/26 22:04:28 jmcneill Exp $ */ /*- * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca> @@ -54,6 +54,7 @@ struct tegraio_attach_args { extern struct bus_space armv7_generic_bs_tag; extern struct bus_space armv7_generic_a4x_bs_tag; extern bus_space_handle_t tegra_host1x_bsh; +extern bus_space_handle_t tegra_ppsb_bsh; extern bus_space_handle_t tegra_apb_bsh; extern bus_space_handle_t tegra_ahb_a2_bsh; extern struct arm32_bus_dma_tag tegra_dma_tag; @@ -69,6 +70,7 @@ const char *tegra_chip_name(void); void tegra_bootstrap(void); void tegra_pmc_reset(void); +void tegra_pmc_power(u_int, bool); psize_t tegra_mc_memsize(void); Index: src/sys/arch/evbarm/tegra/tegra_machdep.c diff -u src/sys/arch/evbarm/tegra/tegra_machdep.c:1.5 src/sys/arch/evbarm/tegra/tegra_machdep.c:1.6 --- src/sys/arch/evbarm/tegra/tegra_machdep.c:1.5 Sun Apr 26 17:40:59 2015 +++ src/sys/arch/evbarm/tegra/tegra_machdep.c Sun Apr 26 22:04:28 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: tegra_machdep.c,v 1.5 2015/04/26 17:40:59 jmcneill Exp $ */ +/* $NetBSD: tegra_machdep.c,v 1.6 2015/04/26 22:04:28 jmcneill Exp $ */ /*- * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: tegra_machdep.c,v 1.5 2015/04/26 17:40:59 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tegra_machdep.c,v 1.6 2015/04/26 22:04:28 jmcneill Exp $"); #include "opt_tegra.h" #include "opt_machdep.h" @@ -116,6 +116,13 @@ static const struct pmap_devmap devmap[] .pd_cache = PTE_NOCACHE }, { + .pd_va = _A(TEGRA_PPSB_VBASE), + .pd_pa = _A(TEGRA_PPSB_BASE), + .pd_size = _S(TEGRA_PPSB_SIZE), + .pd_prot = VM_PROT_READ|VM_PROT_WRITE, + .pd_cache = PTE_NOCACHE + }, + { .pd_va = _A(TEGRA_APB_VBASE), .pd_pa = _A(TEGRA_APB_BASE), .pd_size = _S(TEGRA_APB_SIZE), @@ -194,6 +201,8 @@ tegra_printn(u_int n, int base) #define DPRINTN(x,b) #endif +extern void cortex_mpstart(void); + /* * u_int initarm(...) * @@ -217,6 +226,10 @@ initarm(void *arg) DPRINTN(armreg_sctlr_read(), 16); DPRINT(">"); + DPRINT(" mpstart<0x"); + DPRINTN((uint32_t)cortex_mpstart, 16); + DPRINT(">"); + DPRINT(" devmap"); pmap_devmap_register(devmap); Index: src/sys/arch/evbarm/tegra/tegra_start.S diff -u src/sys/arch/evbarm/tegra/tegra_start.S:1.2 src/sys/arch/evbarm/tegra/tegra_start.S:1.3 --- src/sys/arch/evbarm/tegra/tegra_start.S:1.2 Sat Apr 18 11:03:31 2015 +++ src/sys/arch/evbarm/tegra/tegra_start.S Sun Apr 26 22:04:28 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: tegra_start.S,v 1.2 2015/04/18 11:03:31 skrll Exp $ */ +/* $NetBSD: tegra_start.S,v 1.3 2015/04/26 22:04:28 jmcneill Exp $ */ /*- * Copyright (c) 2014, 2015 The NetBSD Foundation, Inc. @@ -43,7 +43,7 @@ #include <arm/nvidia/tegra_reg.h> #include <evbarm/tegra/platform.h> -RCSID("$NetBSD: tegra_start.S,v 1.2 2015/04/18 11:03:31 skrll Exp $") +RCSID("$NetBSD: tegra_start.S,v 1.3 2015/04/26 22:04:28 jmcneill Exp $") #if defined(VERBOSE_INIT_ARM) #define XPUTC(n) mov r0, n; bl xputc @@ -175,6 +175,16 @@ mmu_init_table: (TEGRA_APB_SIZE + L1_S_SIZE - 1) / L1_S_SIZE, L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_V6_XN) + /* Map PPSB */ + MMU_INIT(TEGRA_PPSB_VBASE, TEGRA_PPSB_BASE, + (TEGRA_PPSB_SIZE + L1_S_SIZE - 1) / L1_S_SIZE, + L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_V6_XN) + + /* Map PPSB */ + MMU_INIT(TEGRA_PPSB_BASE, TEGRA_PPSB_BASE, + (TEGRA_PPSB_SIZE + L1_S_SIZE - 1) / L1_S_SIZE, + L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_V6_XN) + /* end of table */ MMU_INIT(0, 0, 0, 0)