Deleted Added
full compact
imx_machdep.c (257660) imx_machdep.c (257669)
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