1/*- 2 * Copyright (c) 2013 Ian Lepore <ian@freebsd.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include "opt_platform.h" 28 29#include <sys/cdefs.h>
| 1/*- 2 * Copyright (c) 2013 Ian Lepore <ian@freebsd.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include "opt_platform.h" 28 29#include <sys/cdefs.h>
|
30__FBSDID("$FreeBSD: head/sys/arm/freescale/imx/imx_machdep.c 257660 2013-11-04 22:45:26Z ian $");
| 30__FBSDID("$FreeBSD: head/sys/arm/freescale/imx/imx_machdep.c 257669 2013-11-05 02:57:34Z ian $");
|
31 32#define _ARM32_BUS_DMA_PRIVATE 33#include <sys/param.h> 34#include <sys/systm.h> 35#include <sys/reboot.h> 36 37#include <vm/vm.h> 38#include <vm/pmap.h> 39 40#include <machine/armreg.h> 41#include <machine/bus.h> 42#include <machine/devmap.h> 43#include <machine/machdep.h> 44 45#include <arm/freescale/imx/imx_machdep.h> 46#include <arm/freescale/imx/imx_wdogreg.h> 47 48#define IMX_MAX_DEVMAP_ENTRIES 8 49 50static struct arm_devmap_entry devmap_entries[IMX_MAX_DEVMAP_ENTRIES]; 51static u_int devmap_idx; 52static vm_offset_t devmap_vaddr = ARM_VECTORS_HIGH; 53 54void 55imx_devmap_addentry(vm_paddr_t pa, vm_size_t sz) 56{ 57 struct arm_devmap_entry *m; 58 59 /* 60 * The last table entry is the all-zeroes end-of-table marker. If we're 61 * about to overwrite it the world is coming to an end. This code runs 62 * too early for the panic to be printed unless a special early-debug 63 * console is in use, but there's nothing else we can do. 64 */ 65 if (devmap_idx == (IMX_MAX_DEVMAP_ENTRIES - 1)) 66 panic("IMX_MAX_DEVMAP_ENTRIES is too small!\n"); 67 68 /* 69 * Allocate virtual address space from the top of kva downwards. If the 70 * range being mapped is aligned and sized to 1MB boundaries then also 71 * align the virtual address to the next-lower 1MB boundary so that we 72 * end up with a section mapping. 73 */ 74 if ((pa & 0x000fffff) == 0 && (sz & 0x000fffff) == 0) { 75 devmap_vaddr = (devmap_vaddr - sz) & ~0x000fffff; 76 } else { 77 devmap_vaddr = (devmap_vaddr - sz) & ~0x00000fff; 78 } 79 m = &devmap_entries[devmap_idx++]; 80 m->pd_va = devmap_vaddr; 81 m->pd_pa = pa; 82 m->pd_size = sz; 83 m->pd_prot = VM_PROT_READ | VM_PROT_WRITE; 84 m->pd_cache = PTE_DEVICE; 85} 86 87vm_offset_t 88initarm_lastaddr(void) 89{ 90
| 31 32#define _ARM32_BUS_DMA_PRIVATE 33#include <sys/param.h> 34#include <sys/systm.h> 35#include <sys/reboot.h> 36 37#include <vm/vm.h> 38#include <vm/pmap.h> 39 40#include <machine/armreg.h> 41#include <machine/bus.h> 42#include <machine/devmap.h> 43#include <machine/machdep.h> 44 45#include <arm/freescale/imx/imx_machdep.h> 46#include <arm/freescale/imx/imx_wdogreg.h> 47 48#define IMX_MAX_DEVMAP_ENTRIES 8 49 50static struct arm_devmap_entry devmap_entries[IMX_MAX_DEVMAP_ENTRIES]; 51static u_int devmap_idx; 52static vm_offset_t devmap_vaddr = ARM_VECTORS_HIGH; 53 54void 55imx_devmap_addentry(vm_paddr_t pa, vm_size_t sz) 56{ 57 struct arm_devmap_entry *m; 58 59 /* 60 * The last table entry is the all-zeroes end-of-table marker. If we're 61 * about to overwrite it the world is coming to an end. This code runs 62 * too early for the panic to be printed unless a special early-debug 63 * console is in use, but there's nothing else we can do. 64 */ 65 if (devmap_idx == (IMX_MAX_DEVMAP_ENTRIES - 1)) 66 panic("IMX_MAX_DEVMAP_ENTRIES is too small!\n"); 67 68 /* 69 * Allocate virtual address space from the top of kva downwards. If the 70 * range being mapped is aligned and sized to 1MB boundaries then also 71 * align the virtual address to the next-lower 1MB boundary so that we 72 * end up with a section mapping. 73 */ 74 if ((pa & 0x000fffff) == 0 && (sz & 0x000fffff) == 0) { 75 devmap_vaddr = (devmap_vaddr - sz) & ~0x000fffff; 76 } else { 77 devmap_vaddr = (devmap_vaddr - sz) & ~0x00000fff; 78 } 79 m = &devmap_entries[devmap_idx++]; 80 m->pd_va = devmap_vaddr; 81 m->pd_pa = pa; 82 m->pd_size = sz; 83 m->pd_prot = VM_PROT_READ | VM_PROT_WRITE; 84 m->pd_cache = PTE_DEVICE; 85} 86 87vm_offset_t 88initarm_lastaddr(void) 89{ 90
|
| 91 return (devmap_vaddr); 92} 93 94void 95initarm_early_init(void) 96{ 97
|
91 /* XXX - Get rid of this stuff soon. */ 92 boothowto |= RB_VERBOSE|RB_MULTIPLE; 93 bootverbose = 1;
| 98 /* XXX - Get rid of this stuff soon. */ 99 boothowto |= RB_VERBOSE|RB_MULTIPLE; 100 bootverbose = 1;
|
94 95 /* 96 * Normally initarm() calls platform_devmap_init() much later in the 97 * init process to set up static device mappings. To calculate the 98 * highest available kva address we have to do that setup first. It 99 * maps downwards from ARM_VECTORS_HIGH and the last usable kva address 100 * is the point right before the virtual address of the first static 101 * mapping. So go set up the static mapping table now, then we can 102 * return the lowest static devmap vaddr as the end of usable kva. 103 */ 104 imx_devmap_init(); 105 106 arm_devmap_register_table(devmap_entries); 107 108 return (devmap_vaddr);
| |
109} 110 111int
| 101} 102 103int
|
112platform_devmap_init(void)
| 104initarm_devmap_init(void)
|
113{ 114
| 105{ 106
|
115 /* On imx this work is done during initarm_lastaddr(). */
| 107 imx_devmap_init(); 108 arm_devmap_register_table(devmap_entries);
|
116 return (0); 117} 118 119/* 120 * Set initial values of GPIO output ports 121 */ 122void 123initarm_gpio_init(void) 124{ 125 126} 127 128void 129initarm_late_init(void) 130{ 131 struct arm_devmap_entry *m; 132 133 /* 134 * We did the static devmap setup earlier, during initarm_lastaddr(), 135 * but now the console should be working and we can be verbose about 136 * what we did. 137 */ 138 if (bootverbose) { 139 for (m = devmap_entries; m->pd_va != 0; ++m) { 140 printf("Devmap: phys 0x%08x virt 0x%08x size %uK\n", 141 m->pd_pa, m->pd_va, m->pd_size / 1024); 142 } 143 } 144 145 146} 147 148struct arm32_dma_range * 149bus_dma_get_range(void) 150{ 151 152 return (NULL); 153} 154 155int 156bus_dma_get_range_nb(void) 157{ 158 159 return (0); 160} 161 162/* 163 * This code which manipulates the watchdog hardware is here to implement 164 * cpu_reset() because the watchdog is the only way for software to reset the 165 * chip. Why here and not in imx_wdog.c? Because there's no requirement that 166 * the watchdog driver be compiled in, but it's nice to be able to reboot even 167 * if it's not. 168 */ 169void 170imx_wdog_cpu_reset(vm_offset_t wdcr_physaddr) 171{ 172 volatile uint16_t * pcr; 173 174 /* 175 * The deceptively simple write of WDOG_CR_WDE enables the watchdog, 176 * sets the timeout to its minimum value (half a second), and also 177 * clears the SRS bit which results in the SFTW (software-requested 178 * reset) bit being set in the watchdog status register after the reset. 179 * This is how software can distinguish a reset from a wdog timeout. 180 */ 181 if ((pcr = arm_devmap_ptov(wdcr_physaddr, sizeof(*pcr))) == NULL) { 182 printf("cpu_reset() can't find its control register... locking up now."); 183 } else { 184 *pcr = WDOG_CR_WDE; 185 } 186 for (;;) 187 continue; 188} 189 190u_int 191imx_soc_family(void) 192{ 193 return (imx_soc_type() >> IMXSOC_FAMSHIFT); 194} 195 196
| 109 return (0); 110} 111 112/* 113 * Set initial values of GPIO output ports 114 */ 115void 116initarm_gpio_init(void) 117{ 118 119} 120 121void 122initarm_late_init(void) 123{ 124 struct arm_devmap_entry *m; 125 126 /* 127 * We did the static devmap setup earlier, during initarm_lastaddr(), 128 * but now the console should be working and we can be verbose about 129 * what we did. 130 */ 131 if (bootverbose) { 132 for (m = devmap_entries; m->pd_va != 0; ++m) { 133 printf("Devmap: phys 0x%08x virt 0x%08x size %uK\n", 134 m->pd_pa, m->pd_va, m->pd_size / 1024); 135 } 136 } 137 138 139} 140 141struct arm32_dma_range * 142bus_dma_get_range(void) 143{ 144 145 return (NULL); 146} 147 148int 149bus_dma_get_range_nb(void) 150{ 151 152 return (0); 153} 154 155/* 156 * This code which manipulates the watchdog hardware is here to implement 157 * cpu_reset() because the watchdog is the only way for software to reset the 158 * chip. Why here and not in imx_wdog.c? Because there's no requirement that 159 * the watchdog driver be compiled in, but it's nice to be able to reboot even 160 * if it's not. 161 */ 162void 163imx_wdog_cpu_reset(vm_offset_t wdcr_physaddr) 164{ 165 volatile uint16_t * pcr; 166 167 /* 168 * The deceptively simple write of WDOG_CR_WDE enables the watchdog, 169 * sets the timeout to its minimum value (half a second), and also 170 * clears the SRS bit which results in the SFTW (software-requested 171 * reset) bit being set in the watchdog status register after the reset. 172 * This is how software can distinguish a reset from a wdog timeout. 173 */ 174 if ((pcr = arm_devmap_ptov(wdcr_physaddr, sizeof(*pcr))) == NULL) { 175 printf("cpu_reset() can't find its control register... locking up now."); 176 } else { 177 *pcr = WDOG_CR_WDE; 178 } 179 for (;;) 180 continue; 181} 182 183u_int 184imx_soc_family(void) 185{ 186 return (imx_soc_type() >> IMXSOC_FAMSHIFT); 187} 188 189
|