Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/arm/nvidia/tegra_abpmisc.c
39478 views
1
/*-
2
* Copyright (c) 2016 Michal Meloun <[email protected]>
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
/*
29
* SoC misc configuration and indentification driver.
30
*/
31
#include <sys/param.h>
32
#include <sys/systm.h>
33
#include <sys/bus.h>
34
#include <sys/clock.h>
35
#include <sys/kernel.h>
36
#include <sys/limits.h>
37
#include <sys/lock.h>
38
#include <sys/mutex.h>
39
#include <sys/module.h>
40
#include <sys/resource.h>
41
42
#include <machine/bus.h>
43
#include <machine/resource.h>
44
#include <sys/rman.h>
45
46
#include <dev/ofw/ofw_bus.h>
47
#include <dev/ofw/ofw_bus_subr.h>
48
49
#include <arm/nvidia/tegra_efuse.h>
50
51
#define PMC_STRAPPING_OPT_A 0 /* 0x464 */
52
53
#define PMC_STRAPPING_OPT_A_RAM_CODE_SHIFT 4
54
#define PMC_STRAPPING_OPT_A_RAM_CODE_MASK_LONG \
55
(0xf << PMC_STRAPPING_OPT_A_RAM_CODE_SHIFT)
56
#define PMC_STRAPPING_OPT_A_RAM_CODE_MASK_SHORT \
57
(0x3 << PMC_STRAPPING_OPT_A_RAM_CODE_SHIFT)
58
59
#define ABP_RD4(_sc, _r) bus_read_4((_sc)->abp_misc_res, (_r))
60
#define STR_RD4(_sc, _r) bus_read_4((_sc)->strap_opt_res, (_r))
61
62
static struct ofw_compat_data compat_data[] = {
63
{"nvidia,tegra124-apbmisc", 1},
64
{"nvidia,tegra210-apbmisc", 1},
65
{NULL, 0}
66
};
67
68
struct tegra_abpmisc_softc {
69
device_t dev;
70
71
struct resource *abp_misc_res;
72
struct resource *strap_opt_res;
73
};
74
75
static struct tegra_abpmisc_softc *dev_sc;
76
77
static void
78
tegra_abpmisc_read_revision(struct tegra_abpmisc_softc *sc)
79
{
80
uint32_t id, chip_id, minor_rev;
81
int rev;
82
83
id = ABP_RD4(sc, 4);
84
chip_id = (id >> 8) & 0xff;
85
minor_rev = (id >> 16) & 0xf;
86
87
switch (minor_rev) {
88
case 1:
89
rev = TEGRA_REVISION_A01;
90
break;
91
case 2:
92
rev = TEGRA_REVISION_A02;
93
break;
94
case 3:
95
rev = TEGRA_REVISION_A03;
96
break;
97
case 4:
98
rev = TEGRA_REVISION_A04;
99
break;
100
default:
101
rev = TEGRA_REVISION_UNKNOWN;
102
}
103
104
tegra_sku_info.chip_id = chip_id;
105
tegra_sku_info.revision = rev;
106
}
107
108
static int
109
tegra_abpmisc_probe(device_t dev)
110
{
111
if (!ofw_bus_status_okay(dev))
112
return (ENXIO);
113
114
if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
115
return (ENXIO);
116
117
return (BUS_PROBE_DEFAULT);
118
}
119
120
static int
121
tegra_abpmisc_attach(device_t dev)
122
{
123
int rid;
124
struct tegra_abpmisc_softc *sc;
125
126
sc = device_get_softc(dev);
127
sc->dev = dev;
128
129
rid = 0;
130
sc->abp_misc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
131
RF_ACTIVE | RF_SHAREABLE);
132
if (sc->abp_misc_res == NULL) {
133
device_printf(dev, "Cannot map ABP misc registers.\n");
134
goto fail;
135
}
136
137
rid = 1;
138
sc->strap_opt_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
139
RF_ACTIVE);
140
if (sc->strap_opt_res == NULL) {
141
device_printf(dev, "Cannot map strapping options registers.\n");
142
goto fail;
143
}
144
145
tegra_abpmisc_read_revision(sc);
146
147
/* XXX - Hack - address collision with pinmux. */
148
if (sc->abp_misc_res != NULL) {
149
bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->abp_misc_res);
150
sc->abp_misc_res = NULL;
151
}
152
153
dev_sc = sc;
154
bus_attach_children(dev);
155
return (0);
156
157
fail:
158
if (sc->abp_misc_res != NULL)
159
bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->abp_misc_res);
160
if (sc->strap_opt_res != NULL)
161
bus_release_resource(dev, SYS_RES_MEMORY, 1, sc->strap_opt_res);
162
163
return (ENXIO);
164
}
165
166
static int
167
tegra_abpmisc_detach(device_t dev)
168
{
169
struct tegra_abpmisc_softc *sc;
170
int error;
171
172
error = bus_generic_detach(dev);
173
if (error != 0)
174
return (error);
175
176
sc = device_get_softc(dev);
177
if (sc->abp_misc_res != NULL)
178
bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->abp_misc_res);
179
if (sc->strap_opt_res != NULL)
180
bus_release_resource(dev, SYS_RES_MEMORY, 1, sc->strap_opt_res);
181
return (0);
182
}
183
184
static device_method_t tegra_abpmisc_methods[] = {
185
/* Device interface */
186
DEVMETHOD(device_probe, tegra_abpmisc_probe),
187
DEVMETHOD(device_attach, tegra_abpmisc_attach),
188
DEVMETHOD(device_detach, tegra_abpmisc_detach),
189
190
DEVMETHOD_END
191
};
192
193
static DEFINE_CLASS_0(abpmisc, tegra_abpmisc_driver, tegra_abpmisc_methods,
194
sizeof(struct tegra_abpmisc_softc));
195
EARLY_DRIVER_MODULE(tegra_abpmisc, simplebus, tegra_abpmisc_driver, NULL, NULL,
196
BUS_PASS_TIMER);
197
198