Home | History | Annotate | Line # | Download | only in altera
cycv_platform.c revision 1.11.6.1
      1  1.11.6.1       ad /* $NetBSD: cycv_platform.c,v 1.11.6.1 2020/02/29 20:18:17 ad Exp $ */
      2       1.1  aymeric 
      3       1.1  aymeric /* This file is in the public domain. */
      4       1.1  aymeric 
      5       1.1  aymeric #include "arml2cc.h"
      6       1.8  aymeric #include "opt_console.h"
      7       1.1  aymeric #include "opt_multiprocessor.h"
      8       1.1  aymeric 
      9       1.1  aymeric #include <sys/cdefs.h>
     10  1.11.6.1       ad __KERNEL_RCSID(0, "$NetBSD: cycv_platform.c,v 1.11.6.1 2020/02/29 20:18:17 ad Exp $");
     11       1.1  aymeric 
     12       1.1  aymeric #define	_ARM32_BUS_DMA_PRIVATE
     13       1.1  aymeric #include <sys/param.h>
     14       1.1  aymeric #include <sys/bus.h>
     15       1.1  aymeric #include <sys/cpu.h>
     16       1.1  aymeric #include <sys/device.h>
     17       1.1  aymeric 
     18       1.1  aymeric #include <uvm/uvm_extern.h>
     19       1.1  aymeric 
     20       1.3    skrll #include <arm/arm32/machdep.h>
     21       1.3    skrll 
     22       1.1  aymeric #include <arm/altera/cycv_reg.h>
     23       1.1  aymeric #include <arm/altera/cycv_var.h>
     24       1.1  aymeric #include <arm/cortex/a9tmr_var.h>
     25       1.1  aymeric #include <arm/cortex/pl310_var.h>
     26       1.1  aymeric #include <arm/cortex/scu_reg.h>
     27       1.1  aymeric 
     28       1.1  aymeric #include <arm/bootconfig.h>
     29       1.1  aymeric #include <arm/cpufunc.h>
     30       1.1  aymeric 
     31       1.1  aymeric #include <arm/fdt/arm_fdtvar.h>
     32       1.1  aymeric #include <dev/fdt/fdtvar.h>
     33       1.8  aymeric #include <dev/ic/comreg.h>
     34       1.1  aymeric 
     35       1.6    skrll void cycv_platform_early_putchar(char);
     36       1.6    skrll 
     37       1.6    skrll void
     38       1.6    skrll cycv_platform_early_putchar(char c) {
     39       1.6    skrll #ifdef CONSADDR
     40       1.6    skrll #define CONSADDR_VA (CONSADDR - CYCV_PERIPHERAL_BASE + CYCV_PERIPHERAL_VBASE)
     41       1.8  aymeric 	volatile uint32_t *uartaddr = cpu_earlydevice_va_p() ?
     42       1.8  aymeric 	    (volatile uint32_t *) CONSADDR_VA :
     43       1.8  aymeric 	    (volatile uint32_t *) CONSADDR;
     44       1.6    skrll 
     45       1.6    skrll 	while ((le32toh(uartaddr[com_lsr]) & LSR_TXRDY) == 0)
     46       1.6    skrll 		;
     47       1.6    skrll 
     48       1.6    skrll 	uartaddr[com_data] = htole32(c);
     49       1.6    skrll #endif
     50       1.6    skrll }
     51       1.1  aymeric 
     52       1.1  aymeric static const struct pmap_devmap *
     53       1.1  aymeric cycv_platform_devmap(void) {
     54       1.1  aymeric 	static const struct pmap_devmap devmap[] = {
     55       1.1  aymeric 		DEVMAP_ENTRY(CYCV_PERIPHERAL_VBASE,
     56       1.1  aymeric 				CYCV_PERIPHERAL_BASE,
     57       1.1  aymeric 				CYCV_PERIPHERAL_SIZE),
     58       1.1  aymeric 		DEVMAP_ENTRY_END
     59       1.1  aymeric 	};
     60       1.1  aymeric 
     61       1.1  aymeric 	return devmap;
     62       1.1  aymeric }
     63       1.1  aymeric 
     64       1.3    skrll static void
     65       1.3    skrll cycv_platform_bootstrap(void)
     66       1.3    skrll {
     67       1.3    skrll 	bus_space_tag_t bst = &armv7_generic_bs_tag;
     68       1.3    skrll 	bus_space_handle_t bsh_l2c;
     69       1.3    skrll 
     70       1.3    skrll 	bus_space_map(bst, CYCV_L2CACHE_BASE, CYCV_L2CACHE_SIZE, 0, &bsh_l2c);
     71       1.3    skrll 
     72       1.3    skrll #if NARML2CC > 0
     73       1.3    skrll 	arml2cc_init(bst, bsh_l2c, 0);
     74       1.3    skrll #endif
     75       1.9  aymeric 
     76       1.9  aymeric 	arm_fdt_cpu_bootstrap();
     77       1.3    skrll }
     78       1.1  aymeric 
     79      1.10    skrll static int
     80       1.3    skrll cycv_mpstart(void)
     81       1.3    skrll {
     82       1.1  aymeric 	bus_space_tag_t bst = &armv7_generic_bs_tag;
     83       1.1  aymeric 	bus_space_handle_t bsh_rst;
     84       1.1  aymeric 	bus_space_handle_t bsh_scu;
     85      1.10    skrll 	int ret = 0;
     86       1.1  aymeric 
     87       1.1  aymeric 	bus_space_map(bst, CYCV_RSTMGR_BASE, CYCV_RSTMGR_SIZE, 0, &bsh_rst);
     88       1.1  aymeric 	bus_space_map(bst, CYCV_SCU_BASE, CYCV_SCU_SIZE, 0, &bsh_scu);
     89       1.1  aymeric 
     90       1.1  aymeric 	/* Enable Snoop Control Unit */
     91       1.7  aymeric 	bus_space_write_4(bst, bsh_scu, SCU_INV_ALL_REG, 0xff);
     92       1.7  aymeric 	bus_space_write_4(bst, bsh_scu, SCU_CTL,
     93       1.7  aymeric 		bus_space_read_4(bst, bsh_scu, SCU_CTL) | SCU_CTL_SCU_ENA);
     94       1.1  aymeric 
     95      1.11  aymeric 	const uint32_t startfunc =
     96      1.11  aymeric 		(uint32_t) KERN_VTOPHYS((vaddr_t) cpu_mpstart);
     97       1.1  aymeric 
     98       1.1  aymeric 	/*
     99      1.11  aymeric 	 * We place a "LDR PC, =cpu_mpstart" at address 0 in order to bootstrap
    100       1.1  aymeric 	 * CPU 1. We can't use the similar feature of the Boot ROM because
    101      1.11  aymeric 	 * it was unmapped by u-boot in favor of the SDRAM.
    102       1.1  aymeric 	 */
    103       1.5  aymeric 	pmap_map_chunk(kernel_l1pt.pv_va, CYCV_SDRAM_VBASE, CYCV_SDRAM_BASE,
    104       1.5  aymeric 		L1_S_SIZE, VM_PROT_READ|VM_PROT_WRITE, PMAP_NOCACHE);
    105      1.11  aymeric 
    106      1.11  aymeric 	/* 0: LDR PC, [PC, #0x18] -> loads address at 0x20 into PC */
    107      1.11  aymeric 	*(volatile uint32_t *) CYCV_SDRAM_VBASE = htole32(0xe59ff018);
    108      1.11  aymeric 	*(volatile uint32_t *) (CYCV_SDRAM_VBASE + 0x20) = startfunc;
    109      1.11  aymeric 
    110       1.5  aymeric 	pmap_unmap_chunk(kernel_l1pt.pv_va, CYCV_SDRAM_VBASE, L1_S_SIZE);
    111       1.1  aymeric 
    112       1.1  aymeric 	bus_space_write_4(bst, bsh_rst, CYCV_RSTMGR_MPUMODRST,
    113       1.1  aymeric 		bus_space_read_4(bst, bsh_rst, CYCV_RSTMGR_MPUMODRST) &
    114       1.1  aymeric 			~CYCV_RSTMGR_MPUMODRST_CPU1);
    115       1.9  aymeric 
    116       1.9  aymeric 	/* Wait for secondary processor to start */
    117      1.10    skrll 	int i;
    118      1.10    skrll 	for (i = 0x10000000; i > 0; i--) {
    119       1.9  aymeric 		membar_consumer();
    120  1.11.6.1       ad 		if (cpu_hatched_p(1))
    121       1.9  aymeric 			break;
    122       1.9  aymeric 	}
    123      1.10    skrll 	if (i == 0) {
    124      1.10    skrll 		aprint_error("cpu%d: WARNING: AP failed to start\n", 1);
    125      1.10    skrll 		ret++;
    126      1.10    skrll 	}
    127      1.10    skrll 
    128      1.10    skrll 	return ret;
    129       1.1  aymeric }
    130       1.1  aymeric 
    131       1.1  aymeric static void
    132       1.1  aymeric cycv_platform_init_attach_args(struct fdt_attach_args *faa) {
    133       1.1  aymeric 	faa->faa_bst = &armv7_generic_bs_tag;
    134       1.1  aymeric 	faa->faa_a4x_bst = &armv7_generic_a4x_bs_tag;
    135       1.1  aymeric 	faa->faa_dmat = &arm_generic_dma_tag;
    136       1.1  aymeric }
    137       1.1  aymeric 
    138       1.1  aymeric static void
    139       1.1  aymeric cycv_platform_device_register(device_t dev, void *aux) {
    140       1.1  aymeric 	prop_dictionary_t dict = device_properties(dev);
    141       1.1  aymeric 
    142       1.1  aymeric 	if (device_is_a(dev, "arma9tmr")) {
    143       1.1  aymeric 		prop_dictionary_set_uint32(dict, "frequency",
    144       1.1  aymeric 			cycv_clkmgr_early_get_mpu_clk() / 4);
    145       1.1  aymeric 	}
    146       1.1  aymeric }
    147       1.1  aymeric 
    148       1.1  aymeric static void
    149       1.1  aymeric cycv_platform_reset(void) {
    150       1.1  aymeric 	bus_space_tag_t bst = &armv7_generic_bs_tag;
    151       1.1  aymeric 	bus_space_handle_t bsh;
    152       1.1  aymeric 	uint32_t val;
    153       1.1  aymeric 
    154       1.1  aymeric 	bus_space_map(bst, CYCV_RSTMGR_BASE, CYCV_RSTMGR_SIZE, 0, &bsh);
    155       1.1  aymeric 	val = bus_space_read_4(bst, bsh, CYCV_RSTMGR_CTRL);
    156       1.1  aymeric 	bus_space_write_4(bst, bsh, CYCV_RSTMGR_CTRL,
    157       1.1  aymeric 		val | CYCV_RSTMGR_CTRL_SWCOLDRSTREQ);
    158       1.1  aymeric }
    159       1.1  aymeric 
    160       1.1  aymeric static u_int
    161       1.1  aymeric cycv_platform_uart_freq(void) {
    162       1.1  aymeric 	return cycv_clkmgr_early_get_l4_sp_clk();
    163       1.1  aymeric }
    164       1.1  aymeric 
    165       1.1  aymeric static const struct arm_platform cycv_platform = {
    166       1.1  aymeric 	.ap_devmap = cycv_platform_devmap,
    167       1.1  aymeric 	.ap_bootstrap = cycv_platform_bootstrap,
    168       1.1  aymeric 	.ap_init_attach_args = cycv_platform_init_attach_args,
    169       1.1  aymeric 	.ap_device_register = cycv_platform_device_register,
    170       1.1  aymeric 	.ap_reset = cycv_platform_reset,
    171       1.1  aymeric 	.ap_delay = a9tmr_delay,
    172       1.1  aymeric 	.ap_uart_freq = cycv_platform_uart_freq,
    173       1.3    skrll 	.ap_mpstart = cycv_mpstart,
    174       1.1  aymeric };
    175       1.1  aymeric 
    176       1.1  aymeric ARM_PLATFORM(cycv, "altr,socfpga-cyclone5", &cycv_platform);
    177