Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/arm/freescale/fsl_ocotp.c
39507 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2014 Steven Lawrance <[email protected]>
5
* All rights reserved.
6
*
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions
9
* are met:
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
* 2. Redistributions in binary form must reproduce the above copyright
13
* notice, this list of conditions and the following disclaimer in the
14
* documentation and/or other materials provided with the distribution.
15
*
16
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
* SUCH DAMAGE.
27
*/
28
29
#include <sys/cdefs.h>
30
/*
31
* Access to the Freescale i.MX6 On-Chip One-Time-Programmable Memory
32
*/
33
34
#include <sys/param.h>
35
#include <sys/systm.h>
36
#include <sys/kernel.h>
37
#include <sys/module.h>
38
#include <sys/bus.h>
39
#include <sys/rman.h>
40
41
#include <dev/ofw/ofw_bus.h>
42
#include <dev/ofw/ofw_bus_subr.h>
43
44
#include <machine/bus.h>
45
46
#include <arm/freescale/fsl_ocotpreg.h>
47
#include <arm/freescale/fsl_ocotpvar.h>
48
49
/*
50
* Find the physical address and size of the ocotp registers and devmap them,
51
* returning a pointer to the virtual address of the base.
52
*
53
* XXX This is temporary until we've worked out all the details of controlling
54
* the load order of devices. In an ideal world this device would be up and
55
* running before anything that needs it. When we're at a point to make that
56
* happen, this little block of code, and the few lines in fsl_ocotp_read_4()
57
* that refer to it can be deleted.
58
*/
59
#include <vm/vm.h>
60
#include <vm/pmap.h>
61
#include <dev/fdt/fdt_common.h>
62
63
static uint32_t *ocotp_regs;
64
static vm_size_t ocotp_size;
65
66
static void
67
fsl_ocotp_devmap(void)
68
{
69
phandle_t child, root;
70
u_long base, size;
71
72
if ((root = OF_finddevice("/")) == -1)
73
goto fatal;
74
if ((child = fdt_depth_search_compatible(root, "fsl,imx6q-ocotp", 0)) == 0)
75
goto fatal;
76
if (fdt_regsize(child, &base, &size) != 0)
77
goto fatal;
78
79
ocotp_size = (vm_size_t)size;
80
81
if ((ocotp_regs = pmap_mapdev((vm_paddr_t)base, ocotp_size)) == NULL)
82
goto fatal;
83
84
return;
85
fatal:
86
panic("cannot find/map the ocotp registers");
87
}
88
/* XXX end of temporary code */
89
90
struct ocotp_softc {
91
device_t dev;
92
struct resource *mem_res;
93
};
94
95
static struct ocotp_softc *ocotp_sc;
96
97
static inline uint32_t
98
RD4(struct ocotp_softc *sc, bus_size_t off)
99
{
100
101
return (bus_read_4(sc->mem_res, off));
102
}
103
104
static int
105
ocotp_detach(device_t dev)
106
{
107
108
/* The ocotp registers are always accessible. */
109
return (EBUSY);
110
}
111
112
static int
113
ocotp_attach(device_t dev)
114
{
115
struct ocotp_softc *sc;
116
int err, rid;
117
118
sc = device_get_softc(dev);
119
sc->dev = dev;
120
121
/* Allocate bus_space resources. */
122
rid = 0;
123
sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
124
RF_ACTIVE);
125
if (sc->mem_res == NULL) {
126
device_printf(dev, "Cannot allocate memory resources\n");
127
err = ENXIO;
128
goto out;
129
}
130
131
ocotp_sc = sc;
132
133
/* We're done with the temporary mapping now. */
134
if (ocotp_regs != NULL)
135
pmap_unmapdev(ocotp_regs, ocotp_size);
136
137
err = 0;
138
139
out:
140
if (err != 0)
141
ocotp_detach(dev);
142
143
return (err);
144
}
145
146
static int
147
ocotp_probe(device_t dev)
148
{
149
150
if (!ofw_bus_status_okay(dev))
151
return (ENXIO);
152
153
if (ofw_bus_is_compatible(dev, "fsl,imx6q-ocotp") == 0)
154
return (ENXIO);
155
156
device_set_desc(dev,
157
"Freescale On-Chip One-Time-Programmable Memory");
158
159
return (BUS_PROBE_DEFAULT);
160
}
161
162
uint32_t
163
fsl_ocotp_read_4(bus_size_t off)
164
{
165
166
if (off > FSL_OCOTP_LAST_REG)
167
panic("fsl_ocotp_read_4: offset out of range");
168
169
/* If we have a softcontext use the regular bus_space read. */
170
if (ocotp_sc != NULL)
171
return (RD4(ocotp_sc, off));
172
173
/*
174
* Otherwise establish a tempory device mapping if necessary, and read
175
* the device without any help from bus_space.
176
*
177
* XXX Eventually the code from there down can be deleted.
178
*/
179
if (ocotp_regs == NULL)
180
fsl_ocotp_devmap();
181
182
return (ocotp_regs[off / 4]);
183
}
184
185
static device_method_t ocotp_methods[] = {
186
/* Device interface */
187
DEVMETHOD(device_probe, ocotp_probe),
188
DEVMETHOD(device_attach, ocotp_attach),
189
DEVMETHOD(device_detach, ocotp_detach),
190
191
DEVMETHOD_END
192
};
193
194
static driver_t ocotp_driver = {
195
"ocotp",
196
ocotp_methods,
197
sizeof(struct ocotp_softc)
198
};
199
200
EARLY_DRIVER_MODULE(ocotp, simplebus, ocotp_driver, 0, 0,
201
BUS_PASS_CPU + BUS_PASS_ORDER_FIRST);
202
203