fsl_ocotp.c revision 261947
1/*-
2 * Copyright (c) 2014 Steven Lawrance <stl@koffein.net>
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 <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/sys/arm/freescale/fsl_ocotp.c 261947 2014-02-15 21:59:00Z ian $");
29
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
49struct ocotp_softc {
50	device_t	dev;
51	struct resource	*mem_res;
52};
53
54static struct ocotp_softc *ocotp_sc;
55
56static inline uint32_t
57RD4(struct ocotp_softc *sc, bus_size_t off)
58{
59
60	return (bus_read_4(sc->mem_res, off));
61}
62
63
64static int
65ocotp_detach(device_t dev)
66{
67	struct ocotp_softc *sc;
68
69	sc = device_get_softc(dev);
70
71	if (sc->mem_res != NULL)
72		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res);
73
74	ocotp_sc = NULL;
75
76	return (0);
77}
78
79static int
80ocotp_attach(device_t dev)
81{
82	struct ocotp_softc *sc;
83	int err, rid;
84
85	sc = device_get_softc(dev);
86	sc->dev = dev;
87
88	/* Allocate bus_space resources. */
89	rid = 0;
90	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
91	    RF_ACTIVE);
92	if (sc->mem_res == NULL) {
93		device_printf(dev, "Cannot allocate memory resources\n");
94		err = ENXIO;
95		goto out;
96	}
97
98	ocotp_sc = sc;
99	err = 0;
100
101out:
102	if (err != 0)
103		ocotp_detach(dev);
104
105	return (err);
106}
107
108static int
109ocotp_probe(device_t dev)
110{
111
112	if (!ofw_bus_status_okay(dev))
113		return (ENXIO);
114
115        if (ofw_bus_is_compatible(dev, "fsl,imx6q-ocotp") == 0)
116		return (ENXIO);
117
118	device_set_desc(dev,
119	    "Freescale On-Chip One-Time-Programmable Memory");
120
121	return (BUS_PROBE_DEFAULT);
122}
123
124uint32_t
125fsl_ocotp_read_4(bus_size_t off)
126{
127
128	if (ocotp_sc == NULL)
129		panic("fsl_ocotp_read_4: softc not set!");
130
131	if (off > FSL_OCOTP_LAST_REG)
132		panic("fsl_ocotp_read_4: offset out of range");
133
134	return (RD4(ocotp_sc, off));
135}
136
137static device_method_t ocotp_methods[] = {
138	/* Device interface */
139	DEVMETHOD(device_probe,  ocotp_probe),
140	DEVMETHOD(device_attach, ocotp_attach),
141	DEVMETHOD(device_detach, ocotp_detach),
142
143	DEVMETHOD_END
144};
145
146static driver_t ocotp_driver = {
147	"ocotp",
148	ocotp_methods,
149	sizeof(struct ocotp_softc)
150};
151
152static devclass_t ocotp_devclass;
153
154DRIVER_MODULE(ocotp, simplebus, ocotp_driver, ocotp_devclass, 0, 0);
155
156