Tue Dec 22 22:10:36 2015 UTC ()
Switch Tegra over to fdt based clocks and reset controls.
(jmcneill)
diff -r1.27 -r1.28 src/sys/arch/arm/nvidia/files.tegra
diff -r1.11 -r1.12 src/sys/arch/arm/nvidia/soc_tegra124.c
diff -r1.11 -r1.12 src/sys/arch/arm/nvidia/tegra_ehci.c
diff -r0 -r1.1 src/sys/arch/arm/nvidia/tegra124_car.c
diff -r0 -r1.1 src/sys/arch/arm/nvidia/tegra124_carreg.h
diff -r0 -r1.1 src/sys/arch/arm/nvidia/tegra_clock.h
diff -r1.8 -r1.9 src/sys/arch/arm/nvidia/tegra_ahcisata.c
diff -r1.8 -r1.9 src/sys/arch/arm/nvidia/tegra_nouveau.c
diff -r1.31 -r0 src/sys/arch/arm/nvidia/tegra_car.c
diff -r1.22 -r0 src/sys/arch/arm/nvidia/tegra_carreg.h
diff -r1.2 -r1.3 src/sys/arch/arm/nvidia/tegra_cec.c
diff -r1.2 -r1.3 src/sys/arch/arm/nvidia/tegra_cpufreq.c
diff -r1.2 -r1.3 src/sys/arch/arm/nvidia/tegra_soctherm.c
diff -r1.2 -r1.3 src/sys/arch/arm/nvidia/tegra_timer.c
diff -r1.4 -r1.5 src/sys/arch/arm/nvidia/tegra_com.c
diff -r1.4 -r1.5 src/sys/arch/arm/nvidia/tegra_drm.c
diff -r1.4 -r1.5 src/sys/arch/arm/nvidia/tegra_usbphy.c
diff -r1.5 -r1.6 src/sys/arch/arm/nvidia/tegra_drm.h
diff -r1.5 -r1.6 src/sys/arch/arm/nvidia/tegra_hdaudio.c
diff -r1.10 -r1.11 src/sys/arch/arm/nvidia/tegra_drm_mode.c
diff -r1.10 -r1.11 src/sys/arch/arm/nvidia/tegra_i2c.c
diff -r1.1 -r1.2 src/sys/arch/arm/nvidia/tegra_fdt.c
diff -r1.1 -r1.2 src/sys/arch/arm/nvidia/tegra_timerreg.h
diff -r1.3 -r1.4 src/sys/arch/arm/nvidia/tegra_fuse.c
diff -r1.14 -r1.15 src/sys/arch/arm/nvidia/tegra_sdhc.c
diff -r1.7 -r1.8 src/sys/arch/arm/nvidia/tegra_soc.c
diff -r1.5 -r1.6 src/sys/arch/evbarm/conf/TEGRA
diff -r1.11 -r1.12 src/sys/arch/evbarm/conf/std.tegra
diff -r1.36 -r1.37 src/sys/arch/evbarm/tegra/tegra_machdep.c
--- src/sys/arch/arm/nvidia/files.tegra 2015/12/13 22:55:05 1.27
+++ src/sys/arch/arm/nvidia/files.tegra 2015/12/22 22:10:36 1.28
| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | # $NetBSD: files.tegra,v 1.27 2015/12/13 22:55:05 jmcneill Exp $ | | 1 | # $NetBSD: files.tegra,v 1.28 2015/12/22 22:10:36 jmcneill Exp $ |
2 | # | | 2 | # |
3 | # Configuration info for NVIDIA Tegra ARM Peripherals | | 3 | # Configuration info for NVIDIA Tegra ARM Peripherals |
4 | # | | 4 | # |
5 | | | 5 | |
6 | include "arch/arm/pic/files.pic" | | 6 | include "arch/arm/pic/files.pic" |
7 | include "arch/arm/cortex/files.cortex" | | 7 | include "arch/arm/cortex/files.cortex" |
8 | | | 8 | |
9 | file arch/arm/arm32/arm32_boot.c | | 9 | file arch/arm/arm32/arm32_boot.c |
10 | file arch/arm/arm32/arm32_kvminit.c | | 10 | file arch/arm/arm32/arm32_kvminit.c |
11 | file arch/arm/arm32/arm32_reboot.c | | 11 | file arch/arm/arm32/arm32_reboot.c |
12 | file arch/arm/arm32/irq_dispatch.S | | 12 | file arch/arm/arm32/irq_dispatch.S |
13 | file arch/arm/arm32/armv7_generic_space.c | | 13 | file arch/arm/arm32/armv7_generic_space.c |
14 | file arch/arm/arm/bus_space_a4x.S | | 14 | file arch/arm/arm/bus_space_a4x.S |
| @@ -33,29 +33,29 @@ attach tegramc at fdt with tegra_mc | | | @@ -33,29 +33,29 @@ attach tegramc at fdt with tegra_mc |
33 | file arch/arm/nvidia/tegra_mc.c tegra_mc | | 33 | file arch/arm/nvidia/tegra_mc.c tegra_mc |
34 | | | 34 | |
35 | # Power management controller | | 35 | # Power management controller |
36 | device tegrapmc | | 36 | device tegrapmc |
37 | attach tegrapmc at fdt with tegra_pmc | | 37 | attach tegrapmc at fdt with tegra_pmc |
38 | file arch/arm/nvidia/tegra_pmc.c tegra_pmc | | 38 | file arch/arm/nvidia/tegra_pmc.c tegra_pmc |
39 | | | 39 | |
40 | # eFUSE | | 40 | # eFUSE |
41 | device tegrafuse | | 41 | device tegrafuse |
42 | attach tegrafuse at fdt with tegra_fuse | | 42 | attach tegrafuse at fdt with tegra_fuse |
43 | file arch/arm/nvidia/tegra_fuse.c tegra_fuse | | 43 | file arch/arm/nvidia/tegra_fuse.c tegra_fuse |
44 | | | 44 | |
45 | # Clock and Reset controller | | 45 | # Clock and Reset controller |
46 | device tegracar | | 46 | device tegra124car: clk |
47 | attach tegracar at fdt with tegra_car | | 47 | attach tegra124car at fdt with tegra124_car |
48 | file arch/arm/nvidia/tegra_car.c tegra_car | | 48 | file arch/arm/nvidia/tegra124_car.c tegra124_car |
49 | | | 49 | |
50 | # GPIO controller | | 50 | # GPIO controller |
51 | device tegragpio: gpiobus | | 51 | device tegragpio: gpiobus |
52 | attach tegragpio at fdt with tegra_gpio | | 52 | attach tegragpio at fdt with tegra_gpio |
53 | file arch/arm/nvidia/tegra_gpio.c tegra_gpio | | 53 | file arch/arm/nvidia/tegra_gpio.c tegra_gpio |
54 | | | 54 | |
55 | # Timers | | 55 | # Timers |
56 | device tegratimer: sysmon_wdog | | 56 | device tegratimer: sysmon_wdog |
57 | attach tegratimer at fdt with tegra_timer | | 57 | attach tegratimer at fdt with tegra_timer |
58 | file arch/arm/nvidia/tegra_timer.c tegra_timer | | 58 | file arch/arm/nvidia/tegra_timer.c tegra_timer |
59 | | | 59 | |
60 | # MPIO / Pinmux | | 60 | # MPIO / Pinmux |
61 | device tegrampio | | 61 | device tegrampio |
--- src/sys/arch/arm/nvidia/soc_tegra124.c 2015/12/01 22:08:13 1.11
+++ src/sys/arch/arm/nvidia/soc_tegra124.c 2015/12/22 22:10:36 1.12
| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: soc_tegra124.c,v 1.11 2015/12/01 22:08:13 jmcneill Exp $ */ | | 1 | /* $NetBSD: soc_tegra124.c,v 1.12 2015/12/22 22:10:36 jmcneill Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> | | 4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -20,35 +20,39 @@ | | | @@ -20,35 +20,39 @@ |
20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | | 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | | 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | | 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | | 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 24 | * 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 | | 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
26 | * SUCH DAMAGE. | | 26 | * SUCH DAMAGE. |
27 | */ | | 27 | */ |
28 | | | 28 | |
29 | #include "opt_tegra.h" | | 29 | #include "opt_tegra.h" |
30 | #include "opt_multiprocessor.h" | | 30 | #include "opt_multiprocessor.h" |
31 | | | 31 | |
32 | #include <sys/cdefs.h> | | 32 | #include <sys/cdefs.h> |
33 | __KERNEL_RCSID(0, "$NetBSD: soc_tegra124.c,v 1.11 2015/12/01 22:08:13 jmcneill Exp $"); | | 33 | __KERNEL_RCSID(0, "$NetBSD: soc_tegra124.c,v 1.12 2015/12/22 22:10:36 jmcneill Exp $"); |
34 | | | 34 | |
35 | #include <sys/param.h> | | 35 | #include <sys/param.h> |
36 | #include <sys/bus.h> | | 36 | #include <sys/bus.h> |
37 | #include <sys/cpu.h> | | 37 | #include <sys/cpu.h> |
38 | #include <sys/device.h> | | 38 | #include <sys/device.h> |
39 | | | 39 | |
40 | #include <uvm/uvm_extern.h> | | 40 | #include <uvm/uvm_extern.h> |
41 | | | 41 | |
| | | 42 | #include <dev/clk/clk.h> |
| | | 43 | #include <dev/i2c/i2cvar.h> |
| | | 44 | #include <dev/fdt/fdtvar.h> |
| | | 45 | |
42 | #include <arm/cpufunc.h> | | 46 | #include <arm/cpufunc.h> |
43 | | | 47 | |
44 | #include <arm/nvidia/tegra_reg.h> | | 48 | #include <arm/nvidia/tegra_reg.h> |
45 | #include <arm/nvidia/tegra_pmcreg.h> | | 49 | #include <arm/nvidia/tegra_pmcreg.h> |
46 | #include <arm/nvidia/tegra_var.h> | | 50 | #include <arm/nvidia/tegra_var.h> |
47 | | | 51 | |
48 | #define EVP_RESET_VECTOR_0_REG 0x100 | | 52 | #define EVP_RESET_VECTOR_0_REG 0x100 |
49 | | | 53 | |
50 | #define FUSE_SKU_INFO_REG 0x010 | | 54 | #define FUSE_SKU_INFO_REG 0x010 |
51 | #define FUSE_CPU_SPEEDO_0_REG 0x014 | | 55 | #define FUSE_CPU_SPEEDO_0_REG 0x014 |
52 | #define FUSE_CPU_IDDQ_REG 0x018 | | 56 | #define FUSE_CPU_IDDQ_REG 0x018 |
53 | #define FUSE_FT_REV_REG 0x028 | | 57 | #define FUSE_FT_REV_REG 0x028 |
54 | #define FUSE_CPU_SPEEDO_1_REG 0x02c | | 58 | #define FUSE_CPU_SPEEDO_1_REG 0x02c |
| @@ -97,39 +101,62 @@ static const u_int tegra124_cpufreq_max[ | | | @@ -97,39 +101,62 @@ static const u_int tegra124_cpufreq_max[ |
97 | 2524 | | 101 | 2524 |
98 | }; | | 102 | }; |
99 | | | 103 | |
100 | static struct tegra124_speedo { | | 104 | static struct tegra124_speedo { |
101 | u_int cpu_speedo_id; | | 105 | u_int cpu_speedo_id; |
102 | u_int soc_speedo_id; | | 106 | u_int soc_speedo_id; |
103 | u_int gpu_speedo_id; | | 107 | u_int gpu_speedo_id; |
104 | } tegra124_speedo = { | | 108 | } tegra124_speedo = { |
105 | .cpu_speedo_id = 0, | | 109 | .cpu_speedo_id = 0, |
106 | .soc_speedo_id = 0, | | 110 | .soc_speedo_id = 0, |
107 | .gpu_speedo_id = 0 | | 111 | .gpu_speedo_id = 0 |
108 | }; | | 112 | }; |
109 | | | 113 | |
| | | 114 | static struct clk *tegra124_clk_pllx = NULL; |
| | | 115 | |
110 | void | | 116 | void |
111 | tegra124_cpuinit(void) | | 117 | tegra124_cpuinit(void) |
112 | { | | 118 | { |
113 | tegra_car_periph_i2c_enable(4, 20400000); | | 119 | const int node = OF_finddevice("/i2c@0,7000d000"); |
| | | 120 | if (node == -1) { |
| | | 121 | aprint_error("cpufreq: ERROR: couldn't find i2c@0,7000d000\n"); |
| | | 122 | return; |
| | | 123 | } |
| | | 124 | i2c_tag_t ic = fdtbus_get_i2c_tag(node); |
114 | | | 125 | |
115 | /* Set VDD_CPU voltage to 1.4V */ | | 126 | /* Set VDD_CPU voltage to 1.4V */ |
116 | const u_int target_mv = 1400; | | 127 | const u_int target_mv = 1400; |
117 | const u_int sd0_vsel = (target_mv - 600) / 10; | | 128 | const u_int sd0_vsel = (target_mv - 600) / 10; |
118 | tegra_i2c_dvc_write(0x40, (sd0_vsel << 8) | 00, 2); | | 129 | uint8_t data[2] = { 0x00, sd0_vsel }; |
| | | 130 | |
| | | 131 | iic_acquire_bus(ic, I2C_F_POLL); |
| | | 132 | const int error = iic_exec(ic, I2C_OP_WRITE_WITH_STOP, 0x40, |
| | | 133 | NULL, 0, data, sizeof(data), I2C_F_POLL); |
| | | 134 | iic_release_bus(ic, I2C_F_POLL); |
| | | 135 | if (error) { |
| | | 136 | aprint_error("cpufreq: ERROR: couldn't set VDD_CPU: %d\n", |
| | | 137 | error); |
| | | 138 | return; |
| | | 139 | } |
119 | delay(10000); | | 140 | delay(10000); |
120 | | | 141 | |
121 | tegra124_speedo_init(); | | 142 | tegra124_speedo_init(); |
122 | | | 143 | |
| | | 144 | tegra124_clk_pllx = clk_get("pll_x"); |
| | | 145 | if (tegra124_clk_pllx == NULL) { |
| | | 146 | aprint_error("cpufreq: ERROR: couldn't find pll_x\n"); |
| | | 147 | return; |
| | | 148 | } |
| | | 149 | |
123 | tegra_cpufreq_register(&tegra124_cpufreq_func); | | 150 | tegra_cpufreq_register(&tegra124_cpufreq_func); |
124 | } | | 151 | } |
125 | | | 152 | |
126 | static void | | 153 | static void |
127 | tegra124_speedo_init(void) | | 154 | tegra124_speedo_init(void) |
128 | { | | 155 | { |
129 | uint32_t sku_id; | | 156 | uint32_t sku_id; |
130 | | | 157 | |
131 | sku_id = tegra_fuse_read(FUSE_SKU_INFO_REG); | | 158 | sku_id = tegra_fuse_read(FUSE_SKU_INFO_REG); |
132 | tegra124_speedo_init_ids(sku_id); | | 159 | tegra124_speedo_init_ids(sku_id); |
133 | } | | 160 | } |
134 | | | 161 | |
135 | static int | | 162 | static int |
| @@ -196,35 +223,33 @@ tegra124_cpufreq_set_rate(u_int rate) | | | @@ -196,35 +223,33 @@ tegra124_cpufreq_set_rate(u_int rate) |
196 | | | 223 | |
197 | if (tegra124_speedo_rate_ok(rate) == false) | | 224 | if (tegra124_speedo_rate_ok(rate) == false) |
198 | return EINVAL; | | 225 | return EINVAL; |
199 | | | 226 | |
200 | for (int i = 0; i < nrates; i++) { | | 227 | for (int i = 0; i < nrates; i++) { |
201 | if (tegra124_cpufreq_rates[i].rate == rate) { | | 228 | if (tegra124_cpufreq_rates[i].rate == rate) { |
202 | r = &tegra124_cpufreq_rates[i]; | | 229 | r = &tegra124_cpufreq_rates[i]; |
203 | break; | | 230 | break; |
204 | } | | 231 | } |
205 | } | | 232 | } |
206 | if (r == NULL) | | 233 | if (r == NULL) |
207 | return EINVAL; | | 234 | return EINVAL; |
208 | | | 235 | |
209 | tegra_car_pllx_set_rate(r->divm, r->divn, r->divp); | | 236 | return clk_set_rate(tegra124_clk_pllx, r->rate * 1000000); |
210 | | | | |
211 | return 0; | | | |
212 | } | | 237 | } |
213 | | | 238 | |
214 | static u_int | | 239 | static u_int |
215 | tegra124_cpufreq_get_rate(void) | | 240 | tegra124_cpufreq_get_rate(void) |
216 | { | | 241 | { |
217 | return tegra_car_pllx_rate() / 1000000; | | 242 | return clk_get_rate(tegra124_clk_pllx) / 1000000; |
218 | } | | 243 | } |
219 | | | 244 | |
220 | static size_t | | 245 | static size_t |
221 | tegra124_cpufreq_get_available(u_int *pavail, size_t maxavail) | | 246 | tegra124_cpufreq_get_available(u_int *pavail, size_t maxavail) |
222 | { | | 247 | { |
223 | const u_int nrates = __arraycount(tegra124_cpufreq_rates); | | 248 | const u_int nrates = __arraycount(tegra124_cpufreq_rates); |
224 | u_int n, cnt; | | 249 | u_int n, cnt; |
225 | | | 250 | |
226 | KASSERT(nrates <= maxavail); | | 251 | KASSERT(nrates <= maxavail); |
227 | | | 252 | |
228 | for (n = 0, cnt = 0; n < nrates; n++) { | | 253 | for (n = 0, cnt = 0; n < nrates; n++) { |
229 | if (tegra124_speedo_rate_ok(tegra124_cpufreq_rates[n].rate)) { | | 254 | if (tegra124_speedo_rate_ok(tegra124_cpufreq_rates[n].rate)) { |
230 | pavail[cnt++] = tegra124_cpufreq_rates[n].rate; | | 255 | pavail[cnt++] = tegra124_cpufreq_rates[n].rate; |
--- src/sys/arch/arm/nvidia/tegra_ehci.c 2015/12/13 17:39:19 1.11
+++ src/sys/arch/arm/nvidia/tegra_ehci.c 2015/12/22 22:10:36 1.12
| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: tegra_ehci.c,v 1.11 2015/12/13 17:39:19 jmcneill Exp $ */ | | 1 | /* $NetBSD: tegra_ehci.c,v 1.12 2015/12/22 22:10:36 jmcneill Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> | | 4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -17,77 +17,60 @@ | | | @@ -17,77 +17,60 @@ |
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | | 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | | 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | | 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | | 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | | 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 24 | * 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 | | 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
26 | * SUCH DAMAGE. | | 26 | * SUCH DAMAGE. |
27 | */ | | 27 | */ |
28 | | | 28 | |
29 | #include <sys/cdefs.h> | | 29 | #include <sys/cdefs.h> |
30 | __KERNEL_RCSID(0, "$NetBSD: tegra_ehci.c,v 1.11 2015/12/13 17:39:19 jmcneill Exp $"); | | 30 | __KERNEL_RCSID(0, "$NetBSD: tegra_ehci.c,v 1.12 2015/12/22 22:10:36 jmcneill Exp $"); |
31 | | | 31 | |
32 | #include <sys/param.h> | | 32 | #include <sys/param.h> |
33 | #include <sys/bus.h> | | 33 | #include <sys/bus.h> |
34 | #include <sys/device.h> | | 34 | #include <sys/device.h> |
35 | #include <sys/intr.h> | | 35 | #include <sys/intr.h> |
36 | #include <sys/systm.h> | | 36 | #include <sys/systm.h> |
37 | #include <sys/kernel.h> | | 37 | #include <sys/kernel.h> |
38 | | | 38 | |
39 | #include <dev/usb/usb.h> | | 39 | #include <dev/usb/usb.h> |
40 | #include <dev/usb/usbdi.h> | | 40 | #include <dev/usb/usbdi.h> |
41 | #include <dev/usb/usbdivar.h> | | 41 | #include <dev/usb/usbdivar.h> |
42 | #include <dev/usb/usb_mem.h> | | 42 | #include <dev/usb/usb_mem.h> |
43 | #include <dev/usb/ehcireg.h> | | 43 | #include <dev/usb/ehcireg.h> |
44 | #include <dev/usb/ehcivar.h> | | 44 | #include <dev/usb/ehcivar.h> |
45 | | | 45 | |
46 | #include <arm/nvidia/tegra_reg.h> | | 46 | #include <arm/nvidia/tegra_reg.h> |
47 | #include <arm/nvidia/tegra_var.h> | | 47 | #include <arm/nvidia/tegra_var.h> |
48 | #include <arm/nvidia/tegra_usbreg.h> | | 48 | #include <arm/nvidia/tegra_usbreg.h> |
49 | | | 49 | |
50 | #include <dev/fdt/fdtvar.h> | | 50 | #include <dev/fdt/fdtvar.h> |
51 | | | 51 | |
52 | /* XXX */ | | | |
53 | static int | | | |
54 | tegra_ehci_addr2port(bus_addr_t addr) | | | |
55 | { | | | |
56 | switch (addr) { | | | |
57 | case TEGRA_AHB_A2_BASE + TEGRA_USB1_OFFSET: | | | |
58 | return 0; | | | |
59 | case TEGRA_AHB_A2_BASE + TEGRA_USB2_OFFSET: | | | |
60 | return 1; | | | |
61 | case TEGRA_AHB_A2_BASE + TEGRA_USB3_OFFSET: | | | |
62 | return 2; | | | |
63 | default: | | | |
64 | return -1; | | | |
65 | } | | | |
66 | } | | | |
67 | | | | |
68 | #define TEGRA_EHCI_REG_OFFSET 0x100 | | 52 | #define TEGRA_EHCI_REG_OFFSET 0x100 |
69 | | | 53 | |
70 | static int tegra_ehci_match(device_t, cfdata_t, void *); | | 54 | static int tegra_ehci_match(device_t, cfdata_t, void *); |
71 | static void tegra_ehci_attach(device_t, device_t, void *); | | 55 | static void tegra_ehci_attach(device_t, device_t, void *); |
72 | | | 56 | |
73 | static void tegra_ehci_init(struct ehci_softc *); | | 57 | static void tegra_ehci_init(struct ehci_softc *); |
74 | | | 58 | |
75 | struct tegra_ehci_softc { | | 59 | struct tegra_ehci_softc { |
76 | struct ehci_softc sc; | | 60 | struct ehci_softc sc; |
77 | bus_space_tag_t sc_bst; | | 61 | bus_space_tag_t sc_bst; |
78 | bus_space_handle_t sc_bsh; | | 62 | bus_space_handle_t sc_bsh; |
79 | void *sc_ih; | | 63 | void *sc_ih; |
80 | u_int sc_port; | | | |
81 | }; | | 64 | }; |
82 | | | 65 | |
83 | static int tegra_ehci_port_status(struct ehci_softc *sc, uint32_t v, | | 66 | static int tegra_ehci_port_status(struct ehci_softc *sc, uint32_t v, |
84 | int i); | | 67 | int i); |
85 | | | 68 | |
86 | CFATTACH_DECL2_NEW(tegra_ehci, sizeof(struct tegra_ehci_softc), | | 69 | CFATTACH_DECL2_NEW(tegra_ehci, sizeof(struct tegra_ehci_softc), |
87 | tegra_ehci_match, tegra_ehci_attach, NULL, | | 70 | tegra_ehci_match, tegra_ehci_attach, NULL, |
88 | ehci_activate, NULL, ehci_childdet); | | 71 | ehci_activate, NULL, ehci_childdet); |
89 | | | 72 | |
90 | static int | | 73 | static int |
91 | tegra_ehci_match(device_t parent, cfdata_t cf, void *aux) | | 74 | tegra_ehci_match(device_t parent, cfdata_t cf, void *aux) |
92 | { | | 75 | { |
93 | const char * const compatible[] = { "nvidia,tegra124-ehci", NULL }; | | 76 | const char * const compatible[] = { "nvidia,tegra124-ehci", NULL }; |
| @@ -102,50 +85,49 @@ tegra_ehci_attach(device_t parent, devic | | | @@ -102,50 +85,49 @@ tegra_ehci_attach(device_t parent, devic |
102 | struct tegra_ehci_softc * const sc = device_private(self); | | 85 | struct tegra_ehci_softc * const sc = device_private(self); |
103 | struct fdt_attach_args * const faa = aux; | | 86 | struct fdt_attach_args * const faa = aux; |
104 | char intrstr[128]; | | 87 | char intrstr[128]; |
105 | bus_addr_t addr; | | 88 | bus_addr_t addr; |
106 | bus_size_t size; | | 89 | bus_size_t size; |
107 | int error; | | 90 | int error; |
108 | | | 91 | |
109 | if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) { | | 92 | if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) { |
110 | aprint_error(": couldn't get registers\n"); | | 93 | aprint_error(": couldn't get registers\n"); |
111 | return; | | 94 | return; |
112 | } | | 95 | } |
113 | | | 96 | |
114 | sc->sc_bst = faa->faa_bst; | | 97 | sc->sc_bst = faa->faa_bst; |
115 | sc->sc_port = tegra_ehci_addr2port(addr); | | | |
116 | error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh); | | 98 | error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh); |
117 | if (error) { | | 99 | if (error) { |
118 | aprint_error(": couldn't map USB%d\n", sc->sc_port + 1); | | 100 | aprint_error(": couldn't map USB\n"); |
119 | return; | | 101 | return; |
120 | } | | 102 | } |
121 | | | 103 | |
122 | sc->sc.sc_dev = self; | | 104 | sc->sc.sc_dev = self; |
123 | sc->sc.sc_bus.hci_private = &sc->sc; | | 105 | sc->sc.sc_bus.hci_private = &sc->sc; |
124 | sc->sc.sc_bus.dmatag = faa->faa_dmat; | | 106 | sc->sc.sc_bus.dmatag = faa->faa_dmat; |
125 | sc->sc.sc_bus.usbrev = USBREV_2_0; | | 107 | sc->sc.sc_bus.usbrev = USBREV_2_0; |
126 | sc->sc.sc_ncomp = 0; | | 108 | sc->sc.sc_ncomp = 0; |
127 | sc->sc.sc_flags = EHCIF_ETTF; | | 109 | sc->sc.sc_flags = EHCIF_ETTF; |
128 | sc->sc.sc_id_vendor = 0x10de; | | 110 | sc->sc.sc_id_vendor = 0x10de; |
129 | strlcpy(sc->sc.sc_vendor, "Tegra", sizeof(sc->sc.sc_vendor)); | | 111 | strlcpy(sc->sc.sc_vendor, "Tegra", sizeof(sc->sc.sc_vendor)); |
130 | sc->sc.sc_size = size - TEGRA_EHCI_REG_OFFSET; | | 112 | sc->sc.sc_size = size - TEGRA_EHCI_REG_OFFSET; |
131 | sc->sc.iot = sc->sc_bst; | | 113 | sc->sc.iot = sc->sc_bst; |
132 | bus_space_subregion(sc->sc_bst, sc->sc_bsh, TEGRA_EHCI_REG_OFFSET, | | 114 | bus_space_subregion(sc->sc_bst, sc->sc_bsh, TEGRA_EHCI_REG_OFFSET, |
133 | sc->sc.sc_size, &sc->sc.ioh); | | 115 | sc->sc.sc_size, &sc->sc.ioh); |
134 | sc->sc.sc_vendor_init = tegra_ehci_init; | | 116 | sc->sc.sc_vendor_init = tegra_ehci_init; |
135 | sc->sc.sc_vendor_port_status = tegra_ehci_port_status; | | 117 | sc->sc.sc_vendor_port_status = tegra_ehci_port_status; |
136 | | | 118 | |
137 | aprint_naive("\n"); | | 119 | aprint_naive("\n"); |
138 | aprint_normal(": USB%d\n", sc->sc_port + 1); | | 120 | aprint_normal(": USB\n"); |
139 | | | 121 | |
140 | sc->sc.sc_offs = EREAD1(&sc->sc, EHCI_CAPLENGTH); | | 122 | sc->sc.sc_offs = EREAD1(&sc->sc, EHCI_CAPLENGTH); |
141 | | | 123 | |
142 | if (!fdtbus_intr_str(faa->faa_phandle, 0, intrstr, sizeof(intrstr))) { | | 124 | if (!fdtbus_intr_str(faa->faa_phandle, 0, intrstr, sizeof(intrstr))) { |
143 | aprint_error_dev(self, "failed to decode interrupt\n"); | | 125 | aprint_error_dev(self, "failed to decode interrupt\n"); |
144 | return; | | 126 | return; |
145 | } | | 127 | } |
146 | | | 128 | |
147 | sc->sc_ih = fdtbus_intr_establish(faa->faa_phandle, 0, IPL_USB, 0, | | 129 | sc->sc_ih = fdtbus_intr_establish(faa->faa_phandle, 0, IPL_USB, 0, |
148 | ehci_intr, &sc->sc); | | 130 | ehci_intr, &sc->sc); |
149 | if (sc->sc_ih == NULL) { | | 131 | if (sc->sc_ih == NULL) { |
150 | aprint_error_dev(self, "couldn't establish interrupt on %s\n", | | 132 | aprint_error_dev(self, "couldn't establish interrupt on %s\n", |
151 | intrstr); | | 133 | intrstr); |
/* $NetBSD: tegra124_car.c,v 1.1 2015/12/22 22:10:36 jmcneill Exp $ */
/*-
* Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: tegra124_car.c,v 1.1 2015/12/22 22:10:36 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/device.h>
#include <sys/intr.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/rndpool.h>
#include <sys/rndsource.h>
#include <sys/atomic.h>
#include <sys/kmem.h>
#include <dev/clk/clk_backend.h>
#include <arm/nvidia/tegra_reg.h>
#include <arm/nvidia/tegra124_carreg.h>
#include <arm/nvidia/tegra_clock.h>
#include <arm/nvidia/tegra_pmcreg.h>
#include <arm/nvidia/tegra_var.h>
#include <dev/fdt/fdtvar.h>
static int tegra124_car_match(device_t, cfdata_t, void *);
static void tegra124_car_attach(device_t, device_t, void *);
static struct clk *tegra124_car_clock_decode(device_t, const void *, size_t);
static const struct fdtbus_clock_controller_func tegra124_car_fdtclock_funcs = {
.decode = tegra124_car_clock_decode
};
/* DT clock ID to clock name mappings */
static struct tegra124_car_clock_id {
u_int id;
const char *name;
} tegra124_car_clock_ids[] = {
{ 3, "ispb" },
{ 4, "rtc" },
{ 5, "timer" },
{ 6, "uarta" },
{ 9, "sdmmc2" },
{ 11, "i2s1" },
{ 12, "i2c1" },
{ 14, "sdmmc1" },
{ 15, "sdmmc4" },
{ 17, "pwm" },
{ 18, "i2s2" },
{ 22, "usbd" },
{ 23, "isp" },
{ 26, "disp2" },
{ 27, "disp1" },
{ 28, "host1x" },
{ 29, "vcp" },
{ 30, "i2s0" },
{ 32, "mc" },
{ 34, "apbdma" },
{ 36, "kbc" },
{ 40, "kfuse" },
{ 41, "sbc1" },
{ 42, "nor" },
{ 44, "sbc2" },
{ 46, "sbc3" },
{ 47, "i2c5" },
{ 48, "dsia" },
{ 50, "mipi" },
{ 51, "hdmi" },
{ 52, "csi" },
{ 54, "i2c2" },
{ 55, "uartc" },
{ 56, "mipi_cal" },
{ 57, "emc" },
{ 58, "usb2" },
{ 59, "usb3" },
{ 61, "vde" },
{ 62, "bsea" },
{ 63, "bsev" },
{ 65, "uartd" },
{ 67, "i2c3" },
{ 68, "sbc4" },
{ 69, "sdmmc3" },
{ 70, "pcie" },
{ 71, "owr" },
{ 72, "afi" },
{ 73, "csite" },
{ 76, "la" },
{ 77, "trace" },
{ 78, "soc_therm" },
{ 79, "dtv" },
{ 81, "i2cslow" },
{ 82, "dsib" },
{ 83, "tsec" },
{ 89, "xusb_host" },
{ 91, "msenc" },
{ 92, "csus" },
{ 99, "mselect" },
{ 100, "tsensor" },
{ 101, "i2s3" },
{ 102, "i2s4" },
{ 103, "i2c4" },
{ 104, "sbc5" },
{ 105, "sbc6" },
{ 106, "d_audio" },
{ 107, "apbif" },
{ 108, "dam0" },
{ 109, "dam1" },
{ 110, "dam2" },
{ 111, "hda2codec_2x" },
{ 113, "audio0_2x" },
{ 114, "audio1_2x" },
{ 115, "audio2_2x" },
{ 116, "audio3_2x" },
{ 117, "audio4_2x" },
{ 118, "spdif_2x" },
{ 119, "actmon" },
{ 120, "extern1" },
{ 121, "extern2" },
{ 122, "extern3" },
{ 123, "sata_oob" },
{ 124, "sata" },
{ 125, "hda" },
{ 127, "se" },
{ 128, "hda2hdmi" },
{ 129, "sata_cold" },
{ 144, "cilab" },
{ 145, "cilcd" },
{ 146, "cile" },
{ 147, "dsialp" },
{ 148, "dsiblp" },
{ 149, "entropy" },
{ 150, "dds" },
{ 152, "dp2" },
{ 153, "amx" },
{ 154, "adx" },
{ 156, "xusb_ss" },
{ 166, "i2c6" },
{ 171, "vim2_clk" },
{ 176, "hdmi_audio" },
{ 177, "clk72mhz" },
{ 178, "vic03" },
{ 180, "adx1" },
{ 181, "dpaux" },
{ 182, "sor0" },
{ 184, "gpu" },
{ 185, "amx1" },
{ 192, "uartb" },
{ 193, "vfir" },
{ 194, "spdif_in" },
{ 195, "spdif_out" },
{ 196, "vi" },
{ 197, "vi_sensor" },
{ 198, "fuse" },
{ 199, "fuse_burn" },
{ 200, "clk_32k" },
{ 201, "clk_m" },
{ 202, "clk_m_div2" },
{ 203, "clk_m_div4" },
{ 204, "pll_ref" },
{ 205, "pll_c" },
{ 206, "pll_c_out1" },
{ 207, "pll_c2" },
{ 208, "pll_c3" },
{ 209, "pll_m" },
{ 210, "pll_m_out1" },
{ 211, "pll_p" },
{ 212, "pll_p_out1" },
{ 213, "pll_p_out2" },
{ 214, "pll_p_out3" },
{ 215, "pll_p_out4" },
{ 216, "pll_a" },
{ 217, "pll_a_out0" },
{ 218, "pll_d" },
{ 219, "pll_d_out0" },
{ 220, "pll_d2" },
{ 221, "pll_d2_out0" },
{ 222, "pll_u" },
{ 223, "pll_u_480m" },
{ 224, "pll_u_60m" },
{ 225, "pll_u_48m" },
{ 226, "pll_u_12m" },
{ 229, "pll_re_vco" },
{ 230, "pll_re_out" },
{ 231, "pll_e" },
{ 232, "spdif_in_sync" },
{ 233, "i2s0_sync" },
{ 234, "i2s1_sync" },
{ 235, "i2s2_sync" },
{ 236, "i2s3_sync" },
{ 237, "i2s4_sync" },
{ 238, "vimclk_sync" },
{ 239, "audio0" },
{ 240, "audio1" },
{ 241, "audio2" },
{ 242, "audio3" },
{ 243, "audio4" },
{ 244, "spdif" },
{ 245, "clk_out_1" },
{ 246, "clk_out_2" },
{ 247, "clk_out_3" },
{ 248, "blink" },
{ 252, "xusb_host_src" },
{ 253, "xusb_falcon_src" },
{ 254, "xusb_fs_src" },
{ 255, "xusb_ss_src" },
{ 256, "xusb_dev_src" },
{ 257, "xusb_dev" },
{ 258, "xusb_hs_src" },
{ 259, "sclk" },
{ 260, "hclk" },
{ 261, "pclk" },
{ 264, "dfll_ref" },
{ 265, "dfll_soc" },
{ 266, "vi_sensor2" },
{ 267, "pll_p_out5" },
{ 268, "cml0" },
{ 269, "cml1" },
{ 270, "pll_c4" },
{ 271, "pll_dp" },
{ 272, "pll_e_mux" },
{ 273, "pll_d_dsi_out" },
{ 300, "audio0_mux" },
{ 301, "audio1_mux" },
{ 302, "audio2_mux" },
{ 303, "audio3_mux" },
{ 304, "audio4_mux" },
{ 305, "spdif_mux" },
{ 306, "clk_out_1_mux" },
{ 307, "clk_out_2_mux" },
{ 308, "clk_out_3_mux" },
{ 311, "sor0_lvds" },
{ 312, "xusb_ss_div2" },
{ 313, "pll_m_ud" },
{ 314, "pll_c_ud" },
{ 227, "pll_x" },
{ 228, "pll_x_out0" },
{ 262, "cclk_g" },
{ 263, "cclk_lp" },
{ 315, "clk_max" },
};
static struct clk *tegra124_car_clock_get(void *, const char *);
static void tegra124_car_clock_put(void *, struct clk *);
static u_int tegra124_car_clock_get_rate(void *, struct clk *);
static int tegra124_car_clock_set_rate(void *, struct clk *, u_int);
static int tegra124_car_clock_enable(void *, struct clk *);
static int tegra124_car_clock_disable(void *, struct clk *);
static int tegra124_car_clock_set_parent(void *, struct clk *,
struct clk *);
static struct clk *tegra124_car_clock_get_parent(void *, struct clk *);
static const struct clk_funcs tegra124_car_clock_funcs = {
.get = tegra124_car_clock_get,
.put = tegra124_car_clock_put,
.get_rate = tegra124_car_clock_get_rate,
.set_rate = tegra124_car_clock_set_rate,
.enable = tegra124_car_clock_enable,
.disable = tegra124_car_clock_disable,
.set_parent = tegra124_car_clock_set_parent,
.get_parent = tegra124_car_clock_get_parent,
};
#define CLK_FIXED(_name, _rate) { \
.base = { .name = (_name) }, .type = TEGRA_CLK_FIXED, \
.u = { .fixed = { .rate = (_rate) } } \
}
#define CLK_PLL(_name, _parent, _base, _divm, _divn, _divp) { \
.base = { .name = (_name) }, .type = TEGRA_CLK_PLL, \
.parent = (_parent), \
.u = { \
.pll = { \
.base_reg = (_base), \
.divm_mask = (_divm), \
.divn_mask = (_divn), \
.divp_mask = (_divp), \
} \
} \
}
#define CLK_MUX(_name, _reg, _bits, _p) { \
.base = { .name = (_name) }, .type = TEGRA_CLK_MUX, \
.u = { \
.mux = { \
.nparents = __arraycount(_p), \
.parents = (_p), \
.reg = (_reg), \
.bits = (_bits) \
} \
} \
}
#define CLK_FIXED_DIV(_name, _parent, _div) { \
.base = { .name = (_name) }, .type = TEGRA_CLK_FIXED_DIV, \
.parent = (_parent), \
.u = { \
.fixed_div = { \
.div = (_div) \
} \
} \
}
#define CLK_DIV(_name, _parent, _reg, _bits) { \
.base = { .name = (_name) }, .type = TEGRA_CLK_DIV, \
.parent = (_parent), \
.u = { \
.div = { \
.reg = (_reg), \
.bits = (_bits) \
} \
} \
}
#define CLK_GATE(_name, _parent, _set, _clr, _bits) { \
.base = { .name = (_name), .flags = CLK_SET_RATE_PARENT }, \
.type = TEGRA_CLK_GATE, \
.parent = (_parent), \
.u = { \
.gate = { \
.set_reg = (_set), \
.clr_reg = (_clr), \
.bits = (_bits), \
} \
} \
}
#define CLK_GATE_L(_name, _parent, _bits) \
CLK_GATE(_name, _parent, \
CAR_CLK_ENB_L_SET_REG, CAR_CLK_ENB_L_CLR_REG, \
_bits)
#define CLK_GATE_H(_name, _parent, _bits) \
CLK_GATE(_name, _parent, \
CAR_CLK_ENB_H_SET_REG, CAR_CLK_ENB_H_CLR_REG, \
_bits)
#define CLK_GATE_U(_name, _parent, _bits) \
CLK_GATE(_name, _parent, \
CAR_CLK_ENB_U_SET_REG, CAR_CLK_ENB_U_CLR_REG, \
_bits)
#define CLK_GATE_V(_name, _parent, _bits) \
CLK_GATE(_name, _parent, \
CAR_CLK_ENB_V_SET_REG, CAR_CLK_ENB_V_CLR_REG, \
_bits)
#define CLK_GATE_W(_name, _parent, _bits) \
CLK_GATE(_name, _parent, \
CAR_CLK_ENB_W_SET_REG, CAR_CLK_ENB_W_CLR_REG, \
_bits)
#define CLK_GATE_X(_name, _parent, _bits) \
CLK_GATE(_name, _parent, \
CAR_CLK_ENB_X_SET_REG, CAR_CLK_ENB_X_CLR_REG, \
_bits)
#define CLK_GATE_SIMPLE(_name, _parent, _reg, _bits) \
CLK_GATE(_name, _parent, _reg, _reg, _bits)
static const char *mux_uart_p[] =
{ "pll_p_out0", "pll_c2_out0", "pll_c_out0", "pll_c3_out0",
"pll_m_out0", NULL, "clk_m" };
static const char *mux_sdmmc_p[] =
{ "pll_p_out0", "pll_c2_out0", "pll_c_out0", "pll_c3_out0",
"pll_m_out0", "pll_e_out0", "clk_m" };
static const char *mux_i2c_p[] =
{ "pll_p_out0", "pll_c2_out0", "pll_c_out0", "pll_c3_out0",
"pll_m_out0", NULL, "clk_m" };
static const char *mux_sata_p[] =
{ "pll_p_out0", NULL, "pll_c_out0", NULL, "pll_m_out0", NULL, "clk_m" };
static const char *mux_hda_p[] =
{ "pll_p_out0", "pll_c2_out0", "pll_c_out0", "pll_c3_out0",
"pll_m_out0", NULL, "clk_m" };
static const char *mux_tsensor_p[] =
{ "pll_p_out0", "pll_c2_out0", "pll_c_out0", "pll_c3_out0", "clk_m",
NULL, "clk_s" };
static const char *mux_soc_therm_p[] =
{ "pll_m_out0", "pll_c_out0", "pll_p_out0", "pll_a_out0", "pll_c2_out0",
"pll_c3_out0" };
static const char *mux_host1x_p[] =
{ "pll_m_out0", "pll_c2_out0", "pll_c_out0", "pll_c3_out0",
"pll_p_out0", NULL, "pll_a_out0" };
static const char *mux_disp_p[] =
{ "pll_p_out0", "pll_m_out0", "pll_d_out0", "pll_a_out0", "pll_c_out0",
"pll_d2_out0", "clk_m" };
static const char *mux_hdmi_p[] =
{ "pll_p_out0", "pll_m_out0", "pll_d_out0", "pll_a_out0", "pll_c_out0",
"pll_d2_out0", "clk_m" };
static struct tegra_clk tegra124_car_clocks[] = {
CLK_FIXED("clk_m", TEGRA_REF_FREQ),
CLK_PLL("pll_p", "clk_m", CAR_PLLP_BASE_REG,
CAR_PLLP_BASE_DIVM, CAR_PLLP_BASE_DIVN, CAR_PLLP_BASE_DIVP),
CLK_PLL("pll_c", "clk_m", CAR_PLLC_BASE_REG,
CAR_PLLC_BASE_DIVM, CAR_PLLC_BASE_DIVN, CAR_PLLC_BASE_DIVP),
CLK_PLL("pll_u", "clk_m", CAR_PLLU_BASE_REG,
CAR_PLLU_BASE_DIVM, CAR_PLLU_BASE_DIVN, CAR_PLLU_BASE_VCO_FREQ),
CLK_PLL("pll_x", "clk_m", CAR_PLLX_BASE_REG,
CAR_PLLX_BASE_DIVM, CAR_PLLX_BASE_DIVN, CAR_PLLX_BASE_DIVP),
CLK_PLL("pll_e", "clk_m", CAR_PLLE_BASE_REG,
CAR_PLLE_BASE_DIVM, CAR_PLLE_BASE_DIVN, CAR_PLLE_BASE_DIVP_CML),
CLK_PLL("pll_d", "clk_m", CAR_PLLD_BASE_REG,
CAR_PLLD_BASE_DIVM, CAR_PLLD_BASE_DIVN, CAR_PLLD_BASE_DIVP),
CLK_PLL("pll_d2", "clk_m", CAR_PLLD2_BASE_REG,
CAR_PLLD2_BASE_DIVM, CAR_PLLD2_BASE_DIVN, CAR_PLLD2_BASE_DIVP),
CLK_FIXED_DIV("pll_p_out0", "pll_p", 1),
CLK_FIXED_DIV("pll_u_480", "pll_u", 1),
CLK_FIXED_DIV("pll_u_60", "pll_u", 8),
CLK_FIXED_DIV("pll_u_48", "pll_u", 10),
CLK_FIXED_DIV("pll_u_12", "pll_u", 40),
CLK_FIXED_DIV("pll_d_out", "pll_d", 1),
CLK_FIXED_DIV("pll_d_out0", "pll_d", 2),
CLK_FIXED_DIV("pll_d2_out0", "pll_d2", 1),
CLK_MUX("mux_uarta", CAR_CLKSRC_UARTA_REG, CAR_CLKSRC_UART_SRC,
mux_uart_p),
CLK_MUX("mux_uartb", CAR_CLKSRC_UARTB_REG, CAR_CLKSRC_UART_SRC,
mux_uart_p),
CLK_MUX("mux_uartc", CAR_CLKSRC_UARTC_REG, CAR_CLKSRC_UART_SRC,
mux_uart_p),
CLK_MUX("mux_uartd", CAR_CLKSRC_UARTD_REG, CAR_CLKSRC_UART_SRC,
mux_uart_p),
CLK_MUX("mux_sdmmc1", CAR_CLKSRC_SDMMC1_REG, CAR_CLKSRC_SDMMC_SRC,
mux_sdmmc_p),
CLK_MUX("mux_sdmmc2", CAR_CLKSRC_SDMMC2_REG, CAR_CLKSRC_SDMMC_SRC,
mux_sdmmc_p),
CLK_MUX("mux_sdmmc3", CAR_CLKSRC_SDMMC3_REG, CAR_CLKSRC_SDMMC_SRC,
mux_sdmmc_p),
CLK_MUX("mux_sdmmc4", CAR_CLKSRC_SDMMC4_REG, CAR_CLKSRC_SDMMC_SRC,
mux_sdmmc_p),
CLK_MUX("mux_i2c1", CAR_CLKSRC_I2C1_REG, CAR_CLKSRC_I2C_SRC, mux_i2c_p),
CLK_MUX("mux_i2c2", CAR_CLKSRC_I2C2_REG, CAR_CLKSRC_I2C_SRC, mux_i2c_p),
CLK_MUX("mux_i2c3", CAR_CLKSRC_I2C3_REG, CAR_CLKSRC_I2C_SRC, mux_i2c_p),
CLK_MUX("mux_i2c4", CAR_CLKSRC_I2C4_REG, CAR_CLKSRC_I2C_SRC, mux_i2c_p),
CLK_MUX("mux_i2c5", CAR_CLKSRC_I2C5_REG, CAR_CLKSRC_I2C_SRC, mux_i2c_p),
CLK_MUX("mux_i2c6", CAR_CLKSRC_I2C6_REG, CAR_CLKSRC_I2C_SRC, mux_i2c_p),
CLK_MUX("mux_sata_oob",
CAR_CLKSRC_SATA_OOB_REG, CAR_CLKSRC_SATA_OOB_SRC, mux_sata_p),
CLK_MUX("mux_sata",
CAR_CLKSRC_SATA_REG, CAR_CLKSRC_SATA_SRC, mux_sata_p),
CLK_MUX("mux_hda2codec_2x",
CAR_CLKSRC_HDA2CODEC_2X_REG, CAR_CLKSRC_HDA2CODEC_2X_SRC,
mux_hda_p),
CLK_MUX("mux_hda",
CAR_CLKSRC_HDA_REG, CAR_CLKSRC_HDA_SRC, mux_hda_p),
CLK_MUX("mux_soc_therm",
CAR_CLKSRC_SOC_THERM_REG, CAR_CLKSRC_SOC_THERM_SRC,
mux_soc_therm_p),
CLK_MUX("mux_tsensor",
CAR_CLKSRC_TSENSOR_REG, CAR_CLKSRC_TSENSOR_SRC,
mux_tsensor_p),
CLK_MUX("mux_host1x",
CAR_CLKSRC_HOST1X_REG, CAR_CLKSRC_HOST1X_SRC,
mux_host1x_p),
CLK_MUX("mux_disp1",
CAR_CLKSRC_DISP1_REG, CAR_CLKSRC_DISP_SRC,
mux_disp_p),
CLK_MUX("mux_disp2",
CAR_CLKSRC_DISP2_REG, CAR_CLKSRC_DISP_SRC,
mux_disp_p),
CLK_MUX("mux_hdmi",
CAR_CLKSRC_HDMI_REG, CAR_CLKSRC_HDMI_SRC,
mux_hdmi_p),
CLK_DIV("div_uarta", "mux_uarta",
CAR_CLKSRC_UARTA_REG, CAR_CLKSRC_UART_DIV),
CLK_DIV("div_uartb", "mux_uartb",
CAR_CLKSRC_UARTB_REG, CAR_CLKSRC_UART_DIV),
CLK_DIV("div_uartc", "mux_uartc",
CAR_CLKSRC_UARTC_REG, CAR_CLKSRC_UART_DIV),
CLK_DIV("div_uartd", "mux_uartd",
CAR_CLKSRC_UARTD_REG, CAR_CLKSRC_UART_DIV),
CLK_DIV("div_sdmmc1", "mux_sdmmc1",
CAR_CLKSRC_SDMMC1_REG, CAR_CLKSRC_SDMMC_DIV),
CLK_DIV("div_sdmmc2", "mux_sdmmc2",
CAR_CLKSRC_SDMMC2_REG, CAR_CLKSRC_SDMMC_DIV),
CLK_DIV("div_sdmmc3", "mux_sdmmc3",
CAR_CLKSRC_SDMMC3_REG, CAR_CLKSRC_SDMMC_DIV),
CLK_DIV("div_sdmmc4", "mux_sdmmc4",
CAR_CLKSRC_SDMMC4_REG, CAR_CLKSRC_SDMMC_DIV),
CLK_DIV("div_i2c1", "mux_i2c1",
CAR_CLKSRC_I2C1_REG, CAR_CLKSRC_I2C_DIV),
CLK_DIV("div_i2c2", "mux_i2c2",
CAR_CLKSRC_I2C2_REG, CAR_CLKSRC_I2C_DIV),
CLK_DIV("div_i2c3", "mux_i2c3",
CAR_CLKSRC_I2C3_REG, CAR_CLKSRC_I2C_DIV),
CLK_DIV("div_i2c4", "mux_i2c4",
CAR_CLKSRC_I2C4_REG, CAR_CLKSRC_I2C_DIV),
CLK_DIV("div_i2c5", "mux_i2c5",
CAR_CLKSRC_I2C5_REG, CAR_CLKSRC_I2C_DIV),
CLK_DIV("div_i2c6", "mux_i2c6",
CAR_CLKSRC_I2C6_REG, CAR_CLKSRC_I2C_DIV),
CLK_DIV("div_sata_oob", "mux_sata_oob",
CAR_CLKSRC_SATA_OOB_REG, CAR_CLKSRC_SATA_OOB_DIV),
CLK_DIV("div_sata", "mux_sata",
CAR_CLKSRC_SATA_REG, CAR_CLKSRC_SATA_DIV),
CLK_DIV("div_hda2codec_2x", "mux_hda2codec_2x",
CAR_CLKSRC_HDA2CODEC_2X_REG, CAR_CLKSRC_HDA2CODEC_2X_DIV),
CLK_DIV("div_hda", "mux_hda",
CAR_CLKSRC_HDA_REG, CAR_CLKSRC_HDA_DIV),
CLK_DIV("div_soc_therm", "mux_soc_therm",
CAR_CLKSRC_SOC_THERM_REG, CAR_CLKSRC_SOC_THERM_DIV),
CLK_DIV("div_tsensor", "mux_tsensor",
CAR_CLKSRC_TSENSOR_REG, CAR_CLKSRC_TSENSOR_DIV),
CLK_DIV("div_host1x", "mux_host1x",
CAR_CLKSRC_HOST1X_REG, CAR_CLKSRC_HOST1X_CLK_DIVISOR),
CLK_DIV("div_hdmi", "mux_hdmi",
CAR_CLKSRC_HDMI_REG, CAR_CLKSRC_HDMI_DIV),
CLK_DIV("div_pll_p_out5", "pll_p",
CAR_PLLP_OUTC_REG, CAR_PLLP_OUTC_OUT5_RATIO),
CLK_GATE_L("uarta", "div_uarta", CAR_DEV_L_UARTA),
CLK_GATE_L("uartb", "div_uartb", CAR_DEV_L_UARTB),
CLK_GATE_H("uartc", "div_uartc", CAR_DEV_H_UARTC),
CLK_GATE_U("uartd", "div_uartd", CAR_DEV_U_UARTD),
CLK_GATE_L("sdmmc1", "div_sdmmc1", CAR_DEV_L_SDMMC1),
CLK_GATE_L("sdmmc2", "div_sdmmc2", CAR_DEV_L_SDMMC2),
CLK_GATE_U("sdmmc3", "div_sdmmc3", CAR_DEV_U_SDMMC3),
CLK_GATE_L("sdmmc4", "div_sdmmc4", CAR_DEV_L_SDMMC4),
CLK_GATE_L("i2c1", "div_i2c1", CAR_DEV_L_I2C1),
CLK_GATE_H("i2c2", "div_i2c2", CAR_DEV_H_I2C2),
CLK_GATE_U("i2c3", "div_i2c3", CAR_DEV_U_I2C3),
CLK_GATE_V("i2c4", "div_i2c4", CAR_DEV_V_I2C4),
CLK_GATE_H("i2c5", "div_i2c5", CAR_DEV_H_I2C5),
CLK_GATE_X("i2c6", "div_i2c6", CAR_DEV_X_I2C6),
CLK_GATE_L("usbd", "pll_u_480", CAR_DEV_L_USBD),
CLK_GATE_H("usb2", "pll_u_480", CAR_DEV_H_USB2),
CLK_GATE_H("usb3", "pll_u_480", CAR_DEV_H_USB3),
CLK_GATE_V("sata_oob", "div_sata_oob", CAR_DEV_V_SATA_OOB),
CLK_GATE_V("sata", "div_sata", CAR_DEV_V_SATA),
CLK_GATE_SIMPLE("cml0", "pll_e",
CAR_PLLE_AUX_REG, CAR_PLLE_AUX_CML0_OEN),
CLK_GATE_SIMPLE("cml1", "pll_e",
CAR_PLLE_AUX_REG, CAR_PLLE_AUX_CML1_OEN),
CLK_GATE_V("hda2codec_2x", "div_hda2codec_2x", CAR_DEV_V_HDA2CODEC_2X),
CLK_GATE_V("hda", "div_hda", CAR_DEV_V_HDA),
CLK_GATE_W("hda2hdmi", "clk_m", CAR_DEV_W_HDA2HDMICODEC),
CLK_GATE_H("fuse", "clk_m", CAR_DEV_H_FUSE),
CLK_GATE_U("soc_therm", "div_soc_therm", CAR_DEV_U_SOC_THERM),
CLK_GATE_V("tsensor", "div_tsensor", CAR_DEV_V_TSENSOR),
CLK_GATE_SIMPLE("watchdog", "clk_m", CAR_RST_SOURCE_REG,
CAR_RST_SOURCE_WDT_EN|CAR_RST_SOURCE_WDT_SYS_RST_EN),
CLK_GATE_L("host1x", "div_host1x", CAR_DEV_L_HOST1X),
CLK_GATE_L("disp1", "mux_disp1", CAR_DEV_L_DISP1),
CLK_GATE_L("disp2", "mux_disp2", CAR_DEV_L_DISP2),
CLK_GATE_H("hdmi", "div_hdmi", CAR_DEV_H_HDMI),
CLK_GATE_SIMPLE("pll_p_out5", "div_pllp_out5",
CAR_PLLP_OUTC_REG, CAR_PLLP_OUTC_OUT5_CLKEN),
};
struct tegra124_car_rst {
u_int set_reg;
u_int clr_reg;
u_int mask;
};
static struct tegra124_car_reset_reg {
u_int set_reg;
u_int clr_reg;
} tegra124_car_reset_regs[] = {
{ CAR_RST_DEV_L_SET_REG, CAR_RST_DEV_L_CLR_REG },
{ CAR_RST_DEV_H_SET_REG, CAR_RST_DEV_H_CLR_REG },
{ CAR_RST_DEV_U_SET_REG, CAR_RST_DEV_U_CLR_REG },
{ CAR_RST_DEV_V_SET_REG, CAR_RST_DEV_V_CLR_REG },
{ CAR_RST_DEV_W_SET_REG, CAR_RST_DEV_W_CLR_REG },
{ CAR_RST_DEV_X_SET_REG, CAR_RST_DEV_X_CLR_REG },
};
static void * tegra124_car_reset_acquire(device_t, const void *, size_t);
static void tegra124_car_reset_release(device_t, void *);
static int tegra124_car_reset_assert(device_t, void *);
static int tegra124_car_reset_deassert(device_t, void *);
static const struct fdtbus_reset_controller_func tegra124_car_fdtreset_funcs = {
.acquire = tegra124_car_reset_acquire,
.release = tegra124_car_reset_release,
.reset_assert = tegra124_car_reset_assert,
.reset_deassert = tegra124_car_reset_deassert,
};
struct tegra124_car_softc {
device_t sc_dev;
bus_space_tag_t sc_bst;
bus_space_handle_t sc_bsh;
u_int sc_clock_cells;
u_int sc_reset_cells;
kmutex_t sc_intr_lock;
kmutex_t sc_rnd_lock;
u_int sc_bytes_wanted;
void *sc_sih;
krndsource_t sc_rndsource;
};
static void tegra124_car_init(struct tegra124_car_softc *);
static void tegra124_car_utmip_init(struct tegra124_car_softc *);
static void tegra124_car_rnd_attach(device_t);
static void tegra124_car_rnd_intr(void *);
static void tegra124_car_rnd_callback(size_t, void *);
CFATTACH_DECL_NEW(tegra124_car, sizeof(struct tegra124_car_softc),
tegra124_car_match, tegra124_car_attach, NULL, NULL);
static int
tegra124_car_match(device_t parent, cfdata_t cf, void *aux)
{
const char * const compatible[] = { "nvidia,tegra124-car", NULL };
struct fdt_attach_args * const faa = aux;
#if 0
return of_match_compatible(faa->faa_phandle, compatible);
#else
if (of_match_compatible(faa->faa_phandle, compatible) == 0)
return 0;
return 999;
#endif
}
static void
tegra124_car_attach(device_t parent, device_t self, void *aux)
{
struct tegra124_car_softc * const sc = device_private(self);
struct fdt_attach_args * const faa = aux;
const int phandle = faa->faa_phandle;
bus_addr_t addr;
bus_size_t size;
int error;
if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
aprint_error(": couldn't get registers\n");
return;
}
sc->sc_dev = self;
sc->sc_bst = faa->faa_bst;
error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh);
if (error) {
aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error);
return;
}
if (of_getprop_uint32(phandle, "#clock-cells", &sc->sc_clock_cells))
sc->sc_clock_cells = 1;
if (of_getprop_uint32(phandle, "#reset-cells", &sc->sc_reset_cells))
sc->sc_reset_cells = 1;
aprint_naive("\n");
aprint_normal(": CAR\n");
clk_backend_register("tegra124", &tegra124_car_clock_funcs, sc);
fdtbus_register_clock_controller(self, phandle,
&tegra124_car_fdtclock_funcs);
fdtbus_register_reset_controller(self, phandle,
&tegra124_car_fdtreset_funcs);
tegra124_car_init(sc);
config_interrupts(self, tegra124_car_rnd_attach);
}
static void
tegra124_car_init(struct tegra124_car_softc *sc)
{
tegra124_car_utmip_init(sc);
}
static void
tegra124_car_utmip_init(struct tegra124_car_softc *sc)
{
bus_space_tag_t bst = sc->sc_bst;
bus_space_handle_t bsh = sc->sc_bsh;
const u_int enable_dly_count = 0x02;
const u_int stable_count = 0x2f;
const u_int active_dly_count = 0x04;
const u_int xtal_freq_count = 0x76;
tegra_reg_set_clear(bst, bsh, CAR_UTMIP_PLL_CFG2_REG,
__SHIFTIN(stable_count, CAR_UTMIP_PLL_CFG2_STABLE_COUNT) |
__SHIFTIN(active_dly_count, CAR_UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT),
CAR_UTMIP_PLL_CFG2_PD_SAMP_A_POWERDOWN |
CAR_UTMIP_PLL_CFG2_PD_SAMP_B_POWERDOWN |
CAR_UTMIP_PLL_CFG2_PD_SAMP_C_POWERDOWN |
CAR_UTMIP_PLL_CFG2_STABLE_COUNT |
CAR_UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT);
tegra_reg_set_clear(bst, bsh, CAR_UTMIP_PLL_CFG1_REG,
__SHIFTIN(enable_dly_count, CAR_UTMIP_PLL_CFG1_ENABLE_DLY_COUNT) |
__SHIFTIN(xtal_freq_count, CAR_UTMIP_PLL_CFG1_XTAL_FREQ_COUNT),
CAR_UTMIP_PLL_CFG1_ENABLE_DLY_COUNT |
CAR_UTMIP_PLL_CFG1_XTAL_FREQ_COUNT);
tegra_reg_set_clear(bst, bsh, CAR_UTMIP_PLL_CFG1_REG,
0,
CAR_UTMIP_PLL_CFG1_PLLU_POWERDOWN |
CAR_UTMIP_PLL_CFG1_PLL_ENABLE_POWERDOWN);
}
static void
tegra124_car_rnd_attach(device_t self)
{
struct tegra124_car_softc * const sc = device_private(self);
mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SERIAL);
mutex_init(&sc->sc_rnd_lock, MUTEX_DEFAULT, IPL_SERIAL);
sc->sc_bytes_wanted = 0;
sc->sc_sih = softint_establish(SOFTINT_SERIAL|SOFTINT_MPSAFE,
tegra124_car_rnd_intr, sc);
if (sc->sc_sih == NULL) {
aprint_error_dev(sc->sc_dev, "couldn't establish softint\n");
return;
}
rndsource_setcb(&sc->sc_rndsource, tegra124_car_rnd_callback, sc);
rnd_attach_source(&sc->sc_rndsource, device_xname(sc->sc_dev),
RND_TYPE_RNG, RND_FLAG_COLLECT_VALUE|RND_FLAG_HASCB);
}
static void
tegra124_car_rnd_intr(void *priv)
{
struct tegra124_car_softc * const sc = priv;
uint16_t buf[512];
uint32_t cnt;
mutex_enter(&sc->sc_intr_lock);
while (sc->sc_bytes_wanted) {
const u_int nbytes = MIN(sc->sc_bytes_wanted, 1024);
for (cnt = 0; cnt < sc->sc_bytes_wanted / 2; cnt++) {
buf[cnt] = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
CAR_PLL_LFSR_REG) & 0xffff;
}
mutex_exit(&sc->sc_intr_lock);
mutex_enter(&sc->sc_rnd_lock);
rnd_add_data(&sc->sc_rndsource, buf, nbytes, nbytes * NBBY);
mutex_exit(&sc->sc_rnd_lock);
mutex_enter(&sc->sc_intr_lock);
sc->sc_bytes_wanted -= MIN(sc->sc_bytes_wanted, nbytes);
}
explicit_memset(buf, 0, sizeof(buf));
mutex_exit(&sc->sc_intr_lock);
}
static void
tegra124_car_rnd_callback(size_t bytes_wanted, void *priv)
{
struct tegra124_car_softc * const sc = priv;
mutex_enter(&sc->sc_intr_lock);
if (sc->sc_bytes_wanted == 0) {
softint_schedule(sc->sc_sih);
}
if (bytes_wanted > (UINT_MAX - sc->sc_bytes_wanted)) {
sc->sc_bytes_wanted = UINT_MAX;
} else {
sc->sc_bytes_wanted += bytes_wanted;
}
mutex_exit(&sc->sc_intr_lock);
}
static struct tegra_clk *
tegra124_car_clock_find(const char *name)
{
u_int n;
for (n = 0; n < __arraycount(tegra124_car_clocks); n++) {
if (strcmp(tegra124_car_clocks[n].base.name, name) == 0) {
return &tegra124_car_clocks[n];
}
}
return NULL;
}
static struct tegra_clk *
tegra124_car_clock_find_by_id(u_int clock_id)
{
u_int n;
for (n = 0; n < __arraycount(tegra124_car_clock_ids); n++) {
if (tegra124_car_clock_ids[n].id == clock_id) {
const char *name = tegra124_car_clock_ids[n].name;
return tegra124_car_clock_find(name);
}
}
return NULL;
}
static struct clk *
tegra124_car_clock_decode(device_t dev, const void *data, size_t len)
{
struct tegra124_car_softc * const sc = device_private(dev);
struct tegra_clk *tclk;
if (len != sc->sc_clock_cells * 4) {
return NULL;
}
const u_int clock_id = be32dec(data);
tclk = tegra124_car_clock_find_by_id(clock_id);
if (tclk)
return TEGRA_CLK_BASE(tclk);
return NULL;
}
static struct clk *
tegra124_car_clock_get(void *priv, const char *name)
{
struct tegra_clk *tclk;
tclk = tegra124_car_clock_find(name);
if (tclk == NULL)
return NULL;
atomic_inc_uint(&tclk->refcnt);
return TEGRA_CLK_BASE(tclk);
}
static void
tegra124_car_clock_put(void *priv, struct clk *clk)
{
struct tegra_clk *tclk = TEGRA_CLK_PRIV(clk);
KASSERT(tclk->refcnt > 0);
atomic_dec_uint(&tclk->refcnt);
}
static u_int
tegra124_car_clock_get_rate_pll(struct tegra124_car_softc *sc,
struct tegra_clk *tclk)
{
struct tegra_pll_clk *tpll = &tclk->u.pll;
struct tegra_clk *tclk_parent;
bus_space_tag_t bst = sc->sc_bst;
bus_space_handle_t bsh = sc->sc_bsh;
u_int divm, divn, divp;
uint64_t rate;
KASSERT(tclk->type == TEGRA_CLK_PLL);
tclk_parent = tegra124_car_clock_find(tclk->parent);
KASSERT(tclk_parent != NULL);
const u_int rate_parent = tegra124_car_clock_get_rate(sc,
TEGRA_CLK_BASE(tclk_parent));
const uint32_t base = bus_space_read_4(bst, bsh, tpll->base_reg);
divm = __SHIFTOUT(base, tpll->divm_mask);
divn = __SHIFTOUT(base, tpll->divn_mask);
if (tpll->base_reg == CAR_PLLU_BASE_REG) {
divp = __SHIFTOUT(base, tpll->divp_mask) ? 0 : 1;
} else {
divp = __SHIFTOUT(base, tpll->divp_mask);
}
rate = (uint64_t)rate_parent * divn;
return rate / (divm << divp);
}
static int
tegra124_car_clock_set_rate_pll(struct tegra124_car_softc *sc,
struct tegra_clk *tclk, u_int rate)
{
struct tegra_pll_clk *tpll = &tclk->u.pll;
bus_space_tag_t bst = sc->sc_bst;
bus_space_handle_t bsh = sc->sc_bsh;
struct clk *clk_parent;
uint32_t bp, base;
clk_parent = tegra124_car_clock_get_parent(sc, TEGRA_CLK_BASE(tclk));
if (clk_parent == NULL)
return EIO;
const u_int rate_parent = tegra124_car_clock_get_rate(sc, clk_parent);
if (rate_parent == 0)
return EIO;
if (tpll->base_reg == CAR_PLLX_BASE_REG) {
const u_int divm = 1;
const u_int divn = rate / rate_parent;
const u_int divp = 0;
bp = bus_space_read_4(bst, bsh, CAR_CCLKG_BURST_POLICY_REG);
bp &= ~CAR_CCLKG_BURST_POLICY_CPU_STATE;
bp |= __SHIFTIN(CAR_CCLKG_BURST_POLICY_CPU_STATE_IDLE,
CAR_CCLKG_BURST_POLICY_CPU_STATE);
bp &= ~CAR_CCLKG_BURST_POLICY_CWAKEUP_IDLE_SOURCE;
bp |= __SHIFTIN(CAR_CCLKG_BURST_POLICY_CWAKEUP_SOURCE_CLKM,
CAR_CCLKG_BURST_POLICY_CWAKEUP_IDLE_SOURCE);
bus_space_write_4(bst, bsh, CAR_CCLKG_BURST_POLICY_REG, bp);
base = bus_space_read_4(bst, bsh, CAR_PLLX_BASE_REG);
base &= ~CAR_PLLX_BASE_DIVM;
base &= ~CAR_PLLX_BASE_DIVN;
base &= ~CAR_PLLX_BASE_DIVP;
base |= __SHIFTIN(divm, CAR_PLLX_BASE_DIVM);
base |= __SHIFTIN(divn, CAR_PLLX_BASE_DIVN);
base |= __SHIFTIN(divp, CAR_PLLX_BASE_DIVP);
bus_space_write_4(bst, bsh, CAR_PLLX_BASE_REG, base);
tegra_reg_set_clear(bst, bsh, CAR_PLLX_MISC_REG,
CAR_PLLX_MISC_LOCK_ENABLE, 0);
do {
delay(2);
base = bus_space_read_4(bst, bsh, tpll->base_reg);
} while ((base & CAR_PLLX_BASE_LOCK) == 0);
delay(100);
bp &= ~CAR_CCLKG_BURST_POLICY_CPU_STATE;
bp |= __SHIFTIN(CAR_CCLKG_BURST_POLICY_CPU_STATE_RUN,
CAR_CCLKG_BURST_POLICY_CPU_STATE);
bp &= ~CAR_CCLKG_BURST_POLICY_CWAKEUP_IDLE_SOURCE;
bp |= __SHIFTIN(CAR_CCLKG_BURST_POLICY_CWAKEUP_SOURCE_PLLX_OUT0_LJ,
CAR_CCLKG_BURST_POLICY_CWAKEUP_IDLE_SOURCE);
bus_space_write_4(bst, bsh, CAR_CCLKG_BURST_POLICY_REG, bp);
return 0;
} else if (tpll->base_reg == CAR_PLLD2_BASE_REG) {
const u_int divm = 1;
const u_int pldiv = 1;
const u_int divn = (rate << pldiv) / rate_parent;
/* Set frequency */
tegra_reg_set_clear(bst, bsh, tpll->base_reg,
__SHIFTIN(divm, CAR_PLLD2_BASE_DIVM) |
__SHIFTIN(divn, CAR_PLLD2_BASE_DIVN) |
__SHIFTIN(pldiv, CAR_PLLD2_BASE_DIVP),
CAR_PLLD2_BASE_REF_SRC_SEL |
CAR_PLLD2_BASE_DIVM |
CAR_PLLD2_BASE_DIVN |
CAR_PLLD2_BASE_DIVP);
return 0;
} else {
/* TODO */
return EOPNOTSUPP;
}
}
static int
tegra124_car_clock_set_parent_mux(struct tegra124_car_softc *sc,
struct tegra_clk *tclk, struct tegra_clk *tclk_parent)
{
struct tegra_mux_clk *tmux = &tclk->u.mux;
bus_space_tag_t bst = sc->sc_bst;
bus_space_handle_t bsh = sc->sc_bsh;
uint32_t v;
u_int src;
KASSERT(tclk->type == TEGRA_CLK_MUX);
for (src = 0; src < tmux->nparents; src++) {
if (tmux->parents[src] == NULL) {
continue;
}
if (strcmp(tmux->parents[src], tclk_parent->base.name) == 0) {
break;
}
}
if (src == tmux->nparents) {
return EINVAL;
}
if (tmux->reg == CAR_CLKSRC_HDMI_REG &&
src == CAR_CLKSRC_HDMI_SRC_PLLD2_OUT0) {
/* Change IDDQ from 1 to 0 */
tegra_reg_set_clear(bst, bsh, CAR_PLLD2_BASE_REG,
0, CAR_PLLD2_BASE_IDDQ);
delay(2);
/* Enable lock */
tegra_reg_set_clear(bst, bsh, CAR_PLLD2_MISC_REG,
CAR_PLLD2_MISC_LOCK_ENABLE, 0);
/* Enable PLLD2 */
tegra_reg_set_clear(bst, bsh, CAR_PLLD2_BASE_REG,
CAR_PLLD2_BASE_ENABLE, 0);
/* Wait for lock */
do {
delay(2);
v = bus_space_read_4(bst, bsh, CAR_PLLD2_BASE_REG);
} while ((v & CAR_PLLD2_BASE_LOCK) == 0);
delay(200);
}
v = bus_space_read_4(bst, bsh, tmux->reg);
v &= ~tmux->bits;
v |= __SHIFTIN(src, tmux->bits);
bus_space_write_4(bst, bsh, tmux->reg, v);
return 0;
}
static struct tegra_clk *
tegra124_car_clock_get_parent_mux(struct tegra124_car_softc *sc,
struct tegra_clk *tclk)
{
struct tegra_mux_clk *tmux = &tclk->u.mux;
bus_space_tag_t bst = sc->sc_bst;
bus_space_handle_t bsh = sc->sc_bsh;
KASSERT(tclk->type == TEGRA_CLK_MUX);
const uint32_t v = bus_space_read_4(bst, bsh, tmux->reg);
const u_int src = __SHIFTOUT(v, tmux->bits);
KASSERT(src < tmux->nparents);
if (tmux->parents[src] == NULL) {
return NULL;
}
return tegra124_car_clock_find(tmux->parents[src]);
}
static u_int
tegra124_car_clock_get_rate_fixed_div(struct tegra124_car_softc *sc,
struct tegra_clk *tclk)
{
struct tegra_fixed_div_clk *tfixed_div = &tclk->u.fixed_div;
struct clk *clk_parent;
clk_parent = tegra124_car_clock_get_parent(sc, TEGRA_CLK_BASE(tclk));
if (clk_parent == NULL)
return 0;
const u_int parent_rate = tegra124_car_clock_get_rate(sc, clk_parent);
return parent_rate / tfixed_div->div;
}
static u_int
tegra124_car_clock_get_rate_div(struct tegra124_car_softc *sc,
struct tegra_clk *tclk)
{
struct tegra_div_clk *tdiv = &tclk->u.div;
bus_space_tag_t bst = sc->sc_bst;
bus_space_handle_t bsh = sc->sc_bsh;
struct clk *clk_parent;
u_int div;
KASSERT(tclk->type == TEGRA_CLK_DIV);
clk_parent = tegra124_car_clock_get_parent(sc, TEGRA_CLK_BASE(tclk));
const u_int parent_rate = tegra124_car_clock_get_rate(sc, clk_parent);
const uint32_t v = bus_space_read_4(bst, bsh, tdiv->reg);
const u_int raw_div = __SHIFTOUT(v, tdiv->bits);
switch (tdiv->reg) {
case CAR_CLKSRC_UARTA_REG:
case CAR_CLKSRC_UARTB_REG:
case CAR_CLKSRC_UARTC_REG:
case CAR_CLKSRC_UARTD_REG:
if (v & CAR_CLKSRC_UART_DIV_ENB) {
div = raw_div * 2;
} else {
div = 2;
}
break;
default:
div = raw_div * 2;
break;
}
return (parent_rate * 2) / div;
}
static int
tegra124_car_clock_set_rate_div(struct tegra124_car_softc *sc,
struct tegra_clk *tclk, u_int rate)
{
struct tegra_div_clk *tdiv = &tclk->u.div;
bus_space_tag_t bst = sc->sc_bst;
bus_space_handle_t bsh = sc->sc_bsh;
struct clk *clk_parent;
uint32_t v;
KASSERT(tclk->type == TEGRA_CLK_DIV);
clk_parent = tegra124_car_clock_get_parent(sc, TEGRA_CLK_BASE(tclk));
if (clk_parent == NULL)
return EINVAL;
const u_int parent_rate = tegra124_car_clock_get_rate(sc, clk_parent);
v = bus_space_read_4(bst, bsh, tdiv->reg);
switch (tdiv->reg) {
case CAR_CLKSRC_UARTA_REG:
case CAR_CLKSRC_UARTB_REG:
case CAR_CLKSRC_UARTC_REG:
case CAR_CLKSRC_UARTD_REG:
if (rate == parent_rate) {
v &= ~CAR_CLKSRC_UART_DIV_ENB;
} else {
v |= CAR_CLKSRC_UART_DIV_ENB;
}
break;
case CAR_CLKSRC_SATA_REG:
if (rate) {
tegra_reg_set_clear(bst, bsh, CAR_SATA_PLL_CFG0_REG,
0, CAR_SATA_PLL_CFG0_PADPLL_RESET_SWCTL);
v |= CAR_CLKSRC_SATA_AUX_CLK_ENB;
} else {
v &= ~CAR_CLKSRC_SATA_AUX_CLK_ENB;
}
break;
case CAR_CLKSRC_HDMI_REG:
break;
}
const u_int raw_div = rate ? howmany(parent_rate * 2, rate) - 2 : 0;
//const u_int raw_div = rate ? (parent_rate * 2) / rate - 2 : 0;
v &= ~tdiv->bits;
v |= __SHIFTIN(raw_div, tdiv->bits);
bus_space_write_4(bst, bsh, tdiv->reg, v);
return 0;
}
static int
tegra124_car_clock_enable_gate(struct tegra124_car_softc *sc,
struct tegra_clk *tclk, bool enable)
{
struct tegra_gate_clk *tgate = &tclk->u.gate;
bus_space_tag_t bst = sc->sc_bst;
bus_space_handle_t bsh = sc->sc_bsh;
bus_size_t reg;
KASSERT(tclk->type == TEGRA_CLK_GATE);
if (tgate->set_reg == tgate->clr_reg) {
uint32_t v = bus_space_read_4(bst, bsh, tgate->set_reg);
if (enable) {
v |= tgate->bits;
} else {
v &= ~tgate->bits;
}
bus_space_write_4(bst, bsh, tgate->set_reg, v);
} else {
if (enable) {
reg = tgate->set_reg;
} else {
reg = tgate->clr_reg;
}
if (reg == CAR_CLK_ENB_V_SET_REG &&
tgate->bits == CAR_DEV_V_SATA) {
/* De-assert reset to SATA PADPLL */
tegra_reg_set_clear(bst, bsh, CAR_SATA_PLL_CFG0_REG,
0, CAR_SATA_PLL_CFG0_PADPLL_RESET_OVERRIDE_VALUE);
delay(15);
}
bus_space_write_4(bst, bsh, reg, tgate->bits);
}
return 0;
}
static u_int
tegra124_car_clock_get_rate(void *priv, struct clk *clk)
{
struct tegra_clk *tclk = TEGRA_CLK_PRIV(clk);
struct clk *clk_parent;
switch (tclk->type) {
case TEGRA_CLK_FIXED:
return tclk->u.fixed.rate;
case TEGRA_CLK_PLL:
return tegra124_car_clock_get_rate_pll(priv, tclk);
case TEGRA_CLK_MUX:
case TEGRA_CLK_GATE:
clk_parent = tegra124_car_clock_get_parent(priv, clk);
if (clk_parent == NULL)
return EINVAL;
return tegra124_car_clock_get_rate(priv, clk_parent);
case TEGRA_CLK_FIXED_DIV:
return tegra124_car_clock_get_rate_fixed_div(priv, tclk);
case TEGRA_CLK_DIV:
return tegra124_car_clock_get_rate_div(priv, tclk);
default:
panic("tegra124: unknown tclk type %d", tclk->type);
}
}
static int
tegra124_car_clock_set_rate(void *priv, struct clk *clk, u_int rate)
{
struct tegra_clk *tclk = TEGRA_CLK_PRIV(clk);
struct clk *clk_parent;
KASSERT((clk->flags & CLK_SET_RATE_PARENT) == 0);
switch (tclk->type) {
case TEGRA_CLK_FIXED:
case TEGRA_CLK_MUX:
return EIO;
case TEGRA_CLK_FIXED_DIV:
clk_parent = tegra124_car_clock_get_parent(priv, clk);
if (clk_parent == NULL)
return EIO;
return tegra124_car_clock_set_rate(priv, clk_parent,
rate * tclk->u.fixed_div.div);
case TEGRA_CLK_GATE:
return EINVAL;
case TEGRA_CLK_PLL:
return tegra124_car_clock_set_rate_pll(priv, tclk, rate);
case TEGRA_CLK_DIV:
return tegra124_car_clock_set_rate_div(priv, tclk, rate);
default:
panic("tegra124: unknown tclk type %d", tclk->type);
}
}
static int
tegra124_car_clock_enable(void *priv, struct clk *clk)
{
struct tegra_clk *tclk = TEGRA_CLK_PRIV(clk);
struct clk *clk_parent;
if (tclk->type != TEGRA_CLK_GATE) {
clk_parent = tegra124_car_clock_get_parent(priv, clk);
if (clk_parent == NULL)
return 0;
return tegra124_car_clock_enable(priv, clk_parent);
}
return tegra124_car_clock_enable_gate(priv, tclk, true);
}
static int
tegra124_car_clock_disable(void *priv, struct clk *clk)
{
struct tegra_clk *tclk = TEGRA_CLK_PRIV(clk);
if (tclk->type != TEGRA_CLK_GATE)
return EINVAL;
return tegra124_car_clock_enable_gate(priv, tclk, false);
}
static int
tegra124_car_clock_set_parent(void *priv, struct clk *clk,
struct clk *clk_parent)
{
struct tegra_clk *tclk = TEGRA_CLK_PRIV(clk);
struct tegra_clk *tclk_parent = TEGRA_CLK_PRIV(clk_parent);
struct clk *nclk_parent;
if (tclk->type != TEGRA_CLK_MUX) {
nclk_parent = tegra124_car_clock_get_parent(priv, clk);
if (nclk_parent == clk_parent || nclk_parent == NULL)
return EINVAL;
return tegra124_car_clock_set_parent(priv, nclk_parent,
clk_parent);
}
return tegra124_car_clock_set_parent_mux(priv, tclk, tclk_parent);
}
static struct clk *
tegra124_car_clock_get_parent(void *priv, struct clk *clk)
{
struct tegra_clk *tclk = TEGRA_CLK_PRIV(clk);
struct tegra_clk *tclk_parent = NULL;
switch (tclk->type) {
case TEGRA_CLK_FIXED:
case TEGRA_CLK_PLL:
case TEGRA_CLK_FIXED_DIV:
case TEGRA_CLK_DIV:
case TEGRA_CLK_GATE:
if (tclk->parent) {
tclk_parent = tegra124_car_clock_find(tclk->parent);
}
break;
case TEGRA_CLK_MUX:
tclk_parent = tegra124_car_clock_get_parent_mux(priv, tclk);
break;
}
if (tclk_parent == NULL)
return NULL;
return TEGRA_CLK_BASE(tclk_parent);
}
static void *
tegra124_car_reset_acquire(device_t dev, const void *data, size_t len)
{
struct tegra124_car_softc * const sc = device_private(dev);
struct tegra124_car_rst *rst;
if (len != sc->sc_reset_cells * 4)
return NULL;
const u_int reset_id = be32dec(data);
if (reset_id > __arraycount(tegra124_car_reset_regs) * 32)
return NULL;
const u_int reg = reset_id / 32;
rst = kmem_alloc(sizeof(*rst), KM_SLEEP);
rst->set_reg = tegra124_car_reset_regs[reg].set_reg;
rst->clr_reg = tegra124_car_reset_regs[reg].clr_reg;
rst->mask = __BIT(reset_id % 32);
return rst;
}
static void
tegra124_car_reset_release(device_t dev, void *priv)
{
struct tegra124_car_rst *rst = priv;
kmem_free(rst, sizeof(*rst));
}
static int
tegra124_car_reset_assert(device_t dev, void *priv)
{
struct tegra124_car_softc * const sc = device_private(dev);
struct tegra124_car_rst *rst = priv;
bus_space_write_4(sc->sc_bst, sc->sc_bsh, rst->set_reg, rst->mask);
return 0;
}
static int
tegra124_car_reset_deassert(device_t dev, void *priv)
{
struct tegra124_car_softc * const sc = device_private(dev);
struct tegra124_car_rst *rst = priv;
bus_space_write_4(sc->sc_bst, sc->sc_bsh, rst->clr_reg, rst->mask);
return 0;
}
/* $NetBSD: tegra124_carreg.h,v 1.1 2015/12/22 22:10:36 jmcneill Exp $ */
/*-
* Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _ARM_TEGRA124_CARREG_H
#define _ARM_TEGRA124_CARREG_H
#define CAR_RST_SOURCE_REG 0x00
#define CAR_RST_SOURCE_WDT_EN __BIT(5)
#define CAR_RST_SOURCE_WDT_SEL __BIT(4)
#define CAR_RST_SOURCE_WDT_SYS_RST_EN __BIT(2)
#define CAR_RST_SOURCE_WDT_COP_RST_EN __BIT(1)
#define CAR_RST_SOURCE_WDT_CPU_RST_EN __BIT(0)
#define CAR_CLK_OUT_ENB_L_REG 0x10
#define CAR_CLK_OUT_ENB_H_REG 0x14
#define CAR_CLK_OUT_ENB_U_REG 0x18
#define CAR_PLL_LFSR_REG 0x54
#define CAR_PLL_LFSR_RND __BITS(15,0)
#define CAR_PLLP_BASE_REG 0xa0
#define CAR_PLLP_BASE_BYPASS __BIT(31)
#define CAR_PLLP_BASE_ENABLE __BIT(30)
#define CAR_PLLP_BASE_REF_DIS __BIT(29)
#define CAR_PLLP_BASE_OVERRIDE __BIT(28)
#define CAR_PLLP_BASE_LOCK __BIT(27)
#define CAR_PLLP_BASE_DIVP __BITS(22,20)
#define CAR_PLLP_BASE_DIVN __BITS(17,8)
#define CAR_PLLP_BASE_DIVM __BITS(4,0)
#define CAR_PLLP_OUTA_REG 0xa4
#define CAR_PLLP_OUTB_REG 0xa8
#define CAR_PLLP_OUTB_OUT4_RATIO __BITS(31,24)
#define CAR_PLLP_OUTB_OUT4_OVRRIDE __BIT(18)
#define CAR_PLLP_OUTB_OUT4_CLKEN __BIT(17)
#define CAR_PLLP_OUTB_OUT4_RSTN __BIT(16)
#define CAR_PLLP_OUTB_OUT3_RATIO __BITS(15,8)
#define CAR_PLLP_OUTB_OUT3_OVRRIDE __BIT(2)
#define CAR_PLLP_OUTB_OUT3_CLKEN __BIT(1)
#define CAR_PLLP_OUTB_OUT3_RSTN __BIT(0)
#define CAR_PLLP_OUTC_REG 0x67c
#define CAR_PLLP_OUTC_OUT5_RATIO __BITS(31,24)
#define CAR_PLLP_OUTC_OUT5_OVERRIDE __BIT(18)
#define CAR_PLLP_OUTC_OUT5_CLKEN __BIT(17)
#define CAR_PLLP_OUTC_OUT5_RSTN __BIT(16)
#define CAR_PLLP_MISC_REG 0xac
#define CAR_PLLC_BASE_REG 0x80
#define CAR_PLLC_BASE_ENABLE __BIT(30)
#define CAR_PLLC_BASE_REF_DIS __BIT(29)
#define CAR_PLLC_BASE_LOCK_OVERRIDE __BIT(28)
#define CAR_PLLC_BASE_LOCK __BIT(27)
#define CAR_PLLC_BASE_DIVP __BITS(23,20)
#define CAR_PLLC_BASE_DIVN __BITS(15,8)
#define CAR_PLLC_BASE_DIVM __BITS(7,0)
#define CAR_PLLU_BASE_REG 0xc0
#define CAR_PLLU_BASE_BYPASS __BIT(31)
#define CAR_PLLU_BASE_ENABLE __BIT(30)
#define CAR_PLLU_BASE_REF_DIS __BIT(29)
#define CAR_PLLU_BASE_LOCK __BIT(27)
#define CAR_PLLU_BASE_CLKENABLE_48M __BIT(25)
#define CAR_PLLU_BASE_OVERRIDE __BIT(24)
#define CAR_PLLU_BASE_CLKENABLE_ICUSB __BIT(23)
#define CAR_PLLU_BASE_CLKENABLE_HSIC __BIT(22)
#define CAR_PLLU_BASE_CLKENABLE_USB __BIT(21)
#define CAR_PLLU_BASE_VCO_FREQ __BIT(20)
#define CAR_PLLU_BASE_DIVN __BITS(17,8)
#define CAR_PLLU_BASE_DIVM __BITS(4,0)
#define CAR_PLLD_BASE_REG 0xd0
#define CAR_PLLD_BASE_BYPASS __BIT(31)
#define CAR_PLLD_BASE_ENABLE __BIT(30)
#define CAR_PLLD_BASE_REF_DIS __BIT(29)
#define CAR_PLLD_BASE_LOCK __BIT(27)
#define CAR_PLLD_BASE_CLKENABLE_CSI __BIT(26)
#define CAR_PLLD_BASE_DSIA_CLK_SRC __BIT(25)
#define CAR_PLLD_BASE_CSI_CLK_SRC __BIT(23)
#define CAR_PLLD_BASE_DIVP __BITS(22,20)
#define CAR_PLLD_BASE_DIVN __BITS(18,8)
#define CAR_PLLD_BASE_DIVM __BITS(4,0)
#define CAR_PLLD_MISC_REG 0xdc
#define CAR_PLLX_BASE_REG 0xe0
#define CAR_PLLX_BASE_BYPASS __BIT(31)
#define CAR_PLLX_BASE_ENABLE __BIT(30)
#define CAR_PLLX_BASE_REF_DIS __BIT(29)
#define CAR_PLLX_BASE_LOCK __BIT(27)
#define CAR_PLLX_BASE_DIVP __BITS(23,20)
#define CAR_PLLX_BASE_DIVN __BITS(15,8)
#define CAR_PLLX_BASE_DIVM __BITS(7,0)
#define CAR_PLLX_MISC_REG 0xe4
#define CAR_PLLX_MISC_FO_LP_DISABLE __BIT(29)
#define CAR_PLLX_MISC_FO_G_DISABLE __BIT(28)
#define CAR_PLLX_MISC_PTS __BITS(23,22)
#define CAR_PLLX_MISC_LOCK_ENABLE __BIT(18)
#define CAR_PLLE_BASE_REG 0xe8
#define CAR_PLLE_BASE_ENABLE __BIT(30)
#define CAR_PLLE_BASE_LOCK_OVERRIDE __BIT(29)
#define CAR_PLLE_BASE_FDIV48 __BIT(28)
#define CAR_PLLE_BASE_DIVP_CML __BITS(27,24)
#define CAR_PLLE_BASE_EXT_SETUP_23_16 __BITS(23,16)
#define CAR_PLLE_BASE_DIVN __BITS(15,8)
#define CAR_PLLE_BASE_DIVM __BITS(7,0)
#define CAR_PLLE_MISC_REG 0xec
#define CAR_PLLD2_BASE_REG 0x4b8
#define CAR_PLLD2_BASE_BYPASS __BIT(31)
#define CAR_PLLD2_BASE_ENABLE __BIT(30)
#define CAR_PLLD2_BASE_REF_DIS __BIT(29)
#define CAR_PLLD2_BASE_FREQLOCK __BIT(28)
#define CAR_PLLD2_BASE_LOCK __BIT(27)
#define CAR_PLLD2_BASE_REF_SRC_SEL __BITS(26,25)
#define CAR_PLLD2_BASE_REF_SRC_SEL_PLL_D 0
#define CAR_PLLD2_BASE_REF_SRC_SEL_PLL_D2 1
#define CAR_PLLD2_BASE_LOCK_OVERRIDE __BIT(24)
#define CAR_PLLD2_BASE_DIVP __BITS(23,20)
#define CAR_PLLD2_BASE_IDDQ __BIT(19)
#define CAR_PLLD2_BASE_PTS __BIT(16)
#define CAR_PLLD2_BASE_DIVN __BITS(15,8)
#define CAR_PLLD2_BASE_DIVM __BITS(7,0)
#define CAR_PLLD2_MISC_REG 0x4bc
#define CAR_PLLD2_MISC_EN_FSTLCK __BIT(31)
#define CAR_PLLD2_MISC_LOCK_ENABLE __BIT(30)
#define CAR_PLLD2_MISC_MON_TEST_OUT __BITS(29,27)
#define CAR_PLLD2_MISC_KCP __BITS(26,25)
#define CAR_PLLD2_MISC_KVCO __BIT(24)
#define CAR_PLLD2_MISC_SETUP __BITS(23,0)
#define CAR_CLKSRC_I2C1_REG 0x124
#define CAR_CLKSRC_I2C2_REG 0x198
#define CAR_CLKSRC_I2C3_REG 0x1b8
#define CAR_CLKSRC_I2C4_REG 0x3c4
#define CAR_CLKSRC_I2C5_REG 0x128
#define CAR_CLKSRC_I2C6_REG 0x65c
#define CAR_CLKSRC_I2C_SRC __BITS(31,29)
#define CAR_CLKSRC_I2C_SRC_PLLP_OUT0 0
#define CAR_CLKSRC_I2C_SRC_PLLC2_OUT0 1
#define CAR_CLKSRC_I2C_SRC_PLLC_OUT0 2
#define CAR_CLKSRC_I2C_SRC_PLLC3_OUT0 3
#define CAR_CLKSRC_I2C_SRC_PLLM_OUT0 4
#define CAR_CLKSRC_I2C_SRC_CLK_M 6
#define CAR_CLKSRC_I2C_DIV __BITS(15,0)
#define CAR_CLKSRC_UARTA_REG 0x178
#define CAR_CLKSRC_UARTB_REG 0x17c
#define CAR_CLKSRC_UARTC_REG 0x1a0
#define CAR_CLKSRC_UARTD_REG 0x1c0
#define CAR_CLKSRC_UART_SRC __BITS(31,29)
#define CAR_CLKSRC_UART_SRC_PLLP_OUT0 0
#define CAR_CLKSRC_UART_SRC_PLLC2_OUT0 1
#define CAR_CLKSRC_UART_SRC_PLLC_OUT0 2
#define CAR_CLKSRC_UART_SRC_PLLC3_OUT0 3
#define CAR_CLKSRC_UART_SRC_PLLM_OUT0 4
#define CAR_CLKSRC_UART_SRC_CLK_M 6
#define CAR_CLKSRC_UART_DIV_ENB __BIT(24)
#define CAR_CLKSRC_UART_DIV __BITS(15,0)
#define CAR_CLKSRC_SDMMC1_REG 0x150
#define CAR_CLKSRC_SDMMC2_REG 0x154
#define CAR_CLKSRC_SDMMC4_REG 0x164
#define CAR_CLKSRC_SDMMC3_REG 0x1bc
#define CAR_CLKSRC_SDMMC_SRC __BITS(31,29)
#define CAR_CLKSRC_SDMMC_SRC_PLLP_OUT0 0
#define CAR_CLKSRC_SDMMC_SRC_PLLC2_OUT0 1
#define CAR_CLKSRC_SDMMC_SRC_PLLC_OUT0 2
#define CAR_CLKSRC_SDMMC_SRC_PLLC3_OUT0 3
#define CAR_CLKSRC_SDMMC_SRC_PLLM_OUT0 4
#define CAR_CLKSRC_SDMMC_SRC_PLLE_OUT0 5
#define CAR_CLKSRC_SDMMC_SRC_CLK_M 6
#define CAR_CLKSRC_SDMMC_DIV __BITS(7,0)
#define CAR_CLKSRC_HDMI_REG 0x18c
#define CAR_CLKSRC_HDMI_SRC __BITS(31,29)
#define CAR_CLKSRC_HDMI_SRC_PLLP_OUT0 0
#define CAR_CLKSRC_HDMI_SRC_PLLM_OUT0 1
#define CAR_CLKSRC_HDMI_SRC_PLLD_OUT0 2
#define CAR_CLKSRC_HDMI_SRC_PLLA_OUT0 3
#define CAR_CLKSRC_HDMI_SRC_PLLC_OUT0 4
#define CAR_CLKSRC_HDMI_SRC_PLLD2_OUT0 5
#define CAR_CLKSRC_HDMI_SRC_CLK_M 6
#define CAR_CLKSRC_HDMI_DIV __BITS(7,0)
#define CAR_CLKSRC_DISP1_REG 0x138
#define CAR_CLKSRC_DISP2_REG 0x13c
#define CAR_CLKSRC_DISP_SRC __BITS(31,29)
#define CAR_CLKSRC_DISP_SRC_PLLP_OUT0 0
#define CAR_CLKSRC_DISP_SRC_PLLM_OUT0 1
#define CAR_CLKSRC_DISP_SRC_PLLD_OUT0 2
#define CAR_CLKSRC_DISP_SRC_PLLA_OUT0 3
#define CAR_CLKSRC_DISP_SRC_PLLC_OUT0 4
#define CAR_CLKSRC_DISP_SRC_PLLD2_OUT0 5
#define CAR_CLKSRC_DISP_SRC_CLK_M 6
#define CAR_CLKSRC_HOST1X_REG 0x180
#define CAR_CLKSRC_HOST1X_SRC __BITS(31,29)
#define CAR_CLKSRC_HOST1X_SRC_PLLM_OUT0 0
#define CAR_CLKSRC_HOST1X_SRC_PLLC2_OUT0 1
#define CAR_CLKSRC_HOST1X_SRC_PLLC_OUT0 2
#define CAR_CLKSRC_HOST1X_SRC_PLLC3_OUT0 3
#define CAR_CLKSRC_HOST1X_SRC_PLLP_OUT0 4
#define CAR_CLKSRC_HOST1X_SRC_PLLA_OUT0 6
#define CAR_CLKSRC_HOST1X_IDLE_DIVISOR __BITS(15,8)
#define CAR_CLKSRC_HOST1X_CLK_DIVISOR __BITS(7,0)
#define CAR_RST_DEV_L_SET_REG 0x300
#define CAR_RST_DEV_L_CLR_REG 0x304
#define CAR_RST_DEV_H_SET_REG 0x308
#define CAR_RST_DEV_H_CLR_REG 0x30c
#define CAR_RST_DEV_U_SET_REG 0x310
#define CAR_RST_DEV_U_CLR_REG 0x314
#define CAR_RST_DEV_V_SET_REG 0x430
#define CAR_RST_DEV_V_CLR_REG 0x434
#define CAR_RST_DEV_W_SET_REG 0x438
#define CAR_RST_DEV_W_CLR_REG 0x43c
#define CAR_RST_DEV_X_SET_REG 0x290
#define CAR_RST_DEV_X_CLR_REG 0x294
#define CAR_CLK_ENB_L_SET_REG 0x320
#define CAR_CLK_ENB_L_CLR_REG 0x324
#define CAR_CLK_ENB_H_SET_REG 0x328
#define CAR_CLK_ENB_H_CLR_REG 0x32c
#define CAR_CLK_ENB_U_SET_REG 0x330
#define CAR_CLK_ENB_U_CLR_REG 0x334
#define CAR_CLK_ENB_V_SET_REG 0x440
#define CAR_CLK_ENB_V_CLR_REG 0x444
#define CAR_CLK_ENB_W_SET_REG 0x448
#define CAR_CLK_ENB_W_CLR_REG 0x44c
#define CAR_CLK_ENB_X_SET_REG 0x284
#define CAR_CLK_ENB_X_CLR_REG 0x288
#define CAR_DEV_L_CACHE2 __BIT(31)
#define CAR_DEV_L_I2S0 __BIT(30)
#define CAR_DEV_L_VCP __BIT(29)
#define CAR_DEV_L_HOST1X __BIT(28)
#define CAR_DEV_L_DISP1 __BIT(27)
#define CAR_DEV_L_DISP2 __BIT(26)
#define CAR_DEV_L_ISP __BIT(23)
#define CAR_DEV_L_USBD __BIT(22)
#define CAR_DEV_L_VI __BIT(20)
#define CAR_DEV_L_I2S2 __BIT(18)
#define CAR_DEV_L_PWM __BIT(17)
#define CAR_DEV_L_SDMMC4 __BIT(15)
#define CAR_DEV_L_SDMMC1 __BIT(14)
#define CAR_DEV_L_I2C1 __BIT(12)
#define CAR_DEV_L_I2S1 __BIT(11)
#define CAR_DEV_L_SPDIF __BIT(10)
#define CAR_DEV_L_SDMMC2 __BIT(9)
#define CAR_DEV_L_GPIO __BIT(8)
#define CAR_DEV_L_UARTB __BIT(7)
#define CAR_DEV_L_UARTA __BIT(6)
#define CAR_DEV_L_TMR __BIT(5
#define CAR_DEV_L_RTC __BIT(4)
#define CAR_DEV_L_ISPB __BIT(3)
#define CAR_DEV_L_CPU __BIT(0)
#define CAR_DEV_U_XUSB_DEV __BIT(31)
#define CAR_DEV_U_DEV1_OUT __BIT(30)
#define CAR_DEV_U_DEV2_OUT __BIT(29)
#define CAR_DEV_U_SUS_OUT __BIT(28)
#define CAR_DEV_U_MSENC __BIT(27)
#define CAR_DEV_U_XUSB_HOST __BIT(25)
#define CAR_DEV_U_CRAM2 __BIT(24)
#define CAR_DEV_U_IRAMD __BIT(23)
#define CAR_DEV_U_IRAMC __BIT(22)
#define CAR_DEV_U_IRAMB __BIT(21)
#define CAR_DEV_U_IRAMA __BIT(20)
#define CAR_DEV_U_TSEC __BIT(19)
#define CAR_DEV_U_DSIB __BIT(18)
#define CAR_DEV_U_I2C_SLOW __BIT(17)
#define CAR_DEV_U_DTV __BIT(15)
#define CAR_DEV_U_SOC_THERM __BIT(14)
#define CAR_DEV_U_TRACECLKIN __BIT(13)
#define CAR_DEV_U_AVPUCQ __BIT(11)
#define CAR_DEV_U_CSITE __BIT(9)
#define CAR_DEV_U_AFI __BIT(8)
#define CAR_DEV_U_OWR __BIT(7)
#define CAR_DEV_U_PCIE __BIT(6)
#define CAR_DEV_U_SDMMC3 __BIT(5)
#define CAR_DEV_U_SPI4 __BIT(4)
#define CAR_DEV_U_I2C3 __BIT(3)
#define CAR_DEV_U_UARTD __BIT(1)
#define CAR_DEV_H_BSEV __BIT(31)
#define CAR_DEV_H_BSEA __BIT(30)
#define CAR_DEV_H_VDE __BIT(29)
#define CAR_DEV_H_USB3 __BIT(27)
#define CAR_DEV_H_USB2 __BIT(26)
#define CAR_DEV_H_EMC __BIT(25)
#define CAR_DEV_H_MIPI_CAL __BIT(24)
#define CAR_DEV_H_UARTC __BIT(23)
#define CAR_DEV_H_I2C2 __BIT(22)
#define CAR_DEV_H_CSI __BIT(20)
#define CAR_DEV_H_HDMI __BIT(19)
#define CAR_DEV_H_HSI __BIT(18)
#define CAR_DEV_H_DSI __BIT(16)
#define CAR_DEV_H_I2C5 __BIT(15)
#define CAR_DEV_H_SPI3 __BIT(14)
#define CAR_DEV_H_SPI2 __BIT(12)
#define CAR_DEV_H_JTAG2TBC __BIT(11)
#define CAR_DEV_H_SNOR __BIT(10)
#define CAR_DEV_H_SPI1 __BIT(9)
#define CAR_DEV_H_KFUSE __BIT(8)
#define CAR_DEV_H_FUSE __BIT(7)
#define CAR_DEV_H_PMC __BIT(6)
#define CAR_DEV_H_STAT_MON __BIT(5)
#define CAR_DEV_H_KBC __BIT(4)
#define CAR_DEV_H_APBDMA __BIT(2)
#define CAR_DEV_H_AHBDMA __BIT(1)
#define CAR_DEV_H_MEM __BIT(0)
#define CAR_DEV_V_HDA __BIT(29)
#define CAR_DEV_V_SATA __BIT(28)
#define CAR_DEV_V_SATA_OOB __BIT(27)
#define CAR_DEV_V_ACTMON __BIT(23)
#define CAR_DEV_V_ATOMICS __BIT(16)
#define CAR_DEV_V_HDA2CODEC_2X __BIT(15)
#define CAR_DEV_V_DAM2 __BIT(14)
#define CAR_DEV_V_DAM1 __BIT(13)
#define CAR_DEV_V_DAM0 __BIT(12)
#define CAR_DEV_V_APBIF __BIT(11)
#define CAR_DEV_V_AUDIO __BIT(10)
#define CAR_DEV_V_SPI6 __BIT(9)
#define CAR_DEV_V_SPI5 __BIT(8)
#define CAR_DEV_V_I2C4 __BIT(7)
#define CAR_DEV_V_I2S4 __BIT(6)
#define CAR_DEV_V_I2S3 __BIT(5)
#define CAR_DEV_V_TSENSOR __BIT(4)
#define CAR_DEV_V_MSELECT __BIT(3)
#define CAR_DEV_V_CPULP __BIT(1)
#define CAR_DEV_V_CPUG __BIT(0)
#define CAR_DEV_W_XUSB_SS __BIT(28)
#define CAR_DEV_W_DVFS __BIT(27)
#define CAR_DEV_W_ADX0 __BIT(26)
#define CAR_DEV_W_AMX0 __BIT(25)
#define CAR_DEV_W_ENTROPY __BIT(21)
#define CAR_DEV_W_XUSB_PADCTL __BIT(14)
#define CAR_DEV_W_CEC __BIT(8)
#define CAR_DEV_W_SATACOLD __BIT(1)
#define CAR_DEV_W_HDA2HDMICODEC __BIT(0)
#define CAR_DEV_X_AMX1 __BIT(25)
#define CAR_DEV_X_GPU __BIT(24)
#define CAR_DEV_X_SOR0 __BIT(22)
#define CAR_DEV_X_DPAUX __BIT(21)
#define CAR_DEV_X_ADX1 __BIT(20)
#define CAR_DEV_X_VIC __BIT(18)
#define CAR_DEV_X_CLK72MHZ __BIT(17)
#define CAR_DEV_X_HDMI_AUDIO __BIT(16)
#define CAR_DEV_X_EMC_DLL __BIT(14)
#define CAR_DEV_X_VIM2_CLK __BIT(11)
#define CAR_DEV_X_I2C6 __BIT(6)
#define CAR_DEV_X_CAM_MCLK2 __BIT(5)
#define CAR_DEV_X_CAM_MCLK __BIT(4)
#define CAR_DEV_X_SPARE __BIT(0)
#define CAR_CCLKG_BURST_POLICY_REG 0x368
#define CAR_CCLKG_BURST_POLICY_CPU_STATE __BITS(31,28)
#define CAR_CCLKG_BURST_POLICY_CPU_STATE_IDLE 1
#define CAR_CCLKG_BURST_POLICY_CPU_STATE_RUN 2
#define CAR_CCLKG_BURST_POLICY_CWAKEUP_IDLE_SOURCE __BITS(3,0)
#define CAR_CCLKG_BURST_POLICY_CWAKEUP_SOURCE_CLKM 0
#define CAR_CCLKG_BURST_POLICY_CWAKEUP_SOURCE_PLLX_OUT0_LJ 8
#define CAR_CLKSRC_TSENSOR_REG 0x3b8
#define CAR_CLKSRC_TSENSOR_SRC __BITS(31,29)
#define CAR_CLKSRC_TSENSOR_SRC_CLK_M 4
#define CAR_CLKSRC_TSENSOR_DIV __BITS(7,0)
#define CAR_CLKSRC_HDA2CODEC_2X_REG 0x3e4
#define CAR_CLKSRC_HDA2CODEC_2X_SRC __BITS(31,29)
#define CAR_CLKSRC_HDA2CODEC_2X_SRC_PLLP_OUT0 0
#define CAR_CLKSRC_HDA2CODEC_2X_SRC_PLLC2_OUT0 1
#define CAR_CLKSRC_HDA2CODEC_2X_SRC_PLLC_OUT0 2
#define CAR_CLKSRC_HDA2CODEC_2X_SRC_PLLC3_OUT0 3
#define CAR_CLKSRC_HDA2CODEC_2X_SRC_PLLM_OUT0 4
#define CAR_CLKSRC_HDA2CODEC_2X_SRC_CLKM 6
#define CAR_CLKSRC_HDA2CODEC_2X_DIV __BITS(7,0)
#define CAR_CLKSRC_SATA_OOB_REG 0x420
#define CAR_CLKSRC_SATA_OOB_SRC __BITS(31,29)
#define CAR_CLKSRC_SATA_OOB_SRC_PLLP_OUT0 0
#define CAR_CLKSRC_SATA_OOB_SRC_PLLC_OUT0 2
#define CAR_CLKSRC_SATA_OOB_SRC_PLLM_OUT0 4
#define CAR_CLKSRC_SATA_OOB_SRC_CLKM 6
#define CAR_CLKSRC_SATA_OOB_DIV __BITS(7,0)
#define CAR_CLKSRC_SATA_REG 0x424
#define CAR_CLKSRC_SATA_SRC __BITS(31,29)
#define CAR_CLKSRC_SATA_SRC_PLLP_OUT0 0
#define CAR_CLKSRC_SATA_SRC_PLLC_OUT0 2
#define CAR_CLKSRC_SATA_SRC_PLLM_OUT0 4
#define CAR_CLKSRC_SATA_SRC_CLKM 6
#define CAR_CLKSRC_SATA_AUX_CLK_ENB __BIT(24)
#define CAR_CLKSRC_SATA_DIV __BITS(7,0)
#define CAR_CLKSRC_HDA_REG 0x428
#define CAR_CLKSRC_HDA_SRC __BITS(31,29)
#define CAR_CLKSRC_HDA_SRC_PLLP_OUT0 0
#define CAR_CLKSRC_HDA_SRC_PLLC2_OUT0 1
#define CAR_CLKSRC_HDA_SRC_PLLC_OUT0 2
#define CAR_CLKSRC_HDA_SRC_PLLC3_OUT0 3
#define CAR_CLKSRC_HDA_SRC_PLLM_OUT0 4
#define CAR_CLKSRC_HDA_SRC_CLKM 6
#define CAR_CLKSRC_HDA_DIV __BITS(7,0)
#define CAR_UTMIP_PLL_CFG0_REG 0x480
#define CAR_UTMIP_PLL_CFG1_REG 0x484
#define CAR_UTMIP_PLL_CFG1_ENABLE_DLY_COUNT __BITS(31,27)
#define CAR_UTMIP_PLL_CFG1_PLLU_POWERUP __BIT(17)
#define CAR_UTMIP_PLL_CFG1_PLLU_POWERDOWN __BIT(16)
#define CAR_UTMIP_PLL_CFG1_PLL_ENABLE_POWERUP __BIT(15)
#define CAR_UTMIP_PLL_CFG1_PLL_ENABLE_POWERDOWN __BIT(14)
#define CAR_UTMIP_PLL_CFG1_XTAL_FREQ_COUNT __BITS(11,0)
#define CAR_UTMIP_PLL_CFG2_REG 0x488
#define CAR_UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT __BITS(23,18)
#define CAR_UTMIP_PLL_CFG2_STABLE_COUNT __BITS(17,6)
#define CAR_UTMIP_PLL_CFG2_PD_SAMP_C_POWERUP __BIT(5)
#define CAR_UTMIP_PLL_CFG2_PD_SAMP_C_POWERDOWN __BIT(4)
#define CAR_UTMIP_PLL_CFG2_PD_SAMP_B_POWERUP __BIT(3)
#define CAR_UTMIP_PLL_CFG2_PD_SAMP_B_POWERDOWN __BIT(2)
#define CAR_UTMIP_PLL_CFG2_PD_SAMP_A_POWERUP __BIT(1)
#define CAR_UTMIP_PLL_CFG2_PD_SAMP_A_POWERDOWN __BIT(0)
#define CAR_PLLE_AUX_REG 0x48c
#define CAR_PLLE_AUX_SS_SEQ_INCLUDE __BIT(31)
#define CAR_PLLE_AUX_REF_SEL_PLLREFE __BIT(28)
#define CAR_PLLE_AUX_SEQ_STATE __BITS(27,26)
#define CAR_PLLE_AUX_SEQ_START_STATE __BIT(25)
#define CAR_PLLE_AUX_SEQ_ENABLE __BIT(24)
#define CAR_PLLE_AUX_SS_DLY __BITS(23,16)
#define CAR_PLLE_AUX_LOCK_DLY __BITS(15,8)
#define CAR_PLLE_AUX_FAST_PT __BIT(7)
#define CAR_PLLE_AUX_SS_SWCTL __BIT(6)
#define CAR_PLLE_AUX_CONFIG_SWCTL __BIT(5)
#define CAR_PLLE_AUX_ENABLE_SWCTL __BIT(4)
#define CAR_PLLE_AUX_USE_LOCKDET __BIT(3)
#define CAR_PLLE_AUX_REF_SRC __BIT(2)
#define CAR_PLLE_AUX_CML1_OEN __BIT(1)
#define CAR_PLLE_AUX_CML0_OEN __BIT(0)
#define CAR_SATA_PLL_CFG0_REG 0x490
#define CAR_SATA_PLL_CFG0_SEQ_STATE __BITS(27,26)
#define CAR_SATA_PLL_CFG0_SEQ_START_STATE __BIT(25)
#define CAR_SATA_PLL_CFG0_SEQ_ENABLE __BIT(24)
#define CAR_SATA_PLL_CFG0_SEQ_PADPLL_PD_INPUT_VALUE __BIT(7)
#define CAR_SATA_PLL_CFG0_SEQ_LANE_PD_INPUT_VALUE __BIT(6)
#define CAR_SATA_PLL_CFG0_SEQ_RESET_INPUT_VALUE __BIT(5)
#define CAR_SATA_PLL_CFG0_SEQ_IN_SWCTL __BIT(4)
#define CAR_SATA_PLL_CFG0_PADPLL_USE_LOCKDET __BIT(2)
#define CAR_SATA_PLL_CFG0_PADPLL_RESET_OVERRIDE_VALUE __BIT(1)
#define CAR_SATA_PLL_CFG0_PADPLL_RESET_SWCTL __BIT(0)
#define CAR_SATA_PLL_CFG1_REG 0x494
#define CAR_SATA_PLL_CFG1_LANE_IDDQ2_PADPLL_RESET_DLY __BITS(31,24)
#define CAR_SATA_PLL_CFG1_PADPLL_IDDQ2LANE_SLUMBER_DLY __BITS(23,16)
#define CAR_SATA_PLL_CFG1_PADPLL_PU_POST_DLY __BITS(15,8)
#define CAR_SATA_PLL_CFG1_LANE_IDDQ2_PADPLL_IDDQ_DLY __BITS(7,0)
#define CAR_CLKSRC_SOC_THERM_REG 0x644
#define CAR_CLKSRC_SOC_THERM_SRC __BITS(31,29)
#define CAR_CLKSRC_SOC_THERM_SRC_PLLP_OUT0 2
#define CAR_CLKSRC_SOC_THERM_DIV __BITS(7,0)
#define CAR_CLKSRC_HDMI_AUDIO_REG 0x668
#define CAR_CLKSRC_HDMI_AUDIO_SRC __BITS(31,29)
#define CAR_CLKSRC_HDMI_AUDIO_SRC_PLLP_OUT0 0
#define CAR_CLKSRC_HDMI_AUDIO_SRC_PLLC_OUT0 1
#define CAR_CLKSRC_HDMI_AUDIO_SRC_PLLC2_OUT0 2
#define CAR_CLKSRC_HDMI_AUDIO_SRC_CLKM 3
#define CAR_CLKSRC_HDMI_AUDIO_DIV __BITS(7,0)
#endif /* _ARM_TEGRA124_CARREG_H */
/* $NetBSD: tegra_clock.h,v 1.1 2015/12/22 22:10:36 jmcneill Exp $ */
/*-
* Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _ARM_TEGRA_CLOCK_H
#define _ARM_TEGRA_CLOCK_H
enum tegra_clk_type {
TEGRA_CLK_FIXED,
TEGRA_CLK_PLL,
TEGRA_CLK_MUX,
TEGRA_CLK_FIXED_DIV,
TEGRA_CLK_DIV,
TEGRA_CLK_GATE
};
struct tegra_fixed_clk {
u_int rate;
};
struct tegra_fixed_div_clk {
u_int div;
};
struct tegra_pll_clk {
u_int base_reg;
u_int divm_mask;
u_int divn_mask;
u_int divp_mask;
};
struct tegra_mux_clk {
const char **parents;
u_int nparents;
u_int reg;
u_int bits;
};
struct tegra_div_clk {
u_int reg;
u_int bits;
};
struct tegra_gate_clk {
u_int set_reg;
u_int clr_reg;
u_int bits;
};
struct tegra_clk {
struct clk base; /* must be first */
u_int id;
const char *parent;
enum tegra_clk_type type;
u_int refcnt;
union {
struct tegra_fixed_clk fixed;
struct tegra_pll_clk pll;
struct tegra_mux_clk mux;
struct tegra_fixed_div_clk fixed_div;
struct tegra_div_clk div;
struct tegra_gate_clk gate;
} u;
};
#define TEGRA_CLK_BASE(_tclk) ((_tclk) ? &(_tclk)->base : NULL)
#define TEGRA_CLK_PRIV(_clk) ((struct tegra_clk *)(_clk))
#endif /* _ARM_TEGRA_CLOCK_H */
--- src/sys/arch/arm/nvidia/tegra_ahcisata.c 2015/12/13 17:39:19 1.8
+++ src/sys/arch/arm/nvidia/tegra_ahcisata.c 2015/12/22 22:10:36 1.9
| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: tegra_ahcisata.c,v 1.8 2015/12/13 17:39:19 jmcneill Exp $ */ | | 1 | /* $NetBSD: tegra_ahcisata.c,v 1.9 2015/12/22 22:10:36 jmcneill Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> | | 4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -17,66 +17,75 @@ | | | @@ -17,66 +17,75 @@ |
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | | 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | | 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | | 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | | 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | | 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 24 | * 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 | | 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
26 | * SUCH DAMAGE. | | 26 | * SUCH DAMAGE. |
27 | */ | | 27 | */ |
28 | | | 28 | |
29 | #include <sys/cdefs.h> | | 29 | #include <sys/cdefs.h> |
30 | __KERNEL_RCSID(0, "$NetBSD: tegra_ahcisata.c,v 1.8 2015/12/13 17:39:19 jmcneill Exp $"); | | 30 | __KERNEL_RCSID(0, "$NetBSD: tegra_ahcisata.c,v 1.9 2015/12/22 22:10:36 jmcneill Exp $"); |
31 | | | 31 | |
32 | #include <sys/param.h> | | 32 | #include <sys/param.h> |
33 | #include <sys/bus.h> | | 33 | #include <sys/bus.h> |
34 | #include <sys/device.h> | | 34 | #include <sys/device.h> |
35 | #include <sys/intr.h> | | 35 | #include <sys/intr.h> |
36 | #include <sys/systm.h> | | 36 | #include <sys/systm.h> |
37 | #include <sys/kernel.h> | | 37 | #include <sys/kernel.h> |
38 | | | 38 | |
39 | #include <dev/ata/atavar.h> | | 39 | #include <dev/ata/atavar.h> |
40 | #include <dev/ic/ahcisatavar.h> | | 40 | #include <dev/ic/ahcisatavar.h> |
41 | | | 41 | |
42 | #include <arm/nvidia/tegra_var.h> | | 42 | #include <arm/nvidia/tegra_var.h> |
| | | 43 | #include <arm/nvidia/tegra_pmcreg.h> |
43 | #include <arm/nvidia/tegra_ahcisatareg.h> | | 44 | #include <arm/nvidia/tegra_ahcisatareg.h> |
44 | | | 45 | |
45 | #include <dev/fdt/fdtvar.h> | | 46 | #include <dev/fdt/fdtvar.h> |
46 | | | 47 | |
47 | #define TEGRA_AHCISATA_OFFSET 0x7000 | | 48 | #define TEGRA_AHCISATA_OFFSET 0x7000 |
48 | | | 49 | |
49 | static int tegra_ahcisata_match(device_t, cfdata_t, void *); | | 50 | static int tegra_ahcisata_match(device_t, cfdata_t, void *); |
50 | static void tegra_ahcisata_attach(device_t, device_t, void *); | | 51 | static void tegra_ahcisata_attach(device_t, device_t, void *); |
51 | | | 52 | |
52 | struct tegra_ahcisata_softc { | | 53 | struct tegra_ahcisata_softc { |
53 | struct ahci_softc sc; | | 54 | struct ahci_softc sc; |
54 | bus_space_tag_t sc_bst; | | 55 | bus_space_tag_t sc_bst; |
55 | bus_space_handle_t sc_bsh; | | 56 | bus_space_handle_t sc_bsh; |
56 | void *sc_ih; | | 57 | void *sc_ih; |
| | | 58 | struct clk *sc_clk_sata; |
| | | 59 | struct clk *sc_clk_sata_oob; |
| | | 60 | struct clk *sc_clk_cml1; |
| | | 61 | struct clk *sc_clk_pll_e; |
| | | 62 | struct fdtbus_reset *sc_rst_sata; |
| | | 63 | struct fdtbus_reset *sc_rst_sata_oob; |
| | | 64 | struct fdtbus_reset *sc_rst_sata_cold; |
57 | | | 65 | |
58 | struct tegra_gpio_pin *sc_pin_power; | | 66 | struct tegra_gpio_pin *sc_pin_power; |
59 | }; | | 67 | }; |
60 | | | 68 | |
61 | static const char * const tegra_ahcisata_supplies[] = { | | 69 | static const char * const tegra_ahcisata_supplies[] = { |
62 | "hvdd-supply", | | 70 | "hvdd-supply", |
63 | "vddio-supply", | | 71 | "vddio-supply", |
64 | "avdd-supply", | | 72 | "avdd-supply", |
65 | "target-5v-supply", | | 73 | "target-5v-supply", |
66 | "target-12v-supply" | | 74 | "target-12v-supply" |
67 | }; | | 75 | }; |
68 | | | 76 | |
69 | static void tegra_ahcisata_init(struct tegra_ahcisata_softc *); | | 77 | static void tegra_ahcisata_init(struct tegra_ahcisata_softc *); |
| | | 78 | static int tegra_ahcisata_init_clocks(struct tegra_ahcisata_softc *); |
70 | | | 79 | |
71 | CFATTACH_DECL_NEW(tegra_ahcisata, sizeof(struct tegra_ahcisata_softc), | | 80 | CFATTACH_DECL_NEW(tegra_ahcisata, sizeof(struct tegra_ahcisata_softc), |
72 | tegra_ahcisata_match, tegra_ahcisata_attach, NULL, NULL); | | 81 | tegra_ahcisata_match, tegra_ahcisata_attach, NULL, NULL); |
73 | | | 82 | |
74 | static int | | 83 | static int |
75 | tegra_ahcisata_match(device_t parent, cfdata_t cf, void *aux) | | 84 | tegra_ahcisata_match(device_t parent, cfdata_t cf, void *aux) |
76 | { | | 85 | { |
77 | const char * const compatible[] = { "nvidia,tegra124-ahci", NULL }; | | 86 | const char * const compatible[] = { "nvidia,tegra124-ahci", NULL }; |
78 | struct fdt_attach_args * const faa = aux; | | 87 | struct fdt_attach_args * const faa = aux; |
79 | | | 88 | |
80 | return of_match_compatible(faa->faa_phandle, compatible); | | 89 | return of_match_compatible(faa->faa_phandle, compatible); |
81 | } | | 90 | } |
82 | | | 91 | |
| @@ -90,26 +99,61 @@ tegra_ahcisata_attach(device_t parent, d | | | @@ -90,26 +99,61 @@ tegra_ahcisata_attach(device_t parent, d |
90 | bus_size_t ahci_size, sata_size; | | 99 | bus_size_t ahci_size, sata_size; |
91 | struct fdtbus_regulator *reg; | | 100 | struct fdtbus_regulator *reg; |
92 | char intrstr[128]; | | 101 | char intrstr[128]; |
93 | int error, n; | | 102 | int error, n; |
94 | | | 103 | |
95 | if (fdtbus_get_reg(phandle, 0, &ahci_addr, &ahci_size) != 0) { | | 104 | if (fdtbus_get_reg(phandle, 0, &ahci_addr, &ahci_size) != 0) { |
96 | aprint_error(": couldn't get ahci registers\n"); | | 105 | aprint_error(": couldn't get ahci registers\n"); |
97 | return; | | 106 | return; |
98 | } | | 107 | } |
99 | if (fdtbus_get_reg(phandle, 1, &sata_addr, &sata_size) != 0) { | | 108 | if (fdtbus_get_reg(phandle, 1, &sata_addr, &sata_size) != 0) { |
100 | aprint_error(": couldn't get sata registers\n"); | | 109 | aprint_error(": couldn't get sata registers\n"); |
101 | return; | | 110 | return; |
102 | } | | 111 | } |
| | | 112 | sc->sc_clk_sata = fdtbus_clock_get(phandle, "sata"); |
| | | 113 | if (sc->sc_clk_sata == NULL) { |
| | | 114 | aprint_error(": couldn't get clock sata\n"); |
| | | 115 | return; |
| | | 116 | } |
| | | 117 | sc->sc_clk_sata_oob = fdtbus_clock_get(phandle, "sata-oob"); |
| | | 118 | if (sc->sc_clk_sata_oob == NULL) { |
| | | 119 | aprint_error(": couldn't get clock sata-oob\n"); |
| | | 120 | return; |
| | | 121 | } |
| | | 122 | sc->sc_clk_cml1 = fdtbus_clock_get(phandle, "cml1"); |
| | | 123 | if (sc->sc_clk_cml1 == NULL) { |
| | | 124 | aprint_error(": couldn't get clock cml1\n"); |
| | | 125 | return; |
| | | 126 | } |
| | | 127 | sc->sc_clk_pll_e = fdtbus_clock_get(phandle, "pll_e"); |
| | | 128 | if (sc->sc_clk_pll_e == NULL) { |
| | | 129 | aprint_error(": couldn't get clock pll_e\n"); |
| | | 130 | return; |
| | | 131 | } |
| | | 132 | sc->sc_rst_sata = fdtbus_reset_get(phandle, "sata"); |
| | | 133 | if (sc->sc_rst_sata == NULL) { |
| | | 134 | aprint_error(": couldn't get reset sata\n"); |
| | | 135 | return; |
| | | 136 | } |
| | | 137 | sc->sc_rst_sata_oob = fdtbus_reset_get(phandle, "sata-oob"); |
| | | 138 | if (sc->sc_rst_sata_oob == NULL) { |
| | | 139 | aprint_error(": couldn't get reset sata-oob\n"); |
| | | 140 | return; |
| | | 141 | } |
| | | 142 | sc->sc_rst_sata_cold = fdtbus_reset_get(phandle, "sata-cold"); |
| | | 143 | if(sc->sc_rst_sata_cold == NULL) { |
| | | 144 | aprint_error(": couldn't get reset sata-cold\n"); |
| | | 145 | return; |
| | | 146 | } |
103 | | | 147 | |
104 | sc->sc_bst = faa->faa_bst; | | 148 | sc->sc_bst = faa->faa_bst; |
105 | error = bus_space_map(sc->sc_bst, sata_addr, sata_size, 0, &sc->sc_bsh); | | 149 | error = bus_space_map(sc->sc_bst, sata_addr, sata_size, 0, &sc->sc_bsh); |
106 | if (error) { | | 150 | if (error) { |
107 | aprint_error(": couldn't map sata registers: %d\n", error); | | 151 | aprint_error(": couldn't map sata registers: %d\n", error); |
108 | return; | | 152 | return; |
109 | } | | 153 | } |
110 | | | 154 | |
111 | sc->sc.sc_atac.atac_dev = self; | | 155 | sc->sc.sc_atac.atac_dev = self; |
112 | sc->sc.sc_dmat = faa->faa_dmat; | | 156 | sc->sc.sc_dmat = faa->faa_dmat; |
113 | sc->sc.sc_ahcit = faa->faa_bst; | | 157 | sc->sc.sc_ahcit = faa->faa_bst; |
114 | sc->sc.sc_ahcis = ahci_size; | | 158 | sc->sc.sc_ahcis = ahci_size; |
115 | error = bus_space_map(sc->sc.sc_ahcit, ahci_addr, ahci_size, 0, | | 159 | error = bus_space_map(sc->sc.sc_ahcit, ahci_addr, ahci_size, 0, |
| @@ -126,27 +170,28 @@ tegra_ahcisata_attach(device_t parent, d | | | @@ -126,27 +170,28 @@ tegra_ahcisata_attach(device_t parent, d |
126 | for (n = 0; n < __arraycount(tegra_ahcisata_supplies); n++) { | | 170 | for (n = 0; n < __arraycount(tegra_ahcisata_supplies); n++) { |
127 | const char *supply = tegra_ahcisata_supplies[n]; | | 171 | const char *supply = tegra_ahcisata_supplies[n]; |
128 | reg = fdtbus_regulator_acquire(phandle, supply); | | 172 | reg = fdtbus_regulator_acquire(phandle, supply); |
129 | if (reg == NULL) { | | 173 | if (reg == NULL) { |
130 | aprint_error_dev(self, "couldn't acquire %s\n", supply); | | 174 | aprint_error_dev(self, "couldn't acquire %s\n", supply); |
131 | continue; | | 175 | continue; |
132 | } | | 176 | } |
133 | if (fdtbus_regulator_enable(reg) != 0) { | | 177 | if (fdtbus_regulator_enable(reg) != 0) { |
134 | aprint_error_dev(self, "couldn't enable %s\n", supply); | | 178 | aprint_error_dev(self, "couldn't enable %s\n", supply); |
135 | } | | 179 | } |
136 | fdtbus_regulator_release(reg); | | 180 | fdtbus_regulator_release(reg); |
137 | } | | 181 | } |
138 | | | 182 | |
139 | tegra_car_periph_sata_enable(); | | 183 | if (tegra_ahcisata_init_clocks(sc) != 0) |
| | | 184 | return; |
140 | | | 185 | |
141 | tegra_xusbpad_sata_enable(); | | 186 | tegra_xusbpad_sata_enable(); |
142 | | | 187 | |
143 | tegra_ahcisata_init(sc); | | 188 | tegra_ahcisata_init(sc); |
144 | | | 189 | |
145 | if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { | | 190 | if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { |
146 | aprint_error_dev(self, "failed to decode interrupt\n"); | | 191 | aprint_error_dev(self, "failed to decode interrupt\n"); |
147 | return; | | 192 | return; |
148 | } | | 193 | } |
149 | | | 194 | |
150 | sc->sc_ih = fdtbus_intr_establish(phandle, 0, IPL_BIO, 0, | | 195 | sc->sc_ih = fdtbus_intr_establish(phandle, 0, IPL_BIO, 0, |
151 | ahci_intr, &sc->sc); | | 196 | ahci_intr, &sc->sc); |
152 | if (sc->sc_ih == NULL) { | | 197 | if (sc->sc_ih == NULL) { |
| @@ -224,13 +269,88 @@ tegra_ahcisata_init(struct tegra_ahcisat | | | @@ -224,13 +269,88 @@ tegra_ahcisata_init(struct tegra_ahcisat |
224 | TEGRA_T_SATA0_CFG1_IO_SPACE, | | 269 | TEGRA_T_SATA0_CFG1_IO_SPACE, |
225 | 0); | | 270 | 0); |
226 | | | 271 | |
227 | /* MMIO setup */ | | 272 | /* MMIO setup */ |
228 | bus_space_write_4(bst, bsh, TEGRA_SATA_FPCI_BAR5_REG, | | 273 | bus_space_write_4(bst, bsh, TEGRA_SATA_FPCI_BAR5_REG, |
229 | __SHIFTIN(0x10000, TEGRA_SATA_FPCI_BAR_START)); | | 274 | __SHIFTIN(0x10000, TEGRA_SATA_FPCI_BAR_START)); |
230 | bus_space_write_4(bst, bsh, TEGRA_T_SATA0_CFG9_REG, | | 275 | bus_space_write_4(bst, bsh, TEGRA_T_SATA0_CFG9_REG, |
231 | __SHIFTIN(0x8000, TEGRA_T_SATA0_CFG9_BASE_ADDRESS)); | | 276 | __SHIFTIN(0x8000, TEGRA_T_SATA0_CFG9_BASE_ADDRESS)); |
232 | | | 277 | |
233 | /* Enable interrupts */ | | 278 | /* Enable interrupts */ |
234 | tegra_reg_set_clear(bst, bsh, TEGRA_SATA_INTR_MASK_REG, | | 279 | tegra_reg_set_clear(bst, bsh, TEGRA_SATA_INTR_MASK_REG, |
235 | TEGRA_SATA_INTR_MASK_IP_INT, 0); | | 280 | TEGRA_SATA_INTR_MASK_IP_INT, 0); |
236 | } | | 281 | } |
| | | 282 | |
| | | 283 | static int |
| | | 284 | tegra_ahcisata_init_clocks(struct tegra_ahcisata_softc *sc) |
| | | 285 | { |
| | | 286 | device_t self = sc->sc.sc_atac.atac_dev; |
| | | 287 | struct clk *pll_p_out0; |
| | | 288 | int error; |
| | | 289 | |
| | | 290 | pll_p_out0 = clk_get("pll_p_out0"); |
| | | 291 | if (pll_p_out0 == NULL) { |
| | | 292 | aprint_error_dev(self, "couldn't find pll_p_out0\n"); |
| | | 293 | return ENOENT; |
| | | 294 | } |
| | | 295 | |
| | | 296 | /* Assert resets */ |
| | | 297 | fdtbus_reset_assert(sc->sc_rst_sata); |
| | | 298 | fdtbus_reset_assert(sc->sc_rst_sata_cold); |
| | | 299 | |
| | | 300 | /* Set SATA_OOB clock source to PLLP, 204MHz */ |
| | | 301 | error = clk_set_parent(sc->sc_clk_sata_oob, pll_p_out0); |
| | | 302 | if (error) { |
| | | 303 | aprint_error_dev(self, "couldn't set sata-oob parent: %d\n", |
| | | 304 | error); |
| | | 305 | return error; |
| | | 306 | } |
| | | 307 | error = clk_set_rate(sc->sc_clk_sata_oob, 204000000); |
| | | 308 | if (error) { |
| | | 309 | aprint_error_dev(self, "couldn't set sata-oob rate: %d\n", |
| | | 310 | error); |
| | | 311 | return error; |
| | | 312 | } |
| | | 313 | |
| | | 314 | /* Set SATA clock source to PLLP, 102MHz */ |
| | | 315 | error = clk_set_parent(sc->sc_clk_sata, pll_p_out0); |
| | | 316 | if (error) { |
| | | 317 | aprint_error_dev(self, "couldn't set sata parent: %d\n", error); |
| | | 318 | return error; |
| | | 319 | } |
| | | 320 | error = clk_set_rate(sc->sc_clk_sata, 102000000); |
| | | 321 | if (error) { |
| | | 322 | aprint_error_dev(self, "couldn't set sata rate: %d\n", error); |
| | | 323 | return error; |
| | | 324 | } |
| | | 325 | |
| | | 326 | /* Ungate SAX partition in the PMC */ |
| | | 327 | tegra_pmc_power(PMC_PARTID_SAX, true); |
| | | 328 | delay(20); |
| | | 329 | |
| | | 330 | /* Remove clamping from SAX partition in the PMC */ |
| | | 331 | tegra_pmc_remove_clamping(PMC_PARTID_SAX); |
| | | 332 | delay(20); |
| | | 333 | |
| | | 334 | /* Un-gate clocks and enable CML clock for SATA */ |
| | | 335 | error = clk_enable(sc->sc_clk_sata); |
| | | 336 | if (error) { |
| | | 337 | aprint_error_dev(self, "couldn't enable sata: %d\n", error); |
| | | 338 | return error; |
| | | 339 | } |
| | | 340 | error = clk_enable(sc->sc_clk_sata_oob); |
| | | 341 | if (error) { |
| | | 342 | aprint_error_dev(self, "couldn't enable sata-oob: %d\n", error); |
| | | 343 | return error; |
| | | 344 | } |
| | | 345 | error = clk_enable(sc->sc_clk_cml1); |
| | | 346 | if (error) { |
| | | 347 | aprint_error_dev(self, "couldn't enable cml1: %d\n", error); |
| | | 348 | return error; |
| | | 349 | } |
| | | 350 | |
| | | 351 | /* De-assert resets */ |
| | | 352 | fdtbus_reset_deassert(sc->sc_rst_sata); |
| | | 353 | fdtbus_reset_deassert(sc->sc_rst_sata_cold); |
| | | 354 | |
| | | 355 | return 0; |
| | | 356 | } |
--- src/sys/arch/arm/nvidia/tegra_nouveau.c 2015/12/13 22:05:52 1.8
+++ src/sys/arch/arm/nvidia/tegra_nouveau.c 2015/12/22 22:10:36 1.9
| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: tegra_nouveau.c,v 1.8 2015/12/13 22:05:52 jmcneill Exp $ */ | | 1 | /* $NetBSD: tegra_nouveau.c,v 1.9 2015/12/22 22:10:36 jmcneill Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> | | 4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -17,56 +17,60 @@ | | | @@ -17,56 +17,60 @@ |
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | | 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | | 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | | 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | | 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | | 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 24 | * 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 | | 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
26 | * SUCH DAMAGE. | | 26 | * SUCH DAMAGE. |
27 | */ | | 27 | */ |
28 | | | 28 | |
29 | #include <sys/cdefs.h> | | 29 | #include <sys/cdefs.h> |
30 | __KERNEL_RCSID(0, "$NetBSD: tegra_nouveau.c,v 1.8 2015/12/13 22:05:52 jmcneill Exp $"); | | 30 | __KERNEL_RCSID(0, "$NetBSD: tegra_nouveau.c,v 1.9 2015/12/22 22:10:36 jmcneill Exp $"); |
31 | | | 31 | |
32 | #include <sys/param.h> | | 32 | #include <sys/param.h> |
33 | #include <sys/bus.h> | | 33 | #include <sys/bus.h> |
34 | #include <sys/device.h> | | 34 | #include <sys/device.h> |
35 | #include <sys/intr.h> | | 35 | #include <sys/intr.h> |
36 | #include <sys/systm.h> | | 36 | #include <sys/systm.h> |
37 | #include <sys/kernel.h> | | 37 | #include <sys/kernel.h> |
38 | #include <sys/module.h> | | 38 | #include <sys/module.h> |
39 | | | 39 | |
40 | #include <arm/nvidia/tegra_reg.h> | | 40 | #include <arm/nvidia/tegra_reg.h> |
| | | 41 | #include <arm/nvidia/tegra_pmcreg.h> |
41 | #include <arm/nvidia/tegra_var.h> | | 42 | #include <arm/nvidia/tegra_var.h> |
42 | | | 43 | |
43 | #include <dev/fdt/fdtvar.h> | | 44 | #include <dev/fdt/fdtvar.h> |
44 | | | 45 | |
45 | #include <drm/drmP.h> | | 46 | #include <drm/drmP.h> |
46 | #include <engine/device.h> | | 47 | #include <engine/device.h> |
47 | | | 48 | |
48 | extern char *nouveau_config; | | 49 | extern char *nouveau_config; |
49 | extern char *nouveau_debug; | | 50 | extern char *nouveau_debug; |
50 | extern struct drm_driver *const nouveau_drm_driver; | | 51 | extern struct drm_driver *const nouveau_drm_driver; |
51 | | | 52 | |
52 | static int tegra_nouveau_match(device_t, cfdata_t, void *); | | 53 | static int tegra_nouveau_match(device_t, cfdata_t, void *); |
53 | static void tegra_nouveau_attach(device_t, device_t, void *); | | 54 | static void tegra_nouveau_attach(device_t, device_t, void *); |
54 | | | 55 | |
55 | struct tegra_nouveau_softc { | | 56 | struct tegra_nouveau_softc { |
56 | device_t sc_dev; | | 57 | device_t sc_dev; |
57 | bus_space_tag_t sc_bst; | | 58 | bus_space_tag_t sc_bst; |
58 | bus_dma_tag_t sc_dmat; | | 59 | bus_dma_tag_t sc_dmat; |
59 | int sc_phandle; | | 60 | int sc_phandle; |
| | | 61 | struct clk *sc_clk_gpu; |
| | | 62 | struct clk *sc_clk_pwr; |
| | | 63 | struct fdtbus_reset *sc_rst_gpu; |
60 | struct drm_device *sc_drm_dev; | | 64 | struct drm_device *sc_drm_dev; |
61 | struct platform_device sc_platform_dev; | | 65 | struct platform_device sc_platform_dev; |
62 | struct nouveau_device *sc_nv_dev; | | 66 | struct nouveau_device *sc_nv_dev; |
63 | }; | | 67 | }; |
64 | | | 68 | |
65 | static void tegra_nouveau_init(device_t); | | 69 | static void tegra_nouveau_init(device_t); |
66 | | | 70 | |
67 | static int tegra_nouveau_get_irq(struct drm_device *); | | 71 | static int tegra_nouveau_get_irq(struct drm_device *); |
68 | static const char *tegra_nouveau_get_name(struct drm_device *); | | 72 | static const char *tegra_nouveau_get_name(struct drm_device *); |
69 | static int tegra_nouveau_set_busid(struct drm_device *, | | 73 | static int tegra_nouveau_set_busid(struct drm_device *, |
70 | struct drm_master *); | | 74 | struct drm_master *); |
71 | static int tegra_nouveau_irq_install(struct drm_device *, | | 75 | static int tegra_nouveau_irq_install(struct drm_device *, |
72 | irqreturn_t (*)(void *), | | 76 | irqreturn_t (*)(void *), |
| @@ -99,33 +103,69 @@ tegra_nouveau_match(device_t parent, cfd | | | @@ -99,33 +103,69 @@ tegra_nouveau_match(device_t parent, cfd |
99 | static void | | 103 | static void |
100 | tegra_nouveau_attach(device_t parent, device_t self, void *aux) | | 104 | tegra_nouveau_attach(device_t parent, device_t self, void *aux) |
101 | { | | 105 | { |
102 | struct tegra_nouveau_softc * const sc = device_private(self); | | 106 | struct tegra_nouveau_softc * const sc = device_private(self); |
103 | struct fdt_attach_args * const faa = aux; | | 107 | struct fdt_attach_args * const faa = aux; |
104 | prop_dictionary_t prop = device_properties(self); | | 108 | prop_dictionary_t prop = device_properties(self); |
105 | int error; | | 109 | int error; |
106 | | | 110 | |
107 | sc->sc_dev = self; | | 111 | sc->sc_dev = self; |
108 | sc->sc_bst = faa->faa_bst; | | 112 | sc->sc_bst = faa->faa_bst; |
109 | sc->sc_dmat = faa->faa_dmat; | | 113 | sc->sc_dmat = faa->faa_dmat; |
110 | sc->sc_phandle = faa->faa_phandle; | | 114 | sc->sc_phandle = faa->faa_phandle; |
111 | | | 115 | |
| | | 116 | sc->sc_clk_gpu = fdtbus_clock_get(faa->faa_phandle, "gpu"); |
| | | 117 | if (sc->sc_clk_gpu == NULL) { |
| | | 118 | aprint_error(": couldn't get clock gpu\n"); |
| | | 119 | return; |
| | | 120 | } |
| | | 121 | sc->sc_clk_pwr = fdtbus_clock_get(faa->faa_phandle, "pwr"); |
| | | 122 | if (sc->sc_clk_pwr == NULL) { |
| | | 123 | aprint_error(": couldn't get clock pwr\n"); |
| | | 124 | return; |
| | | 125 | } |
| | | 126 | sc->sc_rst_gpu = fdtbus_reset_get(faa->faa_phandle, "gpu"); |
| | | 127 | if (sc->sc_rst_gpu == NULL) { |
| | | 128 | aprint_error(": couldn't get reset gpu\n"); |
| | | 129 | return; |
| | | 130 | } |
| | | 131 | |
112 | aprint_naive("\n"); | | 132 | aprint_naive("\n"); |
113 | aprint_normal(": GPU\n"); | | 133 | aprint_normal(": GPU\n"); |
114 | | | 134 | |
115 | prop_dictionary_get_cstring(prop, "debug", &nouveau_debug); | | 135 | prop_dictionary_get_cstring(prop, "debug", &nouveau_debug); |
116 | prop_dictionary_get_cstring(prop, "config", &nouveau_config); | | 136 | prop_dictionary_get_cstring(prop, "config", &nouveau_config); |
117 | | | 137 | |
118 | tegra_car_gpu_enable(); | | 138 | fdtbus_reset_assert(sc->sc_rst_gpu); |
| | | 139 | error = clk_set_rate(sc->sc_clk_pwr, 204000000); |
| | | 140 | if (error) { |
| | | 141 | aprint_error_dev(self, "couldn't set clock pwr frequency: %d\n", |
| | | 142 | error); |
| | | 143 | return; |
| | | 144 | } |
| | | 145 | error = clk_enable(sc->sc_clk_pwr); |
| | | 146 | if (error) { |
| | | 147 | aprint_error_dev(self, "couldn't enable clock pwr: %d\n", |
| | | 148 | error); |
| | | 149 | return; |
| | | 150 | } |
| | | 151 | error = clk_enable(sc->sc_clk_gpu); |
| | | 152 | if (error) { |
| | | 153 | aprint_error_dev(self, "couldn't enable clock gpu: %d\n", |
| | | 154 | error); |
| | | 155 | return; |
| | | 156 | } |
| | | 157 | tegra_pmc_remove_clamping(PMC_PARTID_TD); |
| | | 158 | fdtbus_reset_deassert(sc->sc_rst_gpu); |
119 | | | 159 | |
120 | error = -nouveau_device_create(&sc->sc_platform_dev, | | 160 | error = -nouveau_device_create(&sc->sc_platform_dev, |
121 | NOUVEAU_BUS_PLATFORM, -1, device_xname(self), | | 161 | NOUVEAU_BUS_PLATFORM, -1, device_xname(self), |
122 | nouveau_config, nouveau_debug, &sc->sc_nv_dev); | | 162 | nouveau_config, nouveau_debug, &sc->sc_nv_dev); |
123 | if (error) { | | 163 | if (error) { |
124 | aprint_error_dev(self, "couldn't create nouveau device: %d\n", | | 164 | aprint_error_dev(self, "couldn't create nouveau device: %d\n", |
125 | error); | | 165 | error); |
126 | return; | | 166 | return; |
127 | } | | 167 | } |
128 | | | 168 | |
129 | config_mountroot(self, tegra_nouveau_init); | | 169 | config_mountroot(self, tegra_nouveau_init); |
130 | } | | 170 | } |
131 | | | 171 | |
--- src/sys/arch/arm/nvidia/tegra_cec.c 2015/12/13 17:39:19 1.2
+++ src/sys/arch/arm/nvidia/tegra_cec.c 2015/12/22 22:10:36 1.3
| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: tegra_cec.c,v 1.2 2015/12/13 17:39:19 jmcneill Exp $ */ | | 1 | /* $NetBSD: tegra_cec.c,v 1.3 2015/12/22 22:10:36 jmcneill Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> | | 4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -17,27 +17,27 @@ | | | @@ -17,27 +17,27 @@ |
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | | 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | | 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | | 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | | 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | | 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 24 | * 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 | | 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
26 | * SUCH DAMAGE. | | 26 | * SUCH DAMAGE. |
27 | */ | | 27 | */ |
28 | | | 28 | |
29 | #include <sys/cdefs.h> | | 29 | #include <sys/cdefs.h> |
30 | __KERNEL_RCSID(0, "$NetBSD: tegra_cec.c,v 1.2 2015/12/13 17:39:19 jmcneill Exp $"); | | 30 | __KERNEL_RCSID(0, "$NetBSD: tegra_cec.c,v 1.3 2015/12/22 22:10:36 jmcneill Exp $"); |
31 | | | 31 | |
32 | #include <sys/param.h> | | 32 | #include <sys/param.h> |
33 | #include <sys/bus.h> | | 33 | #include <sys/bus.h> |
34 | #include <sys/device.h> | | 34 | #include <sys/device.h> |
35 | #include <sys/intr.h> | | 35 | #include <sys/intr.h> |
36 | #include <sys/systm.h> | | 36 | #include <sys/systm.h> |
37 | #include <sys/kernel.h> | | 37 | #include <sys/kernel.h> |
38 | #include <sys/mutex.h> | | 38 | #include <sys/mutex.h> |
39 | #include <sys/condvar.h> | | 39 | #include <sys/condvar.h> |
40 | #include <sys/poll.h> | | 40 | #include <sys/poll.h> |
41 | #include <sys/select.h> | | 41 | #include <sys/select.h> |
42 | | | 42 | |
43 | #include <dev/hdmicec/hdmicecio.h> | | 43 | #include <dev/hdmicec/hdmicecio.h> |
| @@ -51,26 +51,28 @@ __KERNEL_RCSID(0, "$NetBSD: tegra_cec.c, | | | @@ -51,26 +51,28 @@ __KERNEL_RCSID(0, "$NetBSD: tegra_cec.c, |
51 | | | 51 | |
52 | #define CEC_VENDORID_NVIDIA 0x00044b | | 52 | #define CEC_VENDORID_NVIDIA 0x00044b |
53 | | | 53 | |
54 | static int tegra_cec_match(device_t, cfdata_t, void *); | | 54 | static int tegra_cec_match(device_t, cfdata_t, void *); |
55 | static void tegra_cec_attach(device_t, device_t, void *); | | 55 | static void tegra_cec_attach(device_t, device_t, void *); |
56 | | | 56 | |
57 | static int tegra_cec_intr(void *); | | 57 | static int tegra_cec_intr(void *); |
58 | | | 58 | |
59 | struct tegra_cec_softc { | | 59 | struct tegra_cec_softc { |
60 | device_t sc_dev; | | 60 | device_t sc_dev; |
61 | bus_space_tag_t sc_bst; | | 61 | bus_space_tag_t sc_bst; |
62 | bus_space_handle_t sc_bsh; | | 62 | bus_space_handle_t sc_bsh; |
63 | void *sc_ih; | | 63 | void *sc_ih; |
| | | 64 | struct clk *sc_clk; |
| | | 65 | struct fdtbus_reset *sc_rst; |
64 | | | 66 | |
65 | kmutex_t sc_lock; | | 67 | kmutex_t sc_lock; |
66 | kcondvar_t sc_cv; | | 68 | kcondvar_t sc_cv; |
67 | | | 69 | |
68 | const char *sc_hdmidevname; | | 70 | const char *sc_hdmidevname; |
69 | device_t sc_cecdev; | | 71 | device_t sc_cecdev; |
70 | | | 72 | |
71 | struct selinfo sc_selinfo; | | 73 | struct selinfo sc_selinfo; |
72 | | | 74 | |
73 | uint8_t sc_rxbuf[16]; | | 75 | uint8_t sc_rxbuf[16]; |
74 | int sc_rxlen; | | 76 | int sc_rxlen; |
75 | bool sc_rxdone; | | 77 | bool sc_rxdone; |
76 | | | 78 | |
| @@ -124,26 +126,36 @@ tegra_cec_attach(device_t parent, device | | | @@ -124,26 +126,36 @@ tegra_cec_attach(device_t parent, device |
124 | struct tegra_cec_softc * const sc = device_private(self); | | 126 | struct tegra_cec_softc * const sc = device_private(self); |
125 | struct fdt_attach_args * const faa = aux; | | 127 | struct fdt_attach_args * const faa = aux; |
126 | prop_dictionary_t prop = device_properties(self); | | 128 | prop_dictionary_t prop = device_properties(self); |
127 | struct hdmicec_attach_args caa; | | 129 | struct hdmicec_attach_args caa; |
128 | char intrstr[128]; | | 130 | char intrstr[128]; |
129 | bus_addr_t addr; | | 131 | bus_addr_t addr; |
130 | bus_size_t size; | | 132 | bus_size_t size; |
131 | int error; | | 133 | int error; |
132 | | | 134 | |
133 | if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) { | | 135 | if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) { |
134 | aprint_error(": couldn't get registers\n"); | | 136 | aprint_error(": couldn't get registers\n"); |
135 | return; | | 137 | return; |
136 | } | | 138 | } |
| | | 139 | sc->sc_clk = fdtbus_clock_get(faa->faa_phandle, "cec"); |
| | | 140 | if (sc->sc_clk == NULL) { |
| | | 141 | aprint_error(": couldn't get clock cec\n"); |
| | | 142 | return; |
| | | 143 | } |
| | | 144 | sc->sc_rst = fdtbus_reset_get(faa->faa_phandle, "cec"); |
| | | 145 | if (sc->sc_rst == NULL) { |
| | | 146 | aprint_error(": couldn't get reset cec\n"); |
| | | 147 | return; |
| | | 148 | } |
137 | | | 149 | |
138 | sc->sc_dev = self; | | 150 | sc->sc_dev = self; |
139 | sc->sc_bst = faa->faa_bst; | | 151 | sc->sc_bst = faa->faa_bst; |
140 | error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh); | | 152 | error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh); |
141 | if (error) { | | 153 | if (error) { |
142 | aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error); | | 154 | aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error); |
143 | return; | | 155 | return; |
144 | } | | 156 | } |
145 | mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM); | | 157 | mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM); |
146 | cv_init(&sc->sc_cv, "tegracec"); | | 158 | cv_init(&sc->sc_cv, "tegracec"); |
147 | selinit(&sc->sc_selinfo); | | 159 | selinit(&sc->sc_selinfo); |
148 | | | 160 | |
149 | aprint_naive("\n"); | | 161 | aprint_naive("\n"); |
| @@ -156,27 +168,33 @@ tegra_cec_attach(device_t parent, device | | | @@ -156,27 +168,33 @@ tegra_cec_attach(device_t parent, device |
156 | | | 168 | |
157 | sc->sc_ih = fdtbus_intr_establish(faa->faa_phandle, 0, IPL_VM, | | 169 | sc->sc_ih = fdtbus_intr_establish(faa->faa_phandle, 0, IPL_VM, |
158 | FDT_INTR_MPSAFE, tegra_cec_intr, sc); | | 170 | FDT_INTR_MPSAFE, tegra_cec_intr, sc); |
159 | if (sc->sc_ih == NULL) { | | 171 | if (sc->sc_ih == NULL) { |
160 | aprint_error_dev(self, "couldn't establish interrupt on %s\n", | | 172 | aprint_error_dev(self, "couldn't establish interrupt on %s\n", |
161 | intrstr); | | 173 | intrstr); |
162 | return; | | 174 | return; |
163 | } | | 175 | } |
164 | aprint_normal_dev(self, "interrupting on %s\n", intrstr); | | 176 | aprint_normal_dev(self, "interrupting on %s\n", intrstr); |
165 | | | 177 | |
166 | prop_dictionary_get_cstring_nocopy(prop, "hdmi-device", | | 178 | prop_dictionary_get_cstring_nocopy(prop, "hdmi-device", |
167 | &sc->sc_hdmidevname); | | 179 | &sc->sc_hdmidevname); |
168 | | | 180 | |
169 | tegra_car_periph_cec_enable(); | | 181 | fdtbus_reset_assert(sc->sc_rst); |
| | | 182 | error = clk_enable(sc->sc_clk); |
| | | 183 | if (error) { |
| | | 184 | aprint_error_dev(self, "couldn't enable cec: %d\n", error); |
| | | 185 | return; |
| | | 186 | } |
| | | 187 | fdtbus_reset_deassert(sc->sc_rst); |
170 | | | 188 | |
171 | CEC_WRITE(sc, CEC_SW_CONTROL_REG, 0); | | 189 | CEC_WRITE(sc, CEC_SW_CONTROL_REG, 0); |
172 | CEC_WRITE(sc, CEC_INPUT_FILTER_REG, 0); | | 190 | CEC_WRITE(sc, CEC_INPUT_FILTER_REG, 0); |
173 | CEC_WRITE(sc, CEC_HW_CONTROL_REG, 0); | | 191 | CEC_WRITE(sc, CEC_HW_CONTROL_REG, 0); |
174 | CEC_WRITE(sc, CEC_INT_MASK_REG, 0); | | 192 | CEC_WRITE(sc, CEC_INT_MASK_REG, 0); |
175 | CEC_WRITE(sc, CEC_INT_STAT_REG, 0xffffffff); | | 193 | CEC_WRITE(sc, CEC_INT_STAT_REG, 0xffffffff); |
176 | | | 194 | |
177 | memset(&caa, 0, sizeof(caa)); | | 195 | memset(&caa, 0, sizeof(caa)); |
178 | caa.priv = sc; | | 196 | caa.priv = sc; |
179 | caa.hwif = &tegra_cec_hw_if; | | 197 | caa.hwif = &tegra_cec_hw_if; |
180 | sc->sc_cecdev = config_found(self, &caa, NULL); | | 198 | sc->sc_cecdev = config_found(self, &caa, NULL); |
181 | } | | 199 | } |
182 | | | 200 | |
--- src/sys/arch/arm/nvidia/tegra_cpufreq.c 2015/11/21 12:09:39 1.2
+++ src/sys/arch/arm/nvidia/tegra_cpufreq.c 2015/12/22 22:10:36 1.3
| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: tegra_cpufreq.c,v 1.2 2015/11/21 12:09:39 jmcneill Exp $ */ | | 1 | /* $NetBSD: tegra_cpufreq.c,v 1.3 2015/12/22 22:10:36 jmcneill Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> | | 4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -19,48 +19,47 @@ | | | @@ -19,48 +19,47 @@ |
19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | | 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | | 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | | 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | | 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 24 | * 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 | | 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
26 | * SUCH DAMAGE. | | 26 | * SUCH DAMAGE. |
27 | */ | | 27 | */ |
28 | | | 28 | |
29 | #include "locators.h" | | 29 | #include "locators.h" |
30 | | | 30 | |
31 | #include <sys/cdefs.h> | | 31 | #include <sys/cdefs.h> |
32 | __KERNEL_RCSID(0, "$NetBSD: tegra_cpufreq.c,v 1.2 2015/11/21 12:09:39 jmcneill Exp $"); | | 32 | __KERNEL_RCSID(0, "$NetBSD: tegra_cpufreq.c,v 1.3 2015/12/22 22:10:36 jmcneill Exp $"); |
33 | | | 33 | |
34 | #include <sys/param.h> | | 34 | #include <sys/param.h> |
35 | #include <sys/bus.h> | | 35 | #include <sys/bus.h> |
36 | #include <sys/device.h> | | 36 | #include <sys/device.h> |
37 | #include <sys/intr.h> | | 37 | #include <sys/intr.h> |
38 | #include <sys/systm.h> | | 38 | #include <sys/systm.h> |
39 | #include <sys/kernel.h> | | 39 | #include <sys/kernel.h> |
40 | #include <sys/atomic.h> | | 40 | #include <sys/atomic.h> |
41 | #include <sys/kmem.h> | | 41 | #include <sys/kmem.h> |
42 | #include <sys/xcall.h> | | 42 | #include <sys/xcall.h> |
43 | #include <sys/sysctl.h> | | 43 | #include <sys/sysctl.h> |
44 | | | 44 | |
45 | #include <arm/nvidia/tegra_var.h> | | 45 | #include <arm/nvidia/tegra_var.h> |
46 | | | 46 | |
47 | static u_int cpufreq_busy; | | 47 | static u_int cpufreq_busy; |
48 | static struct sysctllog *cpufreq_log; | | 48 | static struct sysctllog *cpufreq_log; |
49 | static int cpufreq_node_target, cpufreq_node_current, cpufreq_node_available; | | 49 | static int cpufreq_node_target, cpufreq_node_current, cpufreq_node_available; |
50 | | | 50 | |
51 | static const struct tegra_cpufreq_func *cpufreq_func = NULL; | | 51 | static const struct tegra_cpufreq_func *cpufreq_func = NULL; |
52 | | | 52 | |
53 | static void tegra_cpufreq_post(void *, void *); | | | |
54 | static int tegra_cpufreq_freq_helper(SYSCTLFN_PROTO); | | 53 | static int tegra_cpufreq_freq_helper(SYSCTLFN_PROTO); |
55 | static char tegra_cpufreq_available[TEGRA_CPUFREQ_MAX * 5]; | | 54 | static char tegra_cpufreq_available[TEGRA_CPUFREQ_MAX * 5]; |
56 | | | 55 | |
57 | #define cpufreq_set_rate cpufreq_func->set_rate | | 56 | #define cpufreq_set_rate cpufreq_func->set_rate |
58 | #define cpufreq_get_rate cpufreq_func->get_rate | | 57 | #define cpufreq_get_rate cpufreq_func->get_rate |
59 | #define cpufreq_get_available cpufreq_func->get_available | | 58 | #define cpufreq_get_available cpufreq_func->get_available |
60 | | | 59 | |
61 | void | | 60 | void |
62 | tegra_cpufreq_register(const struct tegra_cpufreq_func *cf) | | 61 | tegra_cpufreq_register(const struct tegra_cpufreq_func *cf) |
63 | { | | 62 | { |
64 | KASSERT(cpufreq_func == NULL); | | 63 | KASSERT(cpufreq_func == NULL); |
65 | cpufreq_func = cf; | | 64 | cpufreq_func = cf; |
66 | } | | 65 | } |
| @@ -118,66 +117,56 @@ tegra_cpufreq_init(void) | | | @@ -118,66 +117,56 @@ tegra_cpufreq_init(void) |
118 | CTL_CREATE, CTL_EOL); | | 117 | CTL_CREATE, CTL_EOL); |
119 | if (error) | | 118 | if (error) |
120 | goto sysctl_failed; | | 119 | goto sysctl_failed; |
121 | cpufreq_node_current = node->sysctl_num; | | 120 | cpufreq_node_current = node->sysctl_num; |
122 | | | 121 | |
123 | error = sysctl_createv(&cpufreq_log, 0, &freqnode, &node, | | 122 | error = sysctl_createv(&cpufreq_log, 0, &freqnode, &node, |
124 | 0, CTLTYPE_STRING, "available", NULL, | | 123 | 0, CTLTYPE_STRING, "available", NULL, |
125 | NULL, 0, tegra_cpufreq_available, 0, | | 124 | NULL, 0, tegra_cpufreq_available, 0, |
126 | CTL_CREATE, CTL_EOL); | | 125 | CTL_CREATE, CTL_EOL); |
127 | if (error) | | 126 | if (error) |
128 | goto sysctl_failed; | | 127 | goto sysctl_failed; |
129 | cpufreq_node_available = node->sysctl_num; | | 128 | cpufreq_node_available = node->sysctl_num; |
130 | | | 129 | |
| | | 130 | device_printf(curcpu()->ci_dev, |
| | | 131 | "setting speed to %d MHz\n", availfreq[0]); |
131 | cpufreq_set_rate(availfreq[0]); | | 132 | cpufreq_set_rate(availfreq[0]); |
132 | tegra_cpufreq_post(NULL, NULL); | | | |
133 | | | 133 | |
134 | return; | | 134 | return; |
135 | | | 135 | |
136 | sysctl_failed: | | 136 | sysctl_failed: |
137 | aprint_error("cpufreq: couldn't create sysctl nodes (%d)\n", error); | | 137 | aprint_error("cpufreq: couldn't create sysctl nodes (%d)\n", error); |
138 | sysctl_teardown(&cpufreq_log); | | 138 | sysctl_teardown(&cpufreq_log); |
139 | } | | 139 | } |
140 | | | 140 | |
141 | static void | | | |
142 | tegra_cpufreq_post(void *arg1, void *arg2) | | | |
143 | { | | | |
144 | struct cpu_info *ci = curcpu(); | | | |
145 | | | | |
146 | ci->ci_data.cpu_cc_freq = cpufreq_get_rate() * 1000000; | | | |
147 | } | | | |
148 | | | | |
149 | static int | | 141 | static int |
150 | tegra_cpufreq_freq_helper(SYSCTLFN_ARGS) | | 142 | tegra_cpufreq_freq_helper(SYSCTLFN_ARGS) |
151 | { | | 143 | { |
152 | struct sysctlnode node; | | 144 | struct sysctlnode node; |
153 | int fq, oldfq = 0, error; | | 145 | int fq, oldfq = 0, error; |
154 | uint64_t xc; | | | |
155 | | | 146 | |
156 | node = *rnode; | | 147 | node = *rnode; |
157 | node.sysctl_data = &fq; | | 148 | node.sysctl_data = &fq; |
158 | | | 149 | |
159 | fq = cpufreq_get_rate(); | | 150 | fq = cpufreq_get_rate(); |
160 | if (rnode->sysctl_num == cpufreq_node_target) | | 151 | if (rnode->sysctl_num == cpufreq_node_target) |
161 | oldfq = fq; | | 152 | oldfq = fq; |
162 | | | 153 | |
163 | error = sysctl_lookup(SYSCTLFN_CALL(&node)); | | 154 | error = sysctl_lookup(SYSCTLFN_CALL(&node)); |
164 | if (error || newp == NULL) | | 155 | if (error || newp == NULL) |
165 | return error; | | 156 | return error; |
166 | | | 157 | |
167 | if (fq == oldfq || rnode->sysctl_num != cpufreq_node_target) | | 158 | if (fq == oldfq || rnode->sysctl_num != cpufreq_node_target) |
168 | return 0; | | 159 | return 0; |
169 | | | 160 | |
170 | if (atomic_cas_uint(&cpufreq_busy, 0, 1) != 0) | | 161 | if (atomic_cas_uint(&cpufreq_busy, 0, 1) != 0) |
171 | return EBUSY; | | 162 | return EBUSY; |
172 | | | 163 | |
173 | error = cpufreq_set_rate(fq); | | 164 | error = cpufreq_set_rate(fq); |
174 | if (error == 0) { | | 165 | if (error == 0) { |
175 | xc = xc_broadcast(0, tegra_cpufreq_post, NULL, NULL); | | | |
176 | xc_wait(xc); | | | |
177 | pmf_event_inject(NULL, PMFE_SPEED_CHANGED); | | 166 | pmf_event_inject(NULL, PMFE_SPEED_CHANGED); |
178 | } | | 167 | } |
179 | | | 168 | |
180 | atomic_dec_uint(&cpufreq_busy); | | 169 | atomic_dec_uint(&cpufreq_busy); |
181 | | | 170 | |
182 | return error; | | 171 | return error; |
183 | } | | 172 | } |
--- src/sys/arch/arm/nvidia/tegra_soctherm.c 2015/12/13 17:39:19 1.2
+++ src/sys/arch/arm/nvidia/tegra_soctherm.c 2015/12/22 22:10:36 1.3
| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: tegra_soctherm.c,v 1.2 2015/12/13 17:39:19 jmcneill Exp $ */ | | 1 | /* $NetBSD: tegra_soctherm.c,v 1.3 2015/12/22 22:10:36 jmcneill Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> | | 4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -17,27 +17,27 @@ | | | @@ -17,27 +17,27 @@ |
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | | 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | | 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | | 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | | 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | | 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 24 | * 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 | | 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
26 | * SUCH DAMAGE. | | 26 | * SUCH DAMAGE. |
27 | */ | | 27 | */ |
28 | | | 28 | |
29 | #include <sys/cdefs.h> | | 29 | #include <sys/cdefs.h> |
30 | __KERNEL_RCSID(0, "$NetBSD: tegra_soctherm.c,v 1.2 2015/12/13 17:39:19 jmcneill Exp $"); | | 30 | __KERNEL_RCSID(0, "$NetBSD: tegra_soctherm.c,v 1.3 2015/12/22 22:10:36 jmcneill Exp $"); |
31 | | | 31 | |
32 | #include <sys/param.h> | | 32 | #include <sys/param.h> |
33 | #include <sys/bus.h> | | 33 | #include <sys/bus.h> |
34 | #include <sys/device.h> | | 34 | #include <sys/device.h> |
35 | #include <sys/intr.h> | | 35 | #include <sys/intr.h> |
36 | #include <sys/systm.h> | | 36 | #include <sys/systm.h> |
37 | #include <sys/kernel.h> | | 37 | #include <sys/kernel.h> |
38 | #include <sys/kmem.h> | | 38 | #include <sys/kmem.h> |
39 | | | 39 | |
40 | #include <dev/sysmon/sysmonvar.h> | | 40 | #include <dev/sysmon/sysmonvar.h> |
41 | | | 41 | |
42 | #include <arm/nvidia/tegra_reg.h> | | 42 | #include <arm/nvidia/tegra_reg.h> |
43 | #include <arm/nvidia/tegra_socthermreg.h> | | 43 | #include <arm/nvidia/tegra_socthermreg.h> |
| @@ -110,37 +110,41 @@ static const struct tegra_soctherm_senso | | | @@ -110,37 +110,41 @@ static const struct tegra_soctherm_senso |
110 | .s_fuse_corr_alpha = 1122300, .s_fuse_corr_beta = -5936400 }, | | 110 | .s_fuse_corr_alpha = 1122300, .s_fuse_corr_beta = -5936400 }, |
111 | { .s_data = { .desc = "MEM1" }, .s_base = 0x160, .s_fuse = 0x15c, | | 111 | { .s_data = { .desc = "MEM1" }, .s_base = 0x160, .s_fuse = 0x15c, |
112 | .s_fuse_corr_alpha = 1145700, .s_fuse_corr_beta = -7124600 }, | | 112 | .s_fuse_corr_alpha = 1145700, .s_fuse_corr_beta = -7124600 }, |
113 | { .s_data = { .desc = "GPU" }, .s_base = 0x180, .s_fuse = 0x154, | | 113 | { .s_data = { .desc = "GPU" }, .s_base = 0x180, .s_fuse = 0x154, |
114 | .s_fuse_corr_alpha = 1120100, .s_fuse_corr_beta = -6000500 }, | | 114 | .s_fuse_corr_alpha = 1120100, .s_fuse_corr_beta = -6000500 }, |
115 | { .s_data = { .desc = "PLLX" }, .s_base = 0x1a0, .s_fuse = 0x160, | | 115 | { .s_data = { .desc = "PLLX" }, .s_base = 0x1a0, .s_fuse = 0x160, |
116 | .s_fuse_corr_alpha = 1106500, .s_fuse_corr_beta = -6729300 }, | | 116 | .s_fuse_corr_alpha = 1106500, .s_fuse_corr_beta = -6729300 }, |
117 | }; | | 117 | }; |
118 | | | 118 | |
119 | struct tegra_soctherm_softc { | | 119 | struct tegra_soctherm_softc { |
120 | device_t sc_dev; | | 120 | device_t sc_dev; |
121 | bus_space_tag_t sc_bst; | | 121 | bus_space_tag_t sc_bst; |
122 | bus_space_handle_t sc_bsh; | | 122 | bus_space_handle_t sc_bsh; |
| | | 123 | struct clk *sc_clk_tsensor; |
| | | 124 | struct clk *sc_clk_soctherm; |
| | | 125 | struct fdtbus_reset *sc_rst_soctherm; |
123 | | | 126 | |
124 | struct sysmon_envsys *sc_sme; | | 127 | struct sysmon_envsys *sc_sme; |
125 | struct tegra_soctherm_sensor *sc_sensors; | | 128 | struct tegra_soctherm_sensor *sc_sensors; |
126 | const struct tegra_soctherm_config *sc_config; | | 129 | const struct tegra_soctherm_config *sc_config; |
127 | | | 130 | |
128 | uint32_t sc_base_cp; | | 131 | uint32_t sc_base_cp; |
129 | uint32_t sc_base_ft; | | 132 | uint32_t sc_base_ft; |
130 | int32_t sc_actual_temp_cp; | | 133 | int32_t sc_actual_temp_cp; |
131 | int32_t sc_actual_temp_ft; | | 134 | int32_t sc_actual_temp_ft; |
132 | }; | | 135 | }; |
133 | | | 136 | |
| | | 137 | static int tegra_soctherm_init_clocks(struct tegra_soctherm_softc *); |
134 | static void tegra_soctherm_init_sensors(struct tegra_soctherm_softc *); | | 138 | static void tegra_soctherm_init_sensors(struct tegra_soctherm_softc *); |
135 | static void tegra_soctherm_init_sensor(struct tegra_soctherm_softc *, | | 139 | static void tegra_soctherm_init_sensor(struct tegra_soctherm_softc *, |
136 | struct tegra_soctherm_sensor *); | | 140 | struct tegra_soctherm_sensor *); |
137 | static void tegra_soctherm_refresh(struct sysmon_envsys *, envsys_data_t *); | | 141 | static void tegra_soctherm_refresh(struct sysmon_envsys *, envsys_data_t *); |
138 | static int tegra_soctherm_decodeint(uint32_t, uint32_t); | | 142 | static int tegra_soctherm_decodeint(uint32_t, uint32_t); |
139 | static int64_t tegra_soctherm_divide(int64_t, int64_t); | | 143 | static int64_t tegra_soctherm_divide(int64_t, int64_t); |
140 | | | 144 | |
141 | CFATTACH_DECL_NEW(tegra_soctherm, sizeof(struct tegra_soctherm_softc), | | 145 | CFATTACH_DECL_NEW(tegra_soctherm, sizeof(struct tegra_soctherm_softc), |
142 | tegra_soctherm_match, tegra_soctherm_attach, NULL, NULL); | | 146 | tegra_soctherm_match, tegra_soctherm_attach, NULL, NULL); |
143 | | | 147 | |
144 | #define SOCTHERM_READ(sc, reg) \ | | 148 | #define SOCTHERM_READ(sc, reg) \ |
145 | bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg)) | | 149 | bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg)) |
146 | #define SOCTHERM_WRITE(sc, reg, val) \ | | 150 | #define SOCTHERM_WRITE(sc, reg, val) \ |
| @@ -167,52 +171,133 @@ tegra_soctherm_match(device_t parent, cf | | | @@ -167,52 +171,133 @@ tegra_soctherm_match(device_t parent, cf |
167 | static void | | 171 | static void |
168 | tegra_soctherm_attach(device_t parent, device_t self, void *aux) | | 172 | tegra_soctherm_attach(device_t parent, device_t self, void *aux) |
169 | { | | 173 | { |
170 | struct tegra_soctherm_softc * const sc = device_private(self); | | 174 | struct tegra_soctherm_softc * const sc = device_private(self); |
171 | struct fdt_attach_args * const faa = aux; | | 175 | struct fdt_attach_args * const faa = aux; |
172 | bus_addr_t addr; | | 176 | bus_addr_t addr; |
173 | bus_size_t size; | | 177 | bus_size_t size; |
174 | int error; | | 178 | int error; |
175 | | | 179 | |
176 | if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) { | | 180 | if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) { |
177 | aprint_error(": couldn't get registers\n"); | | 181 | aprint_error(": couldn't get registers\n"); |
178 | return; | | 182 | return; |
179 | } | | 183 | } |
| | | 184 | sc->sc_clk_tsensor = fdtbus_clock_get(faa->faa_phandle, "tsensor"); |
| | | 185 | if (sc->sc_clk_tsensor == NULL) { |
| | | 186 | aprint_error(": couldn't get clock tsensor\n"); |
| | | 187 | return; |
| | | 188 | } |
| | | 189 | sc->sc_clk_soctherm = fdtbus_clock_get(faa->faa_phandle, "soctherm"); |
| | | 190 | if (sc->sc_clk_soctherm == NULL) { |
| | | 191 | aprint_error(": couldn't get clock soctherm\n"); |
| | | 192 | return; |
| | | 193 | } |
| | | 194 | sc->sc_rst_soctherm = fdtbus_reset_get(faa->faa_phandle, "soctherm"); |
| | | 195 | if (sc->sc_rst_soctherm == NULL) { |
| | | 196 | aprint_error(": couldn't get reset soctherm\n"); |
| | | 197 | return; |
| | | 198 | } |
180 | | | 199 | |
181 | sc->sc_dev = self; | | 200 | sc->sc_dev = self; |
182 | sc->sc_bst = faa->faa_bst; | | 201 | sc->sc_bst = faa->faa_bst; |
183 | error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh); | | 202 | error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh); |
184 | if (error) { | | 203 | if (error) { |
185 | aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error); | | 204 | aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error); |
186 | return; | | 205 | return; |
187 | } | | 206 | } |
188 | | | 207 | |
189 | aprint_naive("\n"); | | 208 | aprint_naive("\n"); |
190 | aprint_normal(": SOC_THERM\n"); | | 209 | aprint_normal(": SOC_THERM\n"); |
191 | | | 210 | |
192 | if (tegra_chip_id() == CHIP_ID_TEGRA124) { | | 211 | if (tegra_chip_id() == CHIP_ID_TEGRA124) { |
193 | sc->sc_config = &tegra124_soctherm_config; | | 212 | sc->sc_config = &tegra124_soctherm_config; |
194 | } | | 213 | } |
195 | | | 214 | |
196 | if (sc->sc_config == NULL) { | | 215 | if (sc->sc_config == NULL) { |
197 | aprint_error_dev(self, "unsupported chip ID\n"); | | 216 | aprint_error_dev(self, "unsupported chip ID\n"); |
198 | return; | | 217 | return; |
199 | } | | 218 | } |
200 | | | 219 | |
201 | tegra_car_soctherm_enable(); | | 220 | if (tegra_soctherm_init_clocks(sc) != 0) |
| | | 221 | return; |
202 | | | 222 | |
203 | tegra_soctherm_init_sensors(sc); | | 223 | tegra_soctherm_init_sensors(sc); |
204 | } | | 224 | } |
205 | | | 225 | |
| | | 226 | static int |
| | | 227 | tegra_soctherm_init_clocks(struct tegra_soctherm_softc *sc) |
| | | 228 | { |
| | | 229 | struct clk *pll_p_out0; |
| | | 230 | struct clk *clk_m; |
| | | 231 | int error; |
| | | 232 | |
| | | 233 | pll_p_out0 = clk_get("pll_p_out0"); |
| | | 234 | if (pll_p_out0 == NULL) { |
| | | 235 | aprint_error_dev(sc->sc_dev, "couldn't find pll_p_out0\n"); |
| | | 236 | return ENOENT; |
| | | 237 | } |
| | | 238 | clk_m = clk_get("clk_m"); |
| | | 239 | if (clk_m == NULL) { |
| | | 240 | aprint_error_dev(sc->sc_dev, "couldn't find clk_m\n"); |
| | | 241 | return ENOENT; |
| | | 242 | } |
| | | 243 | |
| | | 244 | fdtbus_reset_assert(sc->sc_rst_soctherm); |
| | | 245 | |
| | | 246 | error = clk_set_parent(sc->sc_clk_soctherm, pll_p_out0); |
| | | 247 | if (error) { |
| | | 248 | aprint_error_dev(sc->sc_dev, |
| | | 249 | "couldn't set soctherm parent: %d\n", error); |
| | | 250 | return error; |
| | | 251 | } |
| | | 252 | error = clk_set_rate(sc->sc_clk_soctherm, 51000000); |
| | | 253 | if (error) { |
| | | 254 | aprint_error_dev(sc->sc_dev, |
| | | 255 | "couldn't set soctherm rate: %d\n", error); |
| | | 256 | return error; |
| | | 257 | } |
| | | 258 | |
| | | 259 | error = clk_set_parent(sc->sc_clk_tsensor, clk_m); |
| | | 260 | if (error) { |
| | | 261 | aprint_error_dev(sc->sc_dev, |
| | | 262 | "couldn't set tsensor parent: %d\n", error); |
| | | 263 | return error; |
| | | 264 | } |
| | | 265 | error = clk_set_rate(sc->sc_clk_tsensor, 400000); |
| | | 266 | if (error) { |
| | | 267 | aprint_error_dev(sc->sc_dev, |
| | | 268 | "couldn't set tsensor rate: %d\n", error); |
| | | 269 | return error; |
| | | 270 | } |
| | | 271 | |
| | | 272 | error = clk_enable(sc->sc_clk_tsensor); |
| | | 273 | if (error) { |
| | | 274 | aprint_error_dev(sc->sc_dev, "couldn't enable tsensor: %d\n", |
| | | 275 | error); |
| | | 276 | return error; |
| | | 277 | } |
| | | 278 | |
| | | 279 | error = clk_enable(sc->sc_clk_soctherm); |
| | | 280 | if (error) { |
| | | 281 | aprint_error_dev(sc->sc_dev, "couldn't enable soctherm: %d\n", |
| | | 282 | error); |
| | | 283 | return error; |
| | | 284 | } |
| | | 285 | |
| | | 286 | fdtbus_reset_deassert(sc->sc_rst_soctherm); |
| | | 287 | |
| | | 288 | return 0; |
| | | 289 | } |
| | | 290 | |
206 | static void | | 291 | static void |
207 | tegra_soctherm_init_sensors(struct tegra_soctherm_softc *sc) | | 292 | tegra_soctherm_init_sensors(struct tegra_soctherm_softc *sc) |
208 | { | | 293 | { |
209 | const struct tegra_soctherm_config *config = sc->sc_config; | | 294 | const struct tegra_soctherm_config *config = sc->sc_config; |
210 | const u_int nsensors = __arraycount(tegra_soctherm_sensors); | | 295 | const u_int nsensors = __arraycount(tegra_soctherm_sensors); |
211 | const size_t len = sizeof(*sc->sc_sensors) * nsensors; | | 296 | const size_t len = sizeof(*sc->sc_sensors) * nsensors; |
212 | uint32_t val; | | 297 | uint32_t val; |
213 | u_int n; | | 298 | u_int n; |
214 | | | 299 | |
215 | val = tegra_fuse_read(FUSE_TSENSOR8_CALIB_REG); | | 300 | val = tegra_fuse_read(FUSE_TSENSOR8_CALIB_REG); |
216 | sc->sc_base_cp = __SHIFTOUT(val, FUSE_TSENSOR8_CALIB_CP_TS_BASE); | | 301 | sc->sc_base_cp = __SHIFTOUT(val, FUSE_TSENSOR8_CALIB_CP_TS_BASE); |
217 | sc->sc_base_ft = __SHIFTOUT(val, FUSE_TSENSOR8_CALIB_FT_TS_BASE); | | 302 | sc->sc_base_ft = __SHIFTOUT(val, FUSE_TSENSOR8_CALIB_FT_TS_BASE); |
218 | val = tegra_fuse_read(FUSE_SPARE_REALIGNMENT_REG); | | 303 | val = tegra_fuse_read(FUSE_SPARE_REALIGNMENT_REG); |
--- src/sys/arch/arm/nvidia/tegra_timer.c 2015/12/13 17:39:19 1.2
+++ src/sys/arch/arm/nvidia/tegra_timer.c 2015/12/22 22:10:36 1.3
| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: tegra_timer.c,v 1.2 2015/12/13 17:39:19 jmcneill Exp $ */ | | 1 | /* $NetBSD: tegra_timer.c,v 1.3 2015/12/22 22:10:36 jmcneill Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> | | 4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -17,53 +17,54 @@ | | | @@ -17,53 +17,54 @@ |
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | | 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | | 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | | 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | | 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | | 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 24 | * 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 | | 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
26 | * SUCH DAMAGE. | | 26 | * SUCH DAMAGE. |
27 | */ | | 27 | */ |
28 | | | 28 | |
29 | #include <sys/cdefs.h> | | 29 | #include <sys/cdefs.h> |
30 | __KERNEL_RCSID(0, "$NetBSD: tegra_timer.c,v 1.2 2015/12/13 17:39:19 jmcneill Exp $"); | | 30 | __KERNEL_RCSID(0, "$NetBSD: tegra_timer.c,v 1.3 2015/12/22 22:10:36 jmcneill Exp $"); |
31 | | | 31 | |
32 | #include <sys/param.h> | | 32 | #include <sys/param.h> |
33 | #include <sys/bus.h> | | 33 | #include <sys/bus.h> |
34 | #include <sys/device.h> | | 34 | #include <sys/device.h> |
35 | #include <sys/intr.h> | | 35 | #include <sys/intr.h> |
36 | #include <sys/systm.h> | | 36 | #include <sys/systm.h> |
37 | #include <sys/kernel.h> | | 37 | #include <sys/kernel.h> |
38 | #include <sys/wdog.h> | | 38 | #include <sys/wdog.h> |
39 | | | 39 | |
40 | #include <dev/sysmon/sysmonvar.h> | | 40 | #include <dev/sysmon/sysmonvar.h> |
41 | | | 41 | |
42 | #include <arm/nvidia/tegra_reg.h> | | 42 | #include <arm/nvidia/tegra_reg.h> |
43 | #include <arm/nvidia/tegra_timerreg.h> | | 43 | #include <arm/nvidia/tegra_timerreg.h> |
44 | #include <arm/nvidia/tegra_var.h> | | 44 | #include <arm/nvidia/tegra_var.h> |
45 | | | 45 | |
46 | #include <dev/fdt/fdtvar.h> | | 46 | #include <dev/fdt/fdtvar.h> |
47 | | | 47 | |
48 | #define TEGRA_TIMER_WDOG_PERIOD_DEFAULT 10 | | 48 | #define TEGRA_TIMER_WDOG_PERIOD_DEFAULT 10 |
49 | | | 49 | |
50 | static int tegra_timer_match(device_t, cfdata_t, void *); | | 50 | static int tegra_timer_match(device_t, cfdata_t, void *); |
51 | static void tegra_timer_attach(device_t, device_t, void *); | | 51 | static void tegra_timer_attach(device_t, device_t, void *); |
52 | | | 52 | |
53 | struct tegra_timer_softc { | | 53 | struct tegra_timer_softc { |
54 | device_t sc_dev; | | 54 | device_t sc_dev; |
55 | bus_space_tag_t sc_bst; | | 55 | bus_space_tag_t sc_bst; |
56 | bus_space_handle_t sc_bsh; | | 56 | bus_space_handle_t sc_bsh; |
| | | 57 | struct clk *sc_clk_watchdog; |
57 | | | 58 | |
58 | struct sysmon_wdog sc_smw; | | 59 | struct sysmon_wdog sc_smw; |
59 | }; | | 60 | }; |
60 | | | 61 | |
61 | static int tegra_timer_wdt_setmode(struct sysmon_wdog *); | | 62 | static int tegra_timer_wdt_setmode(struct sysmon_wdog *); |
62 | static int tegra_timer_wdt_tickle(struct sysmon_wdog *); | | 63 | static int tegra_timer_wdt_tickle(struct sysmon_wdog *); |
63 | | | 64 | |
64 | CFATTACH_DECL_NEW(tegra_timer, sizeof(struct tegra_timer_softc), | | 65 | CFATTACH_DECL_NEW(tegra_timer, sizeof(struct tegra_timer_softc), |
65 | tegra_timer_match, tegra_timer_attach, NULL, NULL); | | 66 | tegra_timer_match, tegra_timer_attach, NULL, NULL); |
66 | | | 67 | |
67 | #define TIMER_READ(sc, reg) \ | | 68 | #define TIMER_READ(sc, reg) \ |
68 | bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg)) | | 69 | bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg)) |
69 | #define TIMER_WRITE(sc, reg, val) \ | | 70 | #define TIMER_WRITE(sc, reg, val) \ |
| @@ -83,73 +84,108 @@ tegra_timer_match(device_t parent, cfdat | | | @@ -83,73 +84,108 @@ tegra_timer_match(device_t parent, cfdat |
83 | static void | | 84 | static void |
84 | tegra_timer_attach(device_t parent, device_t self, void *aux) | | 85 | tegra_timer_attach(device_t parent, device_t self, void *aux) |
85 | { | | 86 | { |
86 | struct tegra_timer_softc * const sc = device_private(self); | | 87 | struct tegra_timer_softc * const sc = device_private(self); |
87 | struct fdt_attach_args * const faa = aux; | | 88 | struct fdt_attach_args * const faa = aux; |
88 | bus_addr_t addr; | | 89 | bus_addr_t addr; |
89 | bus_size_t size; | | 90 | bus_size_t size; |
90 | int error; | | 91 | int error; |
91 | | | 92 | |
92 | if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) { | | 93 | if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) { |
93 | aprint_error(": couldn't get registers\n"); | | 94 | aprint_error(": couldn't get registers\n"); |
94 | return; | | 95 | return; |
95 | } | | 96 | } |
| | | 97 | sc->sc_clk_watchdog = fdtbus_clock_get(faa->faa_phandle, "watchdog"); |
96 | | | 98 | |
97 | sc->sc_dev = self; | | 99 | sc->sc_dev = self; |
98 | sc->sc_bst = faa->faa_bst; | | 100 | sc->sc_bst = faa->faa_bst; |
99 | error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh); | | 101 | error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh); |
100 | if (error) { | | 102 | if (error) { |
101 | aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error); | | 103 | aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error); |
102 | return; | | 104 | return; |
103 | } | | 105 | } |
104 | | | 106 | |
105 | aprint_naive("\n"); | | 107 | aprint_naive("\n"); |
106 | aprint_normal(": Timers\n"); | | 108 | aprint_normal(": Timers\n"); |
107 | | | 109 | |
108 | sc->sc_smw.smw_name = device_xname(self); | | 110 | if (sc->sc_clk_watchdog) { |
109 | sc->sc_smw.smw_cookie = sc; | | 111 | sc->sc_smw.smw_name = device_xname(self); |
110 | sc->sc_smw.smw_setmode = tegra_timer_wdt_setmode; | | 112 | sc->sc_smw.smw_cookie = sc; |
111 | sc->sc_smw.smw_tickle = tegra_timer_wdt_tickle; | | 113 | sc->sc_smw.smw_setmode = tegra_timer_wdt_setmode; |
112 | sc->sc_smw.smw_period = TEGRA_TIMER_WDOG_PERIOD_DEFAULT; | | 114 | sc->sc_smw.smw_tickle = tegra_timer_wdt_tickle; |
113 | | | 115 | sc->sc_smw.smw_period = TEGRA_TIMER_WDOG_PERIOD_DEFAULT; |
114 | aprint_normal_dev(self, "default watchdog period is %u seconds\n", | | 116 | |
115 | sc->sc_smw.smw_period); | | 117 | aprint_normal_dev(self, |
116 | | | 118 | "default watchdog period is %u seconds\n", |
117 | if (sysmon_wdog_register(&sc->sc_smw) != 0) | | 119 | sc->sc_smw.smw_period); |
118 | aprint_error_dev(self, "couldn't register with sysmon\n"); | | 120 | |
| | | 121 | if (sysmon_wdog_register(&sc->sc_smw) != 0) { |
| | | 122 | aprint_error_dev(self, |
| | | 123 | "couldn't register with sysmon\n"); |
| | | 124 | } |
| | | 125 | } |
119 | } | | 126 | } |
120 | | | 127 | |
121 | static int | | 128 | static int |
122 | tegra_timer_wdt_setmode(struct sysmon_wdog *smw) | | 129 | tegra_timer_wdt_setmode(struct sysmon_wdog *smw) |
123 | { | | 130 | { |
124 | struct tegra_timer_softc * const sc = smw->smw_cookie; | | 131 | struct tegra_timer_softc * const sc = smw->smw_cookie; |
125 | | | 132 | |
126 | if ((smw->smw_mode & WDOG_MODE_MASK) == WDOG_MODE_DISARMED) { | | 133 | if ((smw->smw_mode & WDOG_MODE_MASK) == WDOG_MODE_DISARMED) { |
127 | TIMER_SET_CLEAR(sc, TMR1_PTV_REG, 0, TMR_PTV_EN); | | 134 | TIMER_SET_CLEAR(sc, TMR1_PTV_REG, 0, TMR_PTV_EN); |
128 | tegra_car_wdt_enable(1, false); | | 135 | return clk_disable(sc->sc_clk_watchdog); |
129 | } else { | | 136 | } else { |
130 | if (smw->smw_period == WDOG_PERIOD_DEFAULT) { | | 137 | if (smw->smw_period == WDOG_PERIOD_DEFAULT) { |
131 | sc->sc_smw.smw_period = TEGRA_TIMER_WDOG_PERIOD_DEFAULT; | | 138 | sc->sc_smw.smw_period = TEGRA_TIMER_WDOG_PERIOD_DEFAULT; |
132 | } else if (smw->smw_period == 0 || smw->smw_period > 1000) { | | 139 | } else if (smw->smw_period == 0 || smw->smw_period > 1000) { |
133 | return EINVAL; | | 140 | return EINVAL; |
134 | } else { | | 141 | } else { |
135 | sc->sc_smw.smw_period = smw->smw_period; | | 142 | sc->sc_smw.smw_period = smw->smw_period; |
136 | } | | 143 | } |
137 | u_int tval = (sc->sc_smw.smw_period * 1000000) / 2; | | 144 | u_int tval = (sc->sc_smw.smw_period * 1000000) / 2; |
138 | TIMER_WRITE(sc, TMR1_PTV_REG, | | 145 | TIMER_WRITE(sc, TMR1_PTV_REG, |
139 | TMR_PTV_EN | TMR_PTV_PER | __SHIFTIN(tval, TMR_PTV_VAL)); | | 146 | TMR_PTV_EN | TMR_PTV_PER | __SHIFTIN(tval, TMR_PTV_VAL)); |
140 | TIMER_WRITE(sc, TMR1_PCR_REG, TMR_PCR_INTR_CLR); | | 147 | TIMER_WRITE(sc, TMR1_PCR_REG, TMR_PCR_INTR_CLR); |
141 | tegra_car_wdt_enable(1, true); | | 148 | return clk_enable(sc->sc_clk_watchdog); |
142 | } | | 149 | } |
143 | | | | |
144 | return 0; | | | |
145 | } | | 150 | } |
146 | | | 151 | |
147 | static int | | 152 | static int |
148 | tegra_timer_wdt_tickle(struct sysmon_wdog *smw) | | 153 | tegra_timer_wdt_tickle(struct sysmon_wdog *smw) |
149 | { | | 154 | { |
150 | struct tegra_timer_softc * const sc = smw->smw_cookie; | | 155 | struct tegra_timer_softc * const sc = smw->smw_cookie; |
151 | | | 156 | |
152 | TIMER_WRITE(sc, TMR1_PCR_REG, TMR_PCR_INTR_CLR); | | 157 | TIMER_WRITE(sc, TMR1_PCR_REG, TMR_PCR_INTR_CLR); |
153 | | | 158 | |
154 | return 0; | | 159 | return 0; |
155 | } | | 160 | } |
| | | 161 | |
| | | 162 | void |
| | | 163 | delay(u_int us) |
| | | 164 | { |
| | | 165 | static bool timerus_configured = false; |
| | | 166 | bus_space_tag_t bst = &armv7_generic_bs_tag; |
| | | 167 | bus_space_handle_t bsh; |
| | | 168 | |
| | | 169 | bus_space_subregion(bst, tegra_ppsb_bsh, TEGRA_TIMER_OFFSET, |
| | | 170 | TEGRA_TIMER_SIZE, &bsh); |
| | | 171 | |
| | | 172 | if (__predict_false(timerus_configured == false)) { |
| | | 173 | /* clk_m frequency 12 MHz */ |
| | | 174 | bus_space_write_4(bst, bsh, TMRUS_USEC_CFG_REG, 0xb); |
| | | 175 | timerus_configured = true; |
| | | 176 | } |
| | | 177 | |
| | | 178 | u_int nus = 0; |
| | | 179 | u_int us_prev = bus_space_read_4(bst, bsh, TMRUS_CNTR_1US_REG); |
| | | 180 | |
| | | 181 | while (nus < us) { |
| | | 182 | const u_int us_cur = bus_space_read_4(bst, bsh, |
| | | 183 | TMRUS_CNTR_1US_REG); |
| | | 184 | if (us_cur < us_prev) { |
| | | 185 | nus += (0xffffffff - us_prev) + us_cur; |
| | | 186 | } else { |
| | | 187 | nus += (us_cur - us_prev); |
| | | 188 | } |
| | | 189 | us_prev = us_cur; |
| | | 190 | } |
| | | 191 | } |
--- src/sys/arch/arm/nvidia/tegra_com.c 2015/12/16 19:46:55 1.4
+++ src/sys/arch/arm/nvidia/tegra_com.c 2015/12/22 22:10:36 1.5
| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: tegra_com.c,v 1.4 2015/12/16 19:46:55 jmcneill Exp $ */ | | 1 | /* $NetBSD: tegra_com.c,v 1.5 2015/12/22 22:10:36 jmcneill Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2013 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2013 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Matt Thomas of 3am Software Foundry. | | 8 | * by Matt Thomas of 3am Software Foundry. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -21,67 +21,52 @@ | | | @@ -21,67 +21,52 @@ |
21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | | 21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | | 22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | 23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
29 | * POSSIBILITY OF SUCH DAMAGE. | | 29 | * POSSIBILITY OF SUCH DAMAGE. |
30 | */ | | 30 | */ |
31 | | | 31 | |
32 | #include <sys/cdefs.h> | | 32 | #include <sys/cdefs.h> |
33 | | | 33 | |
34 | __KERNEL_RCSID(1, "$NetBSD: tegra_com.c,v 1.4 2015/12/16 19:46:55 jmcneill Exp $"); | | 34 | __KERNEL_RCSID(1, "$NetBSD: tegra_com.c,v 1.5 2015/12/22 22:10:36 jmcneill Exp $"); |
35 | | | 35 | |
36 | #include <sys/param.h> | | 36 | #include <sys/param.h> |
37 | #include <sys/bus.h> | | 37 | #include <sys/bus.h> |
38 | #include <sys/device.h> | | 38 | #include <sys/device.h> |
39 | #include <sys/intr.h> | | 39 | #include <sys/intr.h> |
40 | #include <sys/systm.h> | | 40 | #include <sys/systm.h> |
41 | #include <sys/time.h> | | 41 | #include <sys/time.h> |
42 | #include <sys/termios.h> | | 42 | #include <sys/termios.h> |
43 | | | 43 | |
44 | #include <arm/nvidia/tegra_reg.h> | | 44 | #include <arm/nvidia/tegra_reg.h> |
45 | #include <arm/nvidia/tegra_var.h> | | 45 | #include <arm/nvidia/tegra_var.h> |
46 | | | 46 | |
47 | #include <dev/ic/comvar.h> | | 47 | #include <dev/ic/comvar.h> |
48 | | | 48 | |
49 | #include <dev/fdt/fdtvar.h> | | 49 | #include <dev/fdt/fdtvar.h> |
50 | | | 50 | |
51 | /* XXX */ | | | |
52 | static int | | | |
53 | tegra_com_addr2port(bus_addr_t addr) | | | |
54 | { | | | |
55 | switch (addr) { | | | |
56 | case TEGRA_APB_BASE + TEGRA_UARTA_OFFSET: | | | |
57 | return 0; | | | |
58 | case TEGRA_APB_BASE + TEGRA_UARTB_OFFSET: | | | |
59 | return 1; | | | |
60 | case TEGRA_APB_BASE + TEGRA_UARTC_OFFSET: | | | |
61 | return 2; | | | |
62 | case TEGRA_APB_BASE + TEGRA_UARTD_OFFSET: | | | |
63 | return 3; | | | |
64 | default: | | | |
65 | return -1; | | | |
66 | } | | | |
67 | } | | | |
68 | | | | |
69 | static int tegra_com_match(device_t, cfdata_t, void *); | | 51 | static int tegra_com_match(device_t, cfdata_t, void *); |
70 | static void tegra_com_attach(device_t, device_t, void *); | | 52 | static void tegra_com_attach(device_t, device_t, void *); |
71 | | | 53 | |
72 | struct tegra_com_softc { | | 54 | struct tegra_com_softc { |
73 | struct com_softc tsc_sc; | | 55 | struct com_softc tsc_sc; |
74 | void *tsc_ih; | | 56 | void *tsc_ih; |
| | | 57 | |
| | | 58 | struct clk *tsc_clk; |
| | | 59 | struct fdtbus_reset *tsc_rst; |
75 | }; | | 60 | }; |
76 | | | 61 | |
77 | CFATTACH_DECL_NEW(tegra_com, sizeof(struct tegra_com_softc), | | 62 | CFATTACH_DECL_NEW(tegra_com, sizeof(struct tegra_com_softc), |
78 | tegra_com_match, tegra_com_attach, NULL, NULL); | | 63 | tegra_com_match, tegra_com_attach, NULL, NULL); |
79 | | | 64 | |
80 | static int | | 65 | static int |
81 | tegra_com_match(device_t parent, cfdata_t cf, void *aux) | | 66 | tegra_com_match(device_t parent, cfdata_t cf, void *aux) |
82 | { | | 67 | { |
83 | const char * const compatible[] = { "nvidia,tegra124-uart", NULL }; | | 68 | const char * const compatible[] = { "nvidia,tegra124-uart", NULL }; |
84 | struct fdt_attach_args * const faa = aux; | | 69 | struct fdt_attach_args * const faa = aux; |
85 | | | 70 | |
86 | return of_match_compatible(faa->faa_phandle, compatible); | | 71 | return of_match_compatible(faa->faa_phandle, compatible); |
87 | } | | 72 | } |
| @@ -112,32 +97,35 @@ tegra_com_attach(device_t parent, device | | | @@ -112,32 +97,35 @@ tegra_com_attach(device_t parent, device |
112 | if (reg_shift == 2) { | | 97 | if (reg_shift == 2) { |
113 | bst = faa->faa_a4x_bst; | | 98 | bst = faa->faa_a4x_bst; |
114 | } else if (reg_shift == 0) { | | 99 | } else if (reg_shift == 0) { |
115 | bst = faa->faa_bst; | | 100 | bst = faa->faa_bst; |
116 | } else { | | 101 | } else { |
117 | aprint_error(": unsupported reg-shift value %d\n", | | 102 | aprint_error(": unsupported reg-shift value %d\n", |
118 | reg_shift); | | 103 | reg_shift); |
119 | return; | | 104 | return; |
120 | } | | 105 | } |
121 | } | | 106 | } |
122 | | | 107 | |
123 | sc->sc_dev = self; | | 108 | sc->sc_dev = self; |
124 | | | 109 | |
125 | /* XXX */ | | 110 | tsc->tsc_clk = fdtbus_clock_get_index(faa->faa_phandle, 0); |
126 | const int port = tegra_com_addr2port(addr); | | 111 | tsc->tsc_rst = fdtbus_reset_get(faa->faa_phandle, "serial"); |
127 | if (port == -1) { | | 112 | |
128 | panic("unsupported com address %#llx", (uint64_t)addr); | | 113 | if (tsc->tsc_clk == NULL) { |
| | | 114 | aprint_error(": couldn't get frequency\n"); |
| | | 115 | return; |
129 | } | | 116 | } |
130 | sc->sc_frequency = tegra_car_uart_rate(port); | | 117 | |
| | | 118 | sc->sc_frequency = clk_get_rate(tsc->tsc_clk); |
131 | sc->sc_type = COM_TYPE_TEGRA; | | 119 | sc->sc_type = COM_TYPE_TEGRA; |
132 | | | 120 | |
133 | error = bus_space_map(bst, addr, size, 0, &bsh); | | 121 | error = bus_space_map(bst, addr, size, 0, &bsh); |
134 | if (error) { | | 122 | if (error) { |
135 | aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error); | | 123 | aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error); |
136 | return; | | 124 | return; |
137 | } | | 125 | } |
138 | | | 126 | |
139 | COM_INIT_REGS(sc->sc_regs, bst, bsh, addr); | | 127 | COM_INIT_REGS(sc->sc_regs, bst, bsh, addr); |
140 | | | 128 | |
141 | com_attach_subr(sc); | | 129 | com_attach_subr(sc); |
142 | aprint_naive("\n"); | | 130 | aprint_naive("\n"); |
143 | | | 131 | |
--- src/sys/arch/arm/nvidia/tegra_drm.c 2015/12/13 17:39:19 1.4
+++ src/sys/arch/arm/nvidia/tegra_drm.c 2015/12/22 22:10:36 1.5
| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: tegra_drm.c,v 1.4 2015/12/13 17:39:19 jmcneill Exp $ */ | | 1 | /* $NetBSD: tegra_drm.c,v 1.5 2015/12/22 22:10:36 jmcneill Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> | | 4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -17,27 +17,27 @@ | | | @@ -17,27 +17,27 @@ |
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | | 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | | 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | | 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | | 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | | 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 24 | * 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 | | 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
26 | * SUCH DAMAGE. | | 26 | * SUCH DAMAGE. |
27 | */ | | 27 | */ |
28 | | | 28 | |
29 | #include <sys/cdefs.h> | | 29 | #include <sys/cdefs.h> |
30 | __KERNEL_RCSID(0, "$NetBSD: tegra_drm.c,v 1.4 2015/12/13 17:39:19 jmcneill Exp $"); | | 30 | __KERNEL_RCSID(0, "$NetBSD: tegra_drm.c,v 1.5 2015/12/22 22:10:36 jmcneill Exp $"); |
31 | | | 31 | |
32 | #include <sys/param.h> | | 32 | #include <sys/param.h> |
33 | #include <sys/bus.h> | | 33 | #include <sys/bus.h> |
34 | #include <sys/device.h> | | 34 | #include <sys/device.h> |
35 | #include <sys/intr.h> | | 35 | #include <sys/intr.h> |
36 | #include <sys/systm.h> | | 36 | #include <sys/systm.h> |
37 | #include <sys/kernel.h> | | 37 | #include <sys/kernel.h> |
38 | #include <sys/conf.h> | | 38 | #include <sys/conf.h> |
39 | | | 39 | |
40 | #include <uvm/uvm_extern.h> | | 40 | #include <uvm/uvm_extern.h> |
41 | #include <uvm/uvm_device.h> | | 41 | #include <uvm/uvm_device.h> |
42 | | | 42 | |
43 | #include <drm/drmP.h> | | 43 | #include <drm/drmP.h> |
| @@ -111,47 +111,69 @@ tegra_drm_match(device_t parent, cfdata_ | | | @@ -111,47 +111,69 @@ tegra_drm_match(device_t parent, cfdata_ |
111 | | | 111 | |
112 | return of_match_compatible(faa->faa_phandle, compatible); | | 112 | return of_match_compatible(faa->faa_phandle, compatible); |
113 | } | | 113 | } |
114 | | | 114 | |
115 | static void | | 115 | static void |
116 | tegra_drm_attach(device_t parent, device_t self, void *aux) | | 116 | tegra_drm_attach(device_t parent, device_t self, void *aux) |
117 | { | | 117 | { |
118 | struct tegra_drm_softc * const sc = device_private(self); | | 118 | struct tegra_drm_softc * const sc = device_private(self); |
119 | struct fdt_attach_args * const faa = aux; | | 119 | struct fdt_attach_args * const faa = aux; |
120 | struct drm_driver * const driver = &tegra_drm_driver; | | 120 | struct drm_driver * const driver = &tegra_drm_driver; |
121 | prop_dictionary_t prop = device_properties(self); | | 121 | prop_dictionary_t prop = device_properties(self); |
122 | int error, node, hdmi_phandle, ddc_phandle; | | 122 | int error, node, hdmi_phandle, ddc_phandle; |
123 | const char * const hdmi_compat[] = { "nvidia,tegra124-hdmi", NULL }; | | 123 | const char * const hdmi_compat[] = { "nvidia,tegra124-hdmi", NULL }; |
| | | 124 | const char * const dc_compat[] = { "nvidia,tegra124-dc", NULL }; |
124 | const char * const hdmi_supplies[] = { | | 125 | const char * const hdmi_supplies[] = { |
125 | "hdmi-supply", "pll-supply", "vdd-supply" | | 126 | "hdmi-supply", "pll-supply", "vdd-supply" |
126 | }; | | 127 | }; |
127 | struct fdtbus_regulator *reg; | | 128 | struct fdtbus_regulator *reg; |
128 | u_int n; | | 129 | struct clk *pll_p_out0; |
| | | 130 | u_int n, ndc; |
129 | | | 131 | |
130 | sc->sc_dev = self; | | 132 | sc->sc_dev = self; |
131 | sc->sc_dmat = faa->faa_dmat; | | 133 | sc->sc_dmat = faa->faa_dmat; |
132 | sc->sc_bst = faa->faa_bst; | | 134 | sc->sc_bst = faa->faa_bst; |
133 | sc->sc_phandle = faa->faa_phandle; | | 135 | sc->sc_phandle = faa->faa_phandle; |
134 | | | 136 | |
135 | aprint_naive("\n"); | | 137 | aprint_naive("\n"); |
136 | aprint_normal("\n"); | | 138 | aprint_normal("\n"); |
137 | | | 139 | |
138 | tegra_car_host1x_enable(); | | 140 | sc->sc_clk_host1x = fdtbus_clock_get_index(faa->faa_phandle, 0); |
| | | 141 | if (sc->sc_clk_host1x == NULL) { |
| | | 142 | aprint_error_dev(self, "couldn't get clock host1x\n"); |
| | | 143 | return; |
| | | 144 | } |
| | | 145 | sc->sc_rst_host1x = fdtbus_reset_get(faa->faa_phandle, "host1x"); |
| | | 146 | if (sc->sc_clk_host1x == NULL || sc->sc_rst_host1x == NULL) { |
| | | 147 | aprint_error_dev(self, "couldn't get reset host1x\n"); |
| | | 148 | return; |
| | | 149 | } |
139 | | | 150 | |
| | | 151 | ndc = 0; |
140 | hdmi_phandle = -1; | | 152 | hdmi_phandle = -1; |
141 | for (node = OF_child(faa->faa_phandle); node; node = OF_peer(node)) { | | 153 | for (node = OF_child(faa->faa_phandle); node; node = OF_peer(node)) { |
142 | if (of_match_compatible(node, hdmi_compat)) { | | 154 | if (of_match_compatible(node, hdmi_compat)) { |
| | | 155 | sc->sc_clk_hdmi = fdtbus_clock_get(node, "hdmi"); |
| | | 156 | sc->sc_clk_hdmi_parent = fdtbus_clock_get(node, |
| | | 157 | "parent"); |
| | | 158 | sc->sc_rst_hdmi = fdtbus_reset_get(node, "hdmi"); |
143 | hdmi_phandle = node; | | 159 | hdmi_phandle = node; |
144 | break; | | 160 | } else if (of_match_compatible(node, dc_compat) && |
| | | 161 | ndc < __arraycount(sc->sc_clk_dc)) { |
| | | 162 | sc->sc_clk_dc[ndc] = fdtbus_clock_get(node, "dc"); |
| | | 163 | sc->sc_clk_dc_parent[ndc] = fdtbus_clock_get(node, |
| | | 164 | "parent"); |
| | | 165 | sc->sc_rst_dc[ndc] = fdtbus_reset_get(node, "dc"); |
| | | 166 | ++ndc; |
145 | } | | 167 | } |
146 | } | | 168 | } |
147 | if (hdmi_phandle >= 0) { | | 169 | if (hdmi_phandle >= 0) { |
148 | ddc_phandle = fdtbus_get_phandle(hdmi_phandle, | | 170 | ddc_phandle = fdtbus_get_phandle(hdmi_phandle, |
149 | "nvidia,ddc-i2c-bus"); | | 171 | "nvidia,ddc-i2c-bus"); |
150 | if (ddc_phandle >= 0) { | | 172 | if (ddc_phandle >= 0) { |
151 | sc->sc_ddc = fdtbus_get_i2c_tag(ddc_phandle); | | 173 | sc->sc_ddc = fdtbus_get_i2c_tag(ddc_phandle); |
152 | } | | 174 | } |
153 | | | 175 | |
154 | sc->sc_pin_hpd = fdtbus_gpio_acquire(hdmi_phandle, | | 176 | sc->sc_pin_hpd = fdtbus_gpio_acquire(hdmi_phandle, |
155 | "nvidia,hpd-gpio", GPIO_PIN_INPUT); | | 177 | "nvidia,hpd-gpio", GPIO_PIN_INPUT); |
156 | | | 178 | |
157 | for (n = 0; n < __arraycount(hdmi_supplies); n++) { | | 179 | for (n = 0; n < __arraycount(hdmi_supplies); n++) { |
| @@ -160,26 +182,53 @@ tegra_drm_attach(device_t parent, device | | | @@ -160,26 +182,53 @@ tegra_drm_attach(device_t parent, device |
160 | if (reg == NULL) { | | 182 | if (reg == NULL) { |
161 | aprint_error_dev(self, "couldn't acquire %s\n", | | 183 | aprint_error_dev(self, "couldn't acquire %s\n", |
162 | supply); | | 184 | supply); |
163 | continue; | | 185 | continue; |
164 | } | | 186 | } |
165 | if (fdtbus_regulator_enable(reg) != 0) { | | 187 | if (fdtbus_regulator_enable(reg) != 0) { |
166 | aprint_error_dev(self, "couldn't enable %s\n", | | 188 | aprint_error_dev(self, "couldn't enable %s\n", |
167 | supply); | | 189 | supply); |
168 | } | | 190 | } |
169 | fdtbus_regulator_release(reg); | | 191 | fdtbus_regulator_release(reg); |
170 | } | | 192 | } |
171 | } | | 193 | } |
172 | | | 194 | |
| | | 195 | pll_p_out0 = clk_get("pll_p_out0"); |
| | | 196 | if (pll_p_out0 == NULL) { |
| | | 197 | aprint_error_dev(self, "couldn't get clock pll_p_out0\n"); |
| | | 198 | return; |
| | | 199 | } |
| | | 200 | fdtbus_reset_assert(sc->sc_rst_host1x); |
| | | 201 | error = clk_set_parent(sc->sc_clk_host1x, pll_p_out0); |
| | | 202 | if (error) { |
| | | 203 | aprint_error_dev(self, "couldn't set host1x clock parent: %d\n", |
| | | 204 | error); |
| | | 205 | return; |
| | | 206 | } |
| | | 207 | error = clk_set_rate(sc->sc_clk_host1x, 408000000); |
| | | 208 | if (error) { |
| | | 209 | aprint_error_dev(self, "couldn't set host1x frequency: %d\n", |
| | | 210 | error); |
| | | 211 | return; |
| | | 212 | } |
| | | 213 | error = clk_enable(sc->sc_clk_host1x); |
| | | 214 | if (error) { |
| | | 215 | aprint_error_dev(self, "couldn't enable clock host1x: %d\n", |
| | | 216 | error); |
| | | 217 | return; |
| | | 218 | } |
| | | 219 | fdtbus_reset_deassert(sc->sc_rst_host1x); |
| | | 220 | clk_put(pll_p_out0); |
| | | 221 | |
173 | prop_dictionary_get_bool(prop, "force-dvi", &sc->sc_force_dvi); | | 222 | prop_dictionary_get_bool(prop, "force-dvi", &sc->sc_force_dvi); |
174 | | | 223 | |
175 | driver->bus = &tegra_drm_bus; | | 224 | driver->bus = &tegra_drm_bus; |
176 | | | 225 | |
177 | sc->sc_ddev = drm_dev_alloc(driver, sc->sc_dev); | | 226 | sc->sc_ddev = drm_dev_alloc(driver, sc->sc_dev); |
178 | if (sc->sc_ddev == NULL) { | | 227 | if (sc->sc_ddev == NULL) { |
179 | aprint_error_dev(self, "couldn't allocate DRM device\n"); | | 228 | aprint_error_dev(self, "couldn't allocate DRM device\n"); |
180 | return; | | 229 | return; |
181 | } | | 230 | } |
182 | sc->sc_ddev->dev_private = sc; | | 231 | sc->sc_ddev->dev_private = sc; |
183 | | | 232 | |
184 | error = -drm_dev_register(sc->sc_ddev, 0); | | 233 | error = -drm_dev_register(sc->sc_ddev, 0); |
185 | if (error) { | | 234 | if (error) { |
--- src/sys/arch/arm/nvidia/tegra_usbphy.c 2015/12/16 19:46:55 1.4
+++ src/sys/arch/arm/nvidia/tegra_usbphy.c 2015/12/22 22:10:36 1.5
| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: tegra_usbphy.c,v 1.4 2015/12/16 19:46:55 jmcneill Exp $ */ | | 1 | /* $NetBSD: tegra_usbphy.c,v 1.5 2015/12/22 22:10:36 jmcneill Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> | | 4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -17,66 +17,55 @@ | | | @@ -17,66 +17,55 @@ |
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | | 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | | 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | | 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | | 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | | 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 24 | * 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 | | 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
26 | * SUCH DAMAGE. | | 26 | * SUCH DAMAGE. |
27 | */ | | 27 | */ |
28 | | | 28 | |
29 | #include <sys/cdefs.h> | | 29 | #include <sys/cdefs.h> |
30 | __KERNEL_RCSID(0, "$NetBSD: tegra_usbphy.c,v 1.4 2015/12/16 19:46:55 jmcneill Exp $"); | | 30 | __KERNEL_RCSID(0, "$NetBSD: tegra_usbphy.c,v 1.5 2015/12/22 22:10:36 jmcneill Exp $"); |
31 | | | 31 | |
32 | #include <sys/param.h> | | 32 | #include <sys/param.h> |
33 | #include <sys/bus.h> | | 33 | #include <sys/bus.h> |
34 | #include <sys/device.h> | | 34 | #include <sys/device.h> |
35 | #include <sys/intr.h> | | 35 | #include <sys/intr.h> |
36 | #include <sys/systm.h> | | 36 | #include <sys/systm.h> |
37 | #include <sys/kernel.h> | | 37 | #include <sys/kernel.h> |
| | | 38 | #include <sys/atomic.h> |
38 | | | 39 | |
39 | #include <arm/nvidia/tegra_reg.h> | | 40 | #include <arm/nvidia/tegra_reg.h> |
40 | #include <arm/nvidia/tegra_var.h> | | 41 | #include <arm/nvidia/tegra_var.h> |
41 | #include <arm/nvidia/tegra_usbreg.h> | | 42 | #include <arm/nvidia/tegra_usbreg.h> |
42 | | | 43 | |
43 | #include <dev/fdt/fdtvar.h> | | 44 | #include <dev/fdt/fdtvar.h> |
44 | | | 45 | |
45 | /* XXX */ | | | |
46 | static int | | | |
47 | tegra_usbphy_addr2port(bus_addr_t addr) | | | |
48 | { | | | |
49 | switch (addr) { | | | |
50 | case TEGRA_AHB_A2_BASE + TEGRA_USB1_OFFSET: | | | |
51 | return 0; | | | |
52 | case TEGRA_AHB_A2_BASE + TEGRA_USB2_OFFSET: | | | |
53 | return 1; | | | |
54 | case TEGRA_AHB_A2_BASE + TEGRA_USB3_OFFSET: | | | |
55 | return 2; | | | |
56 | default: | | | |
57 | return -1; | | | |
58 | } | | | |
59 | } | | | |
60 | | | | |
61 | static int tegra_usbphy_match(device_t, cfdata_t, void *); | | 46 | static int tegra_usbphy_match(device_t, cfdata_t, void *); |
62 | static void tegra_usbphy_attach(device_t, device_t, void *); | | 47 | static void tegra_usbphy_attach(device_t, device_t, void *); |
63 | | | 48 | |
64 | struct tegra_usbphy_softc { | | 49 | struct tegra_usbphy_softc { |
65 | device_t sc_dev; | | 50 | device_t sc_dev; |
66 | bus_space_tag_t sc_bst; | | 51 | bus_space_tag_t sc_bst; |
67 | bus_space_handle_t sc_bsh; | | 52 | bus_space_handle_t sc_bsh; |
68 | int sc_phandle; | | 53 | int sc_phandle; |
69 | u_int sc_port; | | 54 | struct clk *sc_clk_reg; |
| | | 55 | struct clk *sc_clk_pll; |
| | | 56 | struct clk *sc_clk_utmip; |
| | | 57 | struct fdtbus_reset *sc_rst_usb; |
| | | 58 | struct fdtbus_reset *sc_rst_utmip; |
70 | | | 59 | |
71 | struct tegra_gpio_pin *sc_pin_vbus; | | 60 | struct tegra_gpio_pin *sc_pin_vbus; |
72 | uint32_t sc_hssync_start_delay; | | 61 | uint32_t sc_hssync_start_delay; |
73 | uint32_t sc_idle_wait_delay; | | 62 | uint32_t sc_idle_wait_delay; |
74 | uint32_t sc_elastic_limit; | | 63 | uint32_t sc_elastic_limit; |
75 | uint32_t sc_term_range_adj; | | 64 | uint32_t sc_term_range_adj; |
76 | uint32_t sc_xcvr_setup; | | 65 | uint32_t sc_xcvr_setup; |
77 | uint32_t sc_xcvr_lsfslew; | | 66 | uint32_t sc_xcvr_lsfslew; |
78 | uint32_t sc_xcvr_lsrslew; | | 67 | uint32_t sc_xcvr_lsrslew; |
79 | uint32_t sc_hssquelch_level; | | 68 | uint32_t sc_hssquelch_level; |
80 | uint32_t sc_hsdiscon_level; | | 69 | uint32_t sc_hsdiscon_level; |
81 | uint32_t sc_xcvr_hsslew; | | 70 | uint32_t sc_xcvr_hsslew; |
82 | }; | | 71 | }; |
| @@ -92,57 +81,88 @@ tegra_usbphy_match(device_t parent, cfda | | | @@ -92,57 +81,88 @@ tegra_usbphy_match(device_t parent, cfda |
92 | { | | 81 | { |
93 | const char * const compatible[] = { "nvidia,tegra124-usb-phy", NULL }; | | 82 | const char * const compatible[] = { "nvidia,tegra124-usb-phy", NULL }; |
94 | struct fdt_attach_args * const faa = aux; | | 83 | struct fdt_attach_args * const faa = aux; |
95 | | | 84 | |
96 | return of_match_compatible(faa->faa_phandle, compatible); | | 85 | return of_match_compatible(faa->faa_phandle, compatible); |
97 | } | | 86 | } |
98 | | | 87 | |
99 | static void | | 88 | static void |
100 | tegra_usbphy_attach(device_t parent, device_t self, void *aux) | | 89 | tegra_usbphy_attach(device_t parent, device_t self, void *aux) |
101 | { | | 90 | { |
102 | struct tegra_usbphy_softc * const sc = device_private(self); | | 91 | struct tegra_usbphy_softc * const sc = device_private(self); |
103 | struct fdt_attach_args * const faa = aux; | | 92 | struct fdt_attach_args * const faa = aux; |
104 | struct fdtbus_regulator *reg; | | 93 | struct fdtbus_regulator *reg; |
| | | 94 | const int phandle = faa->faa_phandle; |
105 | bus_addr_t addr; | | 95 | bus_addr_t addr; |
106 | bus_size_t size; | | 96 | bus_size_t size; |
107 | int error; | | 97 | int error; |
108 | | | 98 | |
109 | if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) { | | 99 | if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { |
110 | aprint_error(": couldn't get registers\n"); | | 100 | aprint_error(": couldn't get registers\n"); |
111 | return; | | 101 | return; |
112 | } | | 102 | } |
| | | 103 | sc->sc_clk_reg = fdtbus_clock_get(phandle, "reg"); |
| | | 104 | if (sc->sc_clk_reg == NULL) { |
| | | 105 | aprint_error(": couldn't get clock reg\n"); |
| | | 106 | return; |
| | | 107 | } |
| | | 108 | sc->sc_clk_pll = fdtbus_clock_get(phandle, "pll_u"); |
| | | 109 | if (sc->sc_clk_pll == NULL) { |
| | | 110 | aprint_error(": couldn't get clock pll_u\n"); |
| | | 111 | return; |
| | | 112 | } |
| | | 113 | sc->sc_clk_utmip = fdtbus_clock_get(phandle, "utmi-pads"); |
| | | 114 | if (sc->sc_clk_utmip == NULL) { |
| | | 115 | aprint_error(": couldn't get clock utmi-pads\n"); |
| | | 116 | return; |
| | | 117 | } |
| | | 118 | sc->sc_rst_usb = fdtbus_reset_get(phandle, "usb"); |
| | | 119 | if (sc->sc_rst_usb == NULL) { |
| | | 120 | aprint_error(": couldn't get reset usb\n"); |
| | | 121 | return; |
| | | 122 | } |
| | | 123 | sc->sc_rst_utmip = fdtbus_reset_get(phandle, "utmi-pads"); |
| | | 124 | if (sc->sc_rst_utmip == NULL) { |
| | | 125 | aprint_error(": couldn't get reset utmi-pads\n"); |
| | | 126 | return; |
| | | 127 | } |
113 | | | 128 | |
114 | sc->sc_dev = self; | | 129 | sc->sc_dev = self; |
115 | sc->sc_phandle = faa->faa_phandle; | | 130 | sc->sc_phandle = phandle; |
116 | sc->sc_bst = faa->faa_bst; | | 131 | sc->sc_bst = faa->faa_bst; |
117 | error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh); | | 132 | error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh); |
118 | if (error) { | | 133 | if (error) { |
119 | aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error); | | 134 | aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error); |
120 | return; | | 135 | return; |
121 | } | | 136 | } |
122 | sc->sc_port = tegra_usbphy_addr2port(addr); | | | |
123 | | | 137 | |
124 | aprint_naive("\n"); | | 138 | aprint_naive("\n"); |
125 | aprint_normal(": USB PHY%d\n", sc->sc_port + 1); | | 139 | aprint_normal(": USB PHY\n"); |
126 | | | 140 | |
127 | if (tegra_usbphy_parse_properties(sc) != 0) | | 141 | if (tegra_usbphy_parse_properties(sc) != 0) |
128 | return; | | 142 | return; |
129 | | | 143 | |
130 | tegra_car_periph_usb_enable(sc->sc_port); | | 144 | fdtbus_reset_assert(sc->sc_rst_usb); |
131 | delay(2); | | 145 | error = clk_enable(sc->sc_clk_reg); |
| | | 146 | if (error) { |
| | | 147 | aprint_error_dev(self, "couldn't enable clock reg: %d\n", |
| | | 148 | error); |
| | | 149 | return; |
| | | 150 | } |
| | | 151 | fdtbus_reset_deassert(sc->sc_rst_usb); |
132 | | | 152 | |
133 | tegra_usbphy_utmip_init(sc); | | 153 | tegra_usbphy_utmip_init(sc); |
134 | | | 154 | |
135 | reg = fdtbus_regulator_acquire(faa->faa_phandle, "vbus-supply"); | | 155 | reg = fdtbus_regulator_acquire(phandle, "vbus-supply"); |
136 | if (reg) { | | 156 | if (reg) { |
137 | const uint32_t v = bus_space_read_4(sc->sc_bst, sc->sc_bsh, | | 157 | const uint32_t v = bus_space_read_4(sc->sc_bst, sc->sc_bsh, |
138 | TEGRA_EHCI_PHY_VBUS_SENSORS_REG); | | 158 | TEGRA_EHCI_PHY_VBUS_SENSORS_REG); |
139 | if ((v & TEGRA_EHCI_PHY_VBUS_SENSORS_A_VBUS_VLD_STS) == 0) { | | 159 | if ((v & TEGRA_EHCI_PHY_VBUS_SENSORS_A_VBUS_VLD_STS) == 0) { |
140 | fdtbus_regulator_enable(reg); | | 160 | fdtbus_regulator_enable(reg); |
141 | } else { | | 161 | } else { |
142 | aprint_normal_dev(self, "VBUS input active\n"); | | 162 | aprint_normal_dev(self, "VBUS input active\n"); |
143 | } | | 163 | } |
144 | } | | 164 | } |
145 | } | | 165 | } |
146 | | | 166 | |
147 | static int | | 167 | static int |
148 | tegra_usbphy_parse_properties(struct tegra_usbphy_softc *sc) | | 168 | tegra_usbphy_parse_properties(struct tegra_usbphy_softc *sc) |
| @@ -162,72 +182,74 @@ tegra_usbphy_parse_properties(struct teg | | | @@ -162,72 +182,74 @@ tegra_usbphy_parse_properties(struct teg |
162 | PROPGET("nvidia,xcvr-lsfslew", &sc->sc_xcvr_lsfslew); | | 182 | PROPGET("nvidia,xcvr-lsfslew", &sc->sc_xcvr_lsfslew); |
163 | PROPGET("nvidia,xcvr-lsrslew", &sc->sc_xcvr_lsrslew); | | 183 | PROPGET("nvidia,xcvr-lsrslew", &sc->sc_xcvr_lsrslew); |
164 | PROPGET("nvidia,hssquelch-level", &sc->sc_hssquelch_level); | | 184 | PROPGET("nvidia,hssquelch-level", &sc->sc_hssquelch_level); |
165 | PROPGET("nvidia,hsdiscon-level", &sc->sc_hsdiscon_level); | | 185 | PROPGET("nvidia,hsdiscon-level", &sc->sc_hsdiscon_level); |
166 | PROPGET("nvidia,xcvr-hsslew", &sc->sc_xcvr_hsslew); | | 186 | PROPGET("nvidia,xcvr-hsslew", &sc->sc_xcvr_hsslew); |
167 | | | 187 | |
168 | return 0; | | 188 | return 0; |
169 | #undef PROPGET | | 189 | #undef PROPGET |
170 | } | | 190 | } |
171 | | | 191 | |
172 | static void | | 192 | static void |
173 | tegra_usbphy_utmip_init(struct tegra_usbphy_softc *sc) | | 193 | tegra_usbphy_utmip_init(struct tegra_usbphy_softc *sc) |
174 | { | | 194 | { |
| | | 195 | static u_int init_count = 0; |
175 | bus_space_tag_t bst = sc->sc_bst; | | 196 | bus_space_tag_t bst = sc->sc_bst; |
176 | bus_space_handle_t bsh = sc->sc_bsh; | | 197 | bus_space_handle_t bsh = sc->sc_bsh; |
177 | int retry; | | 198 | int retry; |
178 | | | 199 | |
179 | /* Put UTMIP PHY into reset before programming UTMIP config registers */ | | 200 | /* Put UTMIP PHY into reset before programming UTMIP config registers */ |
180 | tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_SUSP_CTRL_REG, | | 201 | tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_SUSP_CTRL_REG, |
181 | TEGRA_EHCI_SUSP_CTRL_UTMIP_RESET, 0); | | 202 | TEGRA_EHCI_SUSP_CTRL_UTMIP_RESET, 0); |
182 | | | 203 | |
183 | /* Enable UTMIP PHY mode */ | | 204 | /* Enable UTMIP PHY mode */ |
184 | tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_SUSP_CTRL_REG, | | 205 | tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_SUSP_CTRL_REG, |
185 | TEGRA_EHCI_SUSP_CTRL_UTMIP_PHY_ENB, 0); | | 206 | TEGRA_EHCI_SUSP_CTRL_UTMIP_PHY_ENB, 0); |
186 | | | 207 | |
187 | /* Stop crystal clock */ | | 208 | /* Stop crystal clock */ |
188 | tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_MISC_CFG1_REG, | | 209 | tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_MISC_CFG1_REG, |
189 | 0, TEGRA_EHCI_UTMIP_MISC_CFG1_PHY_XTAL_CLOCKEN); | | 210 | 0, TEGRA_EHCI_UTMIP_MISC_CFG1_PHY_XTAL_CLOCKEN); |
190 | delay(1); | | 211 | delay(1); |
191 | | | 212 | |
192 | /* Clear session status */ | | 213 | /* Clear session status */ |
193 | tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_PHY_VBUS_SENSORS_REG, | | 214 | tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_PHY_VBUS_SENSORS_REG, |
194 | 0, | | 215 | 0, |
195 | TEGRA_EHCI_PHY_VBUS_SENSORS_B_VLD_SW_VALUE | | | 216 | TEGRA_EHCI_PHY_VBUS_SENSORS_B_VLD_SW_VALUE | |
196 | TEGRA_EHCI_PHY_VBUS_SENSORS_B_VLD_SW_EN); | | 217 | TEGRA_EHCI_PHY_VBUS_SENSORS_B_VLD_SW_EN); |
197 | | | 218 | |
198 | /* PLL configuration */ | | | |
199 | tegra_car_utmip_init(); | | | |
200 | | | | |
201 | /* Transceiver configuration */ | | 219 | /* Transceiver configuration */ |
202 | tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_XCVR_CFG0_REG, | | 220 | tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_XCVR_CFG0_REG, |
203 | __SHIFTIN(4, TEGRA_EHCI_UTMIP_XCVR_CFG0_SETUP) | | | 221 | __SHIFTIN(4, TEGRA_EHCI_UTMIP_XCVR_CFG0_SETUP) | |
204 | __SHIFTIN(3, TEGRA_EHCI_UTMIP_XCVR_CFG0_SETUP_MSB) | | | 222 | __SHIFTIN(3, TEGRA_EHCI_UTMIP_XCVR_CFG0_SETUP_MSB) | |
205 | __SHIFTIN(sc->sc_xcvr_hsslew, | | 223 | __SHIFTIN(sc->sc_xcvr_hsslew, |
206 | TEGRA_EHCI_UTMIP_XCVR_CFG0_HSSLEW_MSB), | | 224 | TEGRA_EHCI_UTMIP_XCVR_CFG0_HSSLEW_MSB), |
207 | TEGRA_EHCI_UTMIP_XCVR_CFG0_SETUP | | | 225 | TEGRA_EHCI_UTMIP_XCVR_CFG0_SETUP | |
208 | TEGRA_EHCI_UTMIP_XCVR_CFG0_SETUP_MSB | | | 226 | TEGRA_EHCI_UTMIP_XCVR_CFG0_SETUP_MSB | |
209 | TEGRA_EHCI_UTMIP_XCVR_CFG0_HSSLEW_MSB); | | 227 | TEGRA_EHCI_UTMIP_XCVR_CFG0_HSSLEW_MSB); |
210 | tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_XCVR_CFG1_REG, | | 228 | tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_XCVR_CFG1_REG, |
211 | __SHIFTIN(sc->sc_term_range_adj, | | 229 | __SHIFTIN(sc->sc_term_range_adj, |
212 | TEGRA_EHCI_UTMIP_XCVR_CFG1_TERM_RANGE_ADJ), | | 230 | TEGRA_EHCI_UTMIP_XCVR_CFG1_TERM_RANGE_ADJ), |
213 | TEGRA_EHCI_UTMIP_XCVR_CFG1_TERM_RANGE_ADJ); | | 231 | TEGRA_EHCI_UTMIP_XCVR_CFG1_TERM_RANGE_ADJ); |
214 | | | 232 | |
215 | if (sc->sc_port == 0) { | | 233 | if (atomic_inc_uint_nv(&init_count) == 1) { |
216 | tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_BIAS_CFG0_REG, | | 234 | tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_BIAS_CFG0_REG, |
217 | TEGRA_EHCI_UTMIP_BIAS_CFG0_HSDISCON_LEVEL_MSB | | | 235 | TEGRA_EHCI_UTMIP_BIAS_CFG0_HSDISCON_LEVEL_MSB | |
218 | __SHIFTIN(sc->sc_hsdiscon_level, | | 236 | __SHIFTIN(sc->sc_hsdiscon_level, |
219 | TEGRA_EHCI_UTMIP_BIAS_CFG0_HSDISCON_LEVEL), | | 237 | TEGRA_EHCI_UTMIP_BIAS_CFG0_HSDISCON_LEVEL), |
| | | 238 | TEGRA_EHCI_UTMIP_BIAS_CFG0_BIASPD | |
220 | TEGRA_EHCI_UTMIP_BIAS_CFG0_HSDISCON_LEVEL); | | 239 | TEGRA_EHCI_UTMIP_BIAS_CFG0_HSDISCON_LEVEL); |
| | | 240 | delay(25); |
| | | 241 | tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_BIAS_CFG1_REG, |
| | | 242 | 0, TEGRA_EHCI_UTMIP_BIAS_CFG1_PDTRK_POWERDOWN); |
221 | } | | 243 | } |
222 | | | 244 | |
223 | /* Misc config */ | | 245 | /* Misc config */ |
224 | tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_MISC_CFG0_REG, | | 246 | tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_MISC_CFG0_REG, |
225 | 0, | | 247 | 0, |
226 | TEGRA_EHCI_UTMIP_MISC_CFG0_SUSPEND_EXIT_ON_EDGE); | | 248 | TEGRA_EHCI_UTMIP_MISC_CFG0_SUSPEND_EXIT_ON_EDGE); |
227 | | | 249 | |
228 | /* BIAS cell power down lag */ | | 250 | /* BIAS cell power down lag */ |
229 | tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_BIAS_CFG1_REG, | | 251 | tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_BIAS_CFG1_REG, |
230 | __SHIFTIN(5, TEGRA_EHCI_UTMIP_BIAS_CFG1_PDTRK_COUNT), | | 252 | __SHIFTIN(5, TEGRA_EHCI_UTMIP_BIAS_CFG1_PDTRK_COUNT), |
231 | TEGRA_EHCI_UTMIP_BIAS_CFG1_PDTRK_COUNT); | | 253 | TEGRA_EHCI_UTMIP_BIAS_CFG1_PDTRK_COUNT); |
232 | | | 254 | |
233 | /* Debounce config */ | | 255 | /* Debounce config */ |
| @@ -255,29 +277,26 @@ tegra_usbphy_utmip_init(struct tegra_usb | | | @@ -255,29 +277,26 @@ tegra_usbphy_utmip_init(struct tegra_usb |
255 | TEGRA_EHCI_UTMIP_HSRX_CFG0_ELASTIC_LIMIT), | | 277 | TEGRA_EHCI_UTMIP_HSRX_CFG0_ELASTIC_LIMIT), |
256 | TEGRA_EHCI_UTMIP_HSRX_CFG0_IDLE_WAIT | | | 278 | TEGRA_EHCI_UTMIP_HSRX_CFG0_IDLE_WAIT | |
257 | TEGRA_EHCI_UTMIP_HSRX_CFG0_ELASTIC_LIMIT); | | 279 | TEGRA_EHCI_UTMIP_HSRX_CFG0_ELASTIC_LIMIT); |
258 | tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_HSRX_CFG1_REG, | | 280 | tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_HSRX_CFG1_REG, |
259 | __SHIFTIN(sc->sc_hssync_start_delay, | | 281 | __SHIFTIN(sc->sc_hssync_start_delay, |
260 | TEGRA_EHCI_UTMIP_HSRX_CFG1_SYNC_START_DLY), | | 282 | TEGRA_EHCI_UTMIP_HSRX_CFG1_SYNC_START_DLY), |
261 | TEGRA_EHCI_UTMIP_HSRX_CFG1_SYNC_START_DLY); | | 283 | TEGRA_EHCI_UTMIP_HSRX_CFG1_SYNC_START_DLY); |
262 | | | 284 | |
263 | /* Start crystal clock */ | | 285 | /* Start crystal clock */ |
264 | delay(1); | | 286 | delay(1); |
265 | tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_MISC_CFG1_REG, | | 287 | tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_MISC_CFG1_REG, |
266 | TEGRA_EHCI_UTMIP_MISC_CFG1_PHY_XTAL_CLOCKEN, 0); | | 288 | TEGRA_EHCI_UTMIP_MISC_CFG1_PHY_XTAL_CLOCKEN, 0); |
267 | | | 289 | |
268 | /* Clear port PLL powerdown status */ | | | |
269 | tegra_car_utmip_enable(sc->sc_port); | | | |
270 | | | | |
271 | /* Bring UTMIP PHY out of reset */ | | 290 | /* Bring UTMIP PHY out of reset */ |
272 | tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_SUSP_CTRL_REG, | | 291 | tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_SUSP_CTRL_REG, |
273 | 0, TEGRA_EHCI_SUSP_CTRL_UTMIP_RESET); | | 292 | 0, TEGRA_EHCI_SUSP_CTRL_UTMIP_RESET); |
274 | for (retry = 100000; retry > 0; retry--) { | | 293 | for (retry = 100000; retry > 0; retry--) { |
275 | const uint32_t susp = bus_space_read_4(bst, bsh, | | 294 | const uint32_t susp = bus_space_read_4(bst, bsh, |
276 | TEGRA_EHCI_SUSP_CTRL_REG); | | 295 | TEGRA_EHCI_SUSP_CTRL_REG); |
277 | if (susp & TEGRA_EHCI_SUSP_CTRL_PHY_CLK_VALID) | | 296 | if (susp & TEGRA_EHCI_SUSP_CTRL_PHY_CLK_VALID) |
278 | break; | | 297 | break; |
279 | delay(1); | | 298 | delay(1); |
280 | } | | 299 | } |
281 | if (retry == 0) { | | 300 | if (retry == 0) { |
282 | aprint_error_dev(sc->sc_dev, "PHY clock is not valid\n"); | | 301 | aprint_error_dev(sc->sc_dev, "PHY clock is not valid\n"); |
283 | return; | | 302 | return; |
| @@ -289,22 +308,14 @@ tegra_usbphy_utmip_init(struct tegra_usb | | | @@ -289,22 +308,14 @@ tegra_usbphy_utmip_init(struct tegra_usb |
289 | TEGRA_EHCI_ICUSB_CTRL_ENB1); | | 308 | TEGRA_EHCI_ICUSB_CTRL_ENB1); |
290 | | | 309 | |
291 | /* Power up UTMPI transceiver */ | | 310 | /* Power up UTMPI transceiver */ |
292 | tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_XCVR_CFG0_REG, | | 311 | tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_XCVR_CFG0_REG, |
293 | 0, | | 312 | 0, |
294 | TEGRA_EHCI_UTMIP_XCVR_CFG0_PD_POWERDOWN | | | 313 | TEGRA_EHCI_UTMIP_XCVR_CFG0_PD_POWERDOWN | |
295 | TEGRA_EHCI_UTMIP_XCVR_CFG0_PD2_POWERDOWN | | | 314 | TEGRA_EHCI_UTMIP_XCVR_CFG0_PD2_POWERDOWN | |
296 | TEGRA_EHCI_UTMIP_XCVR_CFG0_PDZI_POWERDOWN); | | 315 | TEGRA_EHCI_UTMIP_XCVR_CFG0_PDZI_POWERDOWN); |
297 | tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_XCVR_CFG1_REG, | | 316 | tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_XCVR_CFG1_REG, |
298 | 0, | | 317 | 0, |
299 | TEGRA_EHCI_UTMIP_XCVR_CFG1_PDDISC_POWERDOWN | | | 318 | TEGRA_EHCI_UTMIP_XCVR_CFG1_PDDISC_POWERDOWN | |
300 | TEGRA_EHCI_UTMIP_XCVR_CFG1_PDCHRP_POWERDOWN | | | 319 | TEGRA_EHCI_UTMIP_XCVR_CFG1_PDCHRP_POWERDOWN | |
301 | TEGRA_EHCI_UTMIP_XCVR_CFG1_PDDR_POWERDOWN); | | 320 | TEGRA_EHCI_UTMIP_XCVR_CFG1_PDDR_POWERDOWN); |
302 | | | | |
303 | if (sc->sc_port == 0) { | | | |
304 | tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_BIAS_CFG0_REG, | | | |
305 | 0, TEGRA_EHCI_UTMIP_BIAS_CFG0_BIASPD); | | | |
306 | delay(25); | | | |
307 | tegra_reg_set_clear(bst, bsh, TEGRA_EHCI_UTMIP_BIAS_CFG1_REG, | | | |
308 | 0, TEGRA_EHCI_UTMIP_BIAS_CFG1_PDTRK_POWERDOWN); | | | |
309 | } | | | |
310 | } | | 321 | } |
--- src/sys/arch/arm/nvidia/tegra_drm.h 2015/12/13 17:39:19 1.5
+++ src/sys/arch/arm/nvidia/tegra_drm.h 2015/12/22 22:10:36 1.6
| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: tegra_drm.h,v 1.5 2015/12/13 17:39:19 jmcneill Exp $ */ | | 1 | /* $NetBSD: tegra_drm.h,v 1.6 2015/12/22 22:10:36 jmcneill Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> | | 4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -44,54 +44,63 @@ | | | @@ -44,54 +44,63 @@ |
44 | struct tegra_framebuffer; | | 44 | struct tegra_framebuffer; |
45 | | | 45 | |
46 | struct tegra_gem_object; | | 46 | struct tegra_gem_object; |
47 | | | 47 | |
48 | struct tegra_drm_softc { | | 48 | struct tegra_drm_softc { |
49 | device_t sc_dev; | | 49 | device_t sc_dev; |
50 | struct drm_device *sc_ddev; | | 50 | struct drm_device *sc_ddev; |
51 | | | 51 | |
52 | bus_space_tag_t sc_bst; | | 52 | bus_space_tag_t sc_bst; |
53 | bus_dma_tag_t sc_dmat; | | 53 | bus_dma_tag_t sc_dmat; |
54 | | | 54 | |
55 | int sc_phandle; | | 55 | int sc_phandle; |
56 | | | 56 | |
| | | 57 | struct clk *sc_clk_host1x; |
| | | 58 | struct fdtbus_reset *sc_rst_host1x; |
| | | 59 | |
| | | 60 | struct clk *sc_clk_dc[2]; |
| | | 61 | struct clk *sc_clk_dc_parent[2]; |
| | | 62 | struct fdtbus_reset *sc_rst_dc[2]; |
| | | 63 | |
| | | 64 | struct clk *sc_clk_hdmi; |
| | | 65 | struct clk *sc_clk_hdmi_parent; |
| | | 66 | struct fdtbus_reset *sc_rst_hdmi; |
| | | 67 | |
57 | i2c_tag_t sc_ddc; | | 68 | i2c_tag_t sc_ddc; |
58 | struct fdtbus_gpio_pin *sc_pin_hpd; | | 69 | struct fdtbus_gpio_pin *sc_pin_hpd; |
59 | | | 70 | |
60 | struct tegra_gpio_pin *sc_pin_pll; | | | |
61 | struct tegra_gpio_pin *sc_pin_power; | | | |
62 | | | | |
63 | bool sc_force_dvi; | | 71 | bool sc_force_dvi; |
64 | | | 72 | |
65 | uint32_t sc_vbl_received[2]; | | 73 | uint32_t sc_vbl_received[2]; |
66 | }; | | 74 | }; |
67 | | | 75 | |
68 | struct tegra_drmfb_attach_args { | | 76 | struct tegra_drmfb_attach_args { |
69 | struct drm_device *tfa_drm_dev; | | 77 | struct drm_device *tfa_drm_dev; |
70 | struct drm_fb_helper *tfa_fb_helper; | | 78 | struct drm_fb_helper *tfa_fb_helper; |
71 | struct drm_fb_helper_surface_size tfa_fb_sizes; | | 79 | struct drm_fb_helper_surface_size tfa_fb_sizes; |
72 | bus_space_tag_t tfa_fb_bst; | | 80 | bus_space_tag_t tfa_fb_bst; |
73 | bus_dma_tag_t tfa_fb_dmat; | | 81 | bus_dma_tag_t tfa_fb_dmat; |
74 | }; | | 82 | }; |
75 | | | 83 | |
76 | struct tegra_crtc { | | 84 | struct tegra_crtc { |
77 | struct drm_crtc base; | | 85 | struct drm_crtc base; |
78 | bus_space_tag_t bst; | | 86 | bus_space_tag_t bst; |
79 | bus_space_handle_t bsh; | | 87 | bus_space_handle_t bsh; |
80 | bus_size_t size; | | 88 | bus_size_t size; |
81 | int intr; | | 89 | int intr; |
82 | int index; | | 90 | int index; |
83 | void *ih; | | 91 | void *ih; |
84 | bool enabled; | | 92 | bool enabled; |
| | | 93 | struct clk *clk_parent; |
85 | | | 94 | |
86 | struct tegra_gem_object *cursor_obj; | | 95 | struct tegra_gem_object *cursor_obj; |
87 | int cursor_x; | | 96 | int cursor_x; |
88 | int cursor_y; | | 97 | int cursor_y; |
89 | }; | | 98 | }; |
90 | | | 99 | |
91 | struct tegra_encoder { | | 100 | struct tegra_encoder { |
92 | struct drm_encoder base; | | 101 | struct drm_encoder base; |
93 | bus_space_tag_t bst; | | 102 | bus_space_tag_t bst; |
94 | bus_space_handle_t bsh; | | 103 | bus_space_handle_t bsh; |
95 | bus_size_t size; | | 104 | bus_size_t size; |
96 | }; | | 105 | }; |
97 | | | 106 | |
--- src/sys/arch/arm/nvidia/tegra_hdaudio.c 2015/12/13 17:39:19 1.5
+++ src/sys/arch/arm/nvidia/tegra_hdaudio.c 2015/12/22 22:10:36 1.6
| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: tegra_hdaudio.c,v 1.5 2015/12/13 17:39:19 jmcneill Exp $ */ | | 1 | /* $NetBSD: tegra_hdaudio.c,v 1.6 2015/12/22 22:10:36 jmcneill Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> | | 4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -17,27 +17,27 @@ | | | @@ -17,27 +17,27 @@ |
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | | 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | | 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | | 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | | 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | | 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 24 | * 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 | | 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
26 | * SUCH DAMAGE. | | 26 | * SUCH DAMAGE. |
27 | */ | | 27 | */ |
28 | | | 28 | |
29 | #include <sys/cdefs.h> | | 29 | #include <sys/cdefs.h> |
30 | __KERNEL_RCSID(0, "$NetBSD: tegra_hdaudio.c,v 1.5 2015/12/13 17:39:19 jmcneill Exp $"); | | 30 | __KERNEL_RCSID(0, "$NetBSD: tegra_hdaudio.c,v 1.6 2015/12/22 22:10:36 jmcneill Exp $"); |
31 | | | 31 | |
32 | #include <sys/param.h> | | 32 | #include <sys/param.h> |
33 | #include <sys/bus.h> | | 33 | #include <sys/bus.h> |
34 | #include <sys/device.h> | | 34 | #include <sys/device.h> |
35 | #include <sys/intr.h> | | 35 | #include <sys/intr.h> |
36 | #include <sys/systm.h> | | 36 | #include <sys/systm.h> |
37 | #include <sys/kernel.h> | | 37 | #include <sys/kernel.h> |
38 | | | 38 | |
39 | #include <dev/hdaudio/hdaudioreg.h> | | 39 | #include <dev/hdaudio/hdaudioreg.h> |
40 | #include <dev/hdaudio/hdaudiovar.h> | | 40 | #include <dev/hdaudio/hdaudiovar.h> |
41 | | | 41 | |
42 | #include <arm/nvidia/tegra_var.h> | | 42 | #include <arm/nvidia/tegra_var.h> |
43 | #include <arm/nvidia/tegra_pmcreg.h> | | 43 | #include <arm/nvidia/tegra_pmcreg.h> |
| @@ -57,97 +57,212 @@ static int tegra_hdaudio_match(device_t, | | | @@ -57,97 +57,212 @@ static int tegra_hdaudio_match(device_t, |
57 | static void tegra_hdaudio_attach(device_t, device_t, void *); | | 57 | static void tegra_hdaudio_attach(device_t, device_t, void *); |
58 | static int tegra_hdaudio_detach(device_t, int); | | 58 | static int tegra_hdaudio_detach(device_t, int); |
59 | static int tegra_hdaudio_rescan(device_t, const char *, const int *); | | 59 | static int tegra_hdaudio_rescan(device_t, const char *, const int *); |
60 | static void tegra_hdaudio_childdet(device_t, device_t); | | 60 | static void tegra_hdaudio_childdet(device_t, device_t); |
61 | | | 61 | |
62 | static int tegra_hdaudio_intr(void *); | | 62 | static int tegra_hdaudio_intr(void *); |
63 | | | 63 | |
64 | struct tegra_hdaudio_softc { | | 64 | struct tegra_hdaudio_softc { |
65 | struct hdaudio_softc sc; | | 65 | struct hdaudio_softc sc; |
66 | bus_space_tag_t sc_bst; | | 66 | bus_space_tag_t sc_bst; |
67 | bus_space_handle_t sc_bsh; | | 67 | bus_space_handle_t sc_bsh; |
68 | void *sc_ih; | | 68 | void *sc_ih; |
69 | int sc_phandle; | | 69 | int sc_phandle; |
| | | 70 | struct clk *sc_clk_hda; |
| | | 71 | struct clk *sc_clk_hda2hdmi; |
| | | 72 | struct clk *sc_clk_hda2codec_2x; |
| | | 73 | struct fdtbus_reset *sc_rst_hda; |
| | | 74 | struct fdtbus_reset *sc_rst_hda2hdmi; |
| | | 75 | struct fdtbus_reset *sc_rst_hda2codec_2x; |
70 | }; | | 76 | }; |
71 | | | 77 | |
| | | 78 | static int tegra_hdaudio_init_clocks(struct tegra_hdaudio_softc *); |
72 | static void tegra_hdaudio_init(struct tegra_hdaudio_softc *); | | 79 | static void tegra_hdaudio_init(struct tegra_hdaudio_softc *); |
73 | | | 80 | |
74 | CFATTACH_DECL2_NEW(tegra_hdaudio, sizeof(struct tegra_hdaudio_softc), | | 81 | CFATTACH_DECL2_NEW(tegra_hdaudio, sizeof(struct tegra_hdaudio_softc), |
75 | tegra_hdaudio_match, tegra_hdaudio_attach, tegra_hdaudio_detach, NULL, | | 82 | tegra_hdaudio_match, tegra_hdaudio_attach, tegra_hdaudio_detach, NULL, |
76 | tegra_hdaudio_rescan, tegra_hdaudio_childdet); | | 83 | tegra_hdaudio_rescan, tegra_hdaudio_childdet); |
77 | | | 84 | |
78 | static int | | 85 | static int |
79 | tegra_hdaudio_match(device_t parent, cfdata_t cf, void *aux) | | 86 | tegra_hdaudio_match(device_t parent, cfdata_t cf, void *aux) |
80 | { | | 87 | { |
81 | const char * const compatible[] = { "nvidia,tegra124-hda", NULL }; | | 88 | const char * const compatible[] = { "nvidia,tegra124-hda", NULL }; |
82 | struct fdt_attach_args * const faa = aux; | | 89 | struct fdt_attach_args * const faa = aux; |
83 | | | 90 | |
84 | return of_match_compatible(faa->faa_phandle, compatible); | | 91 | return of_match_compatible(faa->faa_phandle, compatible); |
85 | } | | 92 | } |
86 | | | 93 | |
87 | static void | | 94 | static void |
88 | tegra_hdaudio_attach(device_t parent, device_t self, void *aux) | | 95 | tegra_hdaudio_attach(device_t parent, device_t self, void *aux) |
89 | { | | 96 | { |
90 | struct tegra_hdaudio_softc * const sc = device_private(self); | | 97 | struct tegra_hdaudio_softc * const sc = device_private(self); |
91 | struct fdt_attach_args * const faa = aux; | | 98 | struct fdt_attach_args * const faa = aux; |
| | | 99 | const int phandle = faa->faa_phandle; |
92 | char intrstr[128]; | | 100 | char intrstr[128]; |
93 | bus_addr_t addr; | | 101 | bus_addr_t addr; |
94 | bus_size_t size; | | 102 | bus_size_t size; |
95 | int error; | | 103 | int error; |
96 | | | 104 | |
97 | if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) { | | 105 | if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { |
98 | aprint_error(": couldn't get registers\n"); | | 106 | aprint_error(": couldn't get registers\n"); |
99 | return; | | 107 | return; |
100 | } | | 108 | } |
| | | 109 | sc->sc_clk_hda = fdtbus_clock_get(phandle, "hda"); |
| | | 110 | if (sc->sc_clk_hda == NULL) { |
| | | 111 | aprint_error(": couldn't get clock hda\n"); |
| | | 112 | return; |
| | | 113 | } |
| | | 114 | sc->sc_clk_hda2hdmi = fdtbus_clock_get(phandle, "hda2hdmi"); |
| | | 115 | if (sc->sc_clk_hda2hdmi == NULL) { |
| | | 116 | aprint_error(": couldn't get clock hda2hdmi\n"); |
| | | 117 | return; |
| | | 118 | } |
| | | 119 | sc->sc_clk_hda2codec_2x = fdtbus_clock_get(phandle, "hda2codec_2x"); |
| | | 120 | if (sc->sc_clk_hda2codec_2x == NULL) { |
| | | 121 | aprint_error(": couldn't get clock hda2codec_2x\n"); |
| | | 122 | return; |
| | | 123 | } |
| | | 124 | sc->sc_rst_hda = fdtbus_reset_get(phandle, "hda"); |
| | | 125 | if (sc->sc_rst_hda == NULL) { |
| | | 126 | aprint_error(": couldn't get reset hda\n"); |
| | | 127 | return; |
| | | 128 | } |
| | | 129 | sc->sc_rst_hda2hdmi = fdtbus_reset_get(phandle, "hda2hdmi"); |
| | | 130 | if (sc->sc_rst_hda2hdmi == NULL) { |
| | | 131 | aprint_error(": couldn't get reset hda2hdmi\n"); |
| | | 132 | return; |
| | | 133 | } |
| | | 134 | sc->sc_rst_hda2codec_2x = fdtbus_reset_get(phandle, "hda2codec_2x"); |
| | | 135 | if (sc->sc_rst_hda2codec_2x == NULL) { |
| | | 136 | aprint_error(": couldn't get reset hda2codec_2x\n"); |
| | | 137 | return; |
| | | 138 | } |
101 | | | 139 | |
102 | sc->sc_phandle = faa->faa_phandle; | | 140 | sc->sc_phandle = phandle; |
103 | sc->sc_bst = faa->faa_bst; | | 141 | sc->sc_bst = faa->faa_bst; |
104 | error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh); | | 142 | error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh); |
105 | if (error) { | | 143 | if (error) { |
106 | aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error); | | 144 | aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error); |
107 | return; | | 145 | return; |
108 | } | | 146 | } |
109 | | | 147 | |
| | | 148 | sc->sc.sc_dev = self; |
110 | sc->sc.sc_memt = faa->faa_bst; | | 149 | sc->sc.sc_memt = faa->faa_bst; |
111 | bus_space_subregion(sc->sc.sc_memt, sc->sc_bsh, TEGRA_HDAUDIO_OFFSET, | | 150 | bus_space_subregion(sc->sc.sc_memt, sc->sc_bsh, TEGRA_HDAUDIO_OFFSET, |
112 | size - TEGRA_HDAUDIO_OFFSET, &sc->sc.sc_memh); | | 151 | size - TEGRA_HDAUDIO_OFFSET, &sc->sc.sc_memh); |
113 | sc->sc.sc_memvalid = true; | | 152 | sc->sc.sc_memvalid = true; |
114 | sc->sc.sc_dmat = faa->faa_dmat; | | 153 | sc->sc.sc_dmat = faa->faa_dmat; |
115 | sc->sc.sc_flags = HDAUDIO_FLAG_NO_STREAM_RESET; | | 154 | sc->sc.sc_flags = HDAUDIO_FLAG_NO_STREAM_RESET; |
116 | | | 155 | |
117 | aprint_naive("\n"); | | 156 | aprint_naive("\n"); |
118 | aprint_normal(": HDA\n"); | | 157 | aprint_normal(": HDA\n"); |
119 | | | 158 | |
120 | if (!fdtbus_intr_str(faa->faa_phandle, 0, intrstr, sizeof(intrstr))) { | | 159 | if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { |
121 | aprint_error_dev(self, "failed to decode interrupt\n"); | | 160 | aprint_error_dev(self, "failed to decode interrupt\n"); |
122 | return; | | 161 | return; |
123 | } | | 162 | } |
124 | | | 163 | |
125 | sc->sc_ih = fdtbus_intr_establish(faa->faa_phandle, 0, IPL_AUDIO, 0, | | 164 | sc->sc_ih = fdtbus_intr_establish(phandle, 0, IPL_AUDIO, 0, |
126 | tegra_hdaudio_intr, sc); | | 165 | tegra_hdaudio_intr, sc); |
127 | if (sc->sc_ih == NULL) { | | 166 | if (sc->sc_ih == NULL) { |
128 | aprint_error_dev(self, "couldn't establish interrupt on %s\n", | | 167 | aprint_error_dev(self, "couldn't establish interrupt on %s\n", |
129 | intrstr); | | 168 | intrstr); |
130 | return; | | 169 | return; |
131 | } | | 170 | } |
132 | aprint_normal_dev(self, "interrupting on %s\n", intrstr); | | 171 | aprint_normal_dev(self, "interrupting on %s\n", intrstr); |
133 | | | 172 | |
134 | tegra_pmc_power(PMC_PARTID_DISB, true); | | 173 | tegra_pmc_power(PMC_PARTID_DISB, true); |
135 | tegra_car_periph_hda_enable(); | | 174 | |
| | | 175 | if (tegra_hdaudio_init_clocks(sc) != 0) |
| | | 176 | return; |
| | | 177 | |
136 | tegra_hdaudio_init(sc); | | 178 | tegra_hdaudio_init(sc); |
137 | | | 179 | |
138 | hdaudio_attach(self, &sc->sc); | | 180 | hdaudio_attach(self, &sc->sc); |
139 | } | | 181 | } |
140 | | | 182 | |
| | | 183 | static int |
| | | 184 | tegra_hdaudio_init_clocks(struct tegra_hdaudio_softc *sc) |
| | | 185 | { |
| | | 186 | device_t self = sc->sc.sc_dev; |
| | | 187 | struct clk *pll_p_out0; |
| | | 188 | int error; |
| | | 189 | |
| | | 190 | pll_p_out0 = clk_get("pll_p_out0"); |
| | | 191 | if (pll_p_out0 == NULL) { |
| | | 192 | aprint_error_dev(self, "couldn't find pll_p_out0\n"); |
| | | 193 | return ENOENT; |
| | | 194 | } |
| | | 195 | |
| | | 196 | /* Assert resets */ |
| | | 197 | fdtbus_reset_assert(sc->sc_rst_hda); |
| | | 198 | fdtbus_reset_assert(sc->sc_rst_hda2hdmi); |
| | | 199 | fdtbus_reset_assert(sc->sc_rst_hda2codec_2x); |
| | | 200 | |
| | | 201 | /* Set hda to 48MHz and enable it */ |
| | | 202 | error = clk_set_parent(sc->sc_clk_hda, pll_p_out0); |
| | | 203 | if (error) { |
| | | 204 | aprint_error_dev(self, "coulnd't set hda parent: %d\n", error); |
| | | 205 | return error; |
| | | 206 | } |
| | | 207 | error = clk_set_rate(sc->sc_clk_hda, 48000000); |
| | | 208 | if (error) { |
| | | 209 | aprint_error_dev(self, "couldn't set hda frequency: %d\n", |
| | | 210 | error); |
| | | 211 | return error; |
| | | 212 | } |
| | | 213 | error = clk_enable(sc->sc_clk_hda); |
| | | 214 | if (error) { |
| | | 215 | aprint_error_dev(self, "couldn't enable clock hda: %d\n", |
| | | 216 | error); |
| | | 217 | return error; |
| | | 218 | } |
| | | 219 | |
| | | 220 | /* Enable hda2hdmi clock */ |
| | | 221 | error = clk_enable(sc->sc_clk_hda2hdmi); |
| | | 222 | if (error) { |
| | | 223 | aprint_error_dev(self, "couldn't enable clock hda2hdmi: %d\n", |
| | | 224 | error); |
| | | 225 | return error; |
| | | 226 | } |
| | | 227 | |
| | | 228 | /* Set hda2codec_2x to 48MHz and enable it */ |
| | | 229 | error = clk_set_parent(sc->sc_clk_hda2codec_2x, pll_p_out0); |
| | | 230 | if (error) { |
| | | 231 | aprint_error_dev(self, "couldn't set hda2codec_2x parent: %d\n", |
| | | 232 | error); |
| | | 233 | return error; |
| | | 234 | } |
| | | 235 | error = clk_set_rate(sc->sc_clk_hda2codec_2x, 48000000); |
| | | 236 | if (error) { |
| | | 237 | aprint_error_dev(self, |
| | | 238 | "couldn't set clock hda2codec_2x frequency: %d\n", error); |
| | | 239 | return error; |
| | | 240 | } |
| | | 241 | error = clk_enable(sc->sc_clk_hda2codec_2x); |
| | | 242 | if (error) { |
| | | 243 | aprint_error_dev(self, |
| | | 244 | "couldn't enable clock hda2codec_2x: %d\n", error); |
| | | 245 | return error; |
| | | 246 | } |
| | | 247 | |
| | | 248 | /* De-assert resets */ |
| | | 249 | fdtbus_reset_deassert(sc->sc_rst_hda); |
| | | 250 | fdtbus_reset_deassert(sc->sc_rst_hda2hdmi); |
| | | 251 | fdtbus_reset_deassert(sc->sc_rst_hda2codec_2x); |
| | | 252 | |
| | | 253 | return 0; |
| | | 254 | } |
| | | 255 | |
141 | static void | | 256 | static void |
142 | tegra_hdaudio_init(struct tegra_hdaudio_softc *sc) | | 257 | tegra_hdaudio_init(struct tegra_hdaudio_softc *sc) |
143 | { | | 258 | { |
144 | tegra_reg_set_clear(sc->sc_bst, sc->sc_bsh, TEGRA_HDA_IFPS_CONFIG_REG, | | 259 | tegra_reg_set_clear(sc->sc_bst, sc->sc_bsh, TEGRA_HDA_IFPS_CONFIG_REG, |
145 | TEGRA_HDA_IFPS_CONFIG_FPCI_EN, 0); | | 260 | TEGRA_HDA_IFPS_CONFIG_FPCI_EN, 0); |
146 | tegra_reg_set_clear(sc->sc_bst, sc->sc_bsh, TEGRA_HDA_CFG_CMD_REG, | | 261 | tegra_reg_set_clear(sc->sc_bst, sc->sc_bsh, TEGRA_HDA_CFG_CMD_REG, |
147 | TEGRA_HDA_CFG_CMD_ENABLE_SERR | | | 262 | TEGRA_HDA_CFG_CMD_ENABLE_SERR | |
148 | TEGRA_HDA_CFG_CMD_BUS_MASTER | | | 263 | TEGRA_HDA_CFG_CMD_BUS_MASTER | |
149 | TEGRA_HDA_CFG_CMD_MEM_SPACE | | | 264 | TEGRA_HDA_CFG_CMD_MEM_SPACE | |
150 | TEGRA_HDA_CFG_CMD_IO_SPACE, | | 265 | TEGRA_HDA_CFG_CMD_IO_SPACE, |
151 | TEGRA_HDA_CFG_CMD_DISABLE_INTR); | | 266 | TEGRA_HDA_CFG_CMD_DISABLE_INTR); |
152 | bus_space_write_4(sc->sc_bst, sc->sc_bsh, TEGRA_HDA_CFG_BAR0_REG, | | 267 | bus_space_write_4(sc->sc_bst, sc->sc_bsh, TEGRA_HDA_CFG_BAR0_REG, |
153 | 0xffffffff); | | 268 | 0xffffffff); |
--- src/sys/arch/arm/nvidia/tegra_drm_mode.c 2015/12/13 17:39:19 1.10
+++ src/sys/arch/arm/nvidia/tegra_drm_mode.c 2015/12/22 22:10:36 1.11
| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: tegra_drm_mode.c,v 1.10 2015/12/13 17:39:19 jmcneill Exp $ */ | | 1 | /* $NetBSD: tegra_drm_mode.c,v 1.11 2015/12/22 22:10:36 jmcneill Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> | | 4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -17,38 +17,39 @@ | | | @@ -17,38 +17,39 @@ |
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | | 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | | 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | | 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | | 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | | 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 24 | * 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 | | 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
26 | * SUCH DAMAGE. | | 26 | * SUCH DAMAGE. |
27 | */ | | 27 | */ |
28 | | | 28 | |
29 | #include <sys/cdefs.h> | | 29 | #include <sys/cdefs.h> |
30 | __KERNEL_RCSID(0, "$NetBSD: tegra_drm_mode.c,v 1.10 2015/12/13 17:39:19 jmcneill Exp $"); | | 30 | __KERNEL_RCSID(0, "$NetBSD: tegra_drm_mode.c,v 1.11 2015/12/22 22:10:36 jmcneill Exp $"); |
31 | | | 31 | |
32 | #include <drm/drmP.h> | | 32 | #include <drm/drmP.h> |
33 | #include <drm/drm_crtc.h> | | 33 | #include <drm/drm_crtc.h> |
34 | #include <drm/drm_crtc_helper.h> | | 34 | #include <drm/drm_crtc_helper.h> |
35 | #include <drm/drm_edid.h> | | 35 | #include <drm/drm_edid.h> |
36 | | | 36 | |
37 | #include <dev/i2c/ddcvar.h> | | 37 | #include <dev/i2c/ddcvar.h> |
38 | | | 38 | |
39 | #include <arm/nvidia/tegra_reg.h> | | 39 | #include <arm/nvidia/tegra_reg.h> |
40 | #include <arm/nvidia/tegra_var.h> | | 40 | #include <arm/nvidia/tegra_var.h> |
41 | #include <arm/nvidia/tegra_intr.h> | | 41 | #include <arm/nvidia/tegra_intr.h> |
| | | 42 | #include <arm/nvidia/tegra_pmcreg.h> |
42 | #include <arm/nvidia/tegra_dcreg.h> | | 43 | #include <arm/nvidia/tegra_dcreg.h> |
43 | #include <arm/nvidia/tegra_hdmireg.h> | | 44 | #include <arm/nvidia/tegra_hdmireg.h> |
44 | #include <arm/nvidia/tegra_drm.h> | | 45 | #include <arm/nvidia/tegra_drm.h> |
45 | | | 46 | |
46 | #include <dev/fdt/fdtvar.h> | | 47 | #include <dev/fdt/fdtvar.h> |
47 | | | 48 | |
48 | static struct drm_framebuffer *tegra_fb_create(struct drm_device *, | | 49 | static struct drm_framebuffer *tegra_fb_create(struct drm_device *, |
49 | struct drm_file *, struct drm_mode_fb_cmd2 *); | | 50 | struct drm_file *, struct drm_mode_fb_cmd2 *); |
50 | | | 51 | |
51 | static const struct drm_mode_config_funcs tegra_mode_config_funcs = { | | 52 | static const struct drm_mode_config_funcs tegra_mode_config_funcs = { |
52 | .fb_create = tegra_fb_create | | 53 | .fb_create = tegra_fb_create |
53 | }; | | 54 | }; |
54 | | | 55 | |
| @@ -273,31 +274,39 @@ tegra_framebuffer_destroy(struct drm_fra | | | @@ -273,31 +274,39 @@ tegra_framebuffer_destroy(struct drm_fra |
273 | { | | 274 | { |
274 | struct tegra_framebuffer *tegra_fb = to_tegra_framebuffer(fb); | | 275 | struct tegra_framebuffer *tegra_fb = to_tegra_framebuffer(fb); |
275 | | | 276 | |
276 | drm_framebuffer_cleanup(fb); | | 277 | drm_framebuffer_cleanup(fb); |
277 | drm_gem_object_unreference_unlocked(&tegra_fb->obj->base); | | 278 | drm_gem_object_unreference_unlocked(&tegra_fb->obj->base); |
278 | kmem_free(tegra_fb, sizeof(*tegra_fb)); | | 279 | kmem_free(tegra_fb, sizeof(*tegra_fb)); |
279 | } | | 280 | } |
280 | | | 281 | |
281 | static int | | 282 | static int |
282 | tegra_crtc_init(struct drm_device *ddev, int index) | | 283 | tegra_crtc_init(struct drm_device *ddev, int index) |
283 | { | | 284 | { |
284 | struct tegra_drm_softc * const sc = tegra_drm_private(ddev); | | 285 | struct tegra_drm_softc * const sc = tegra_drm_private(ddev); |
285 | struct tegra_crtc *crtc; | | 286 | struct tegra_crtc *crtc; |
| | | 287 | struct clk *clk_parent; |
286 | bus_addr_t offset; | | 288 | bus_addr_t offset; |
287 | bus_size_t size; | | 289 | bus_size_t size; |
288 | u_int intr; | | 290 | u_int intr; |
289 | int error; | | 291 | int error; |
290 | | | 292 | |
| | | 293 | if (sc->sc_clk_dc[index] == NULL || |
| | | 294 | sc->sc_clk_dc_parent[index] == NULL || |
| | | 295 | sc->sc_rst_dc[index] == NULL) { |
| | | 296 | DRM_ERROR("no clocks configured for crtc %d\n", index); |
| | | 297 | return -EIO; |
| | | 298 | } |
| | | 299 | |
291 | switch (index) { | | 300 | switch (index) { |
292 | case 0: | | 301 | case 0: |
293 | offset = TEGRA_GHOST_BASE + TEGRA_DISPLAYA_OFFSET; | | 302 | offset = TEGRA_GHOST_BASE + TEGRA_DISPLAYA_OFFSET; |
294 | size = TEGRA_DISPLAYA_SIZE; | | 303 | size = TEGRA_DISPLAYA_SIZE; |
295 | intr = TEGRA_INTR_DISPLAYA; | | 304 | intr = TEGRA_INTR_DISPLAYA; |
296 | break; | | 305 | break; |
297 | case 1: | | 306 | case 1: |
298 | offset = TEGRA_GHOST_BASE + TEGRA_DISPLAYB_OFFSET; | | 307 | offset = TEGRA_GHOST_BASE + TEGRA_DISPLAYB_OFFSET; |
299 | size = TEGRA_DISPLAYB_SIZE; | | 308 | size = TEGRA_DISPLAYB_SIZE; |
300 | intr = TEGRA_INTR_DISPLAYB; | | 309 | intr = TEGRA_INTR_DISPLAYB; |
301 | break; | | 310 | break; |
302 | default: | | 311 | default: |
303 | return -EINVAL; | | 312 | return -EINVAL; |
| @@ -318,27 +327,58 @@ tegra_crtc_init(struct drm_device *ddev, | | | @@ -318,27 +327,58 @@ tegra_crtc_init(struct drm_device *ddev, |
318 | crtc->intr = intr; | | 327 | crtc->intr = intr; |
319 | crtc->ih = intr_establish(intr, IPL_VM, IST_LEVEL | IST_MPSAFE, | | 328 | crtc->ih = intr_establish(intr, IPL_VM, IST_LEVEL | IST_MPSAFE, |
320 | tegra_crtc_intr, crtc); | | 329 | tegra_crtc_intr, crtc); |
321 | if (crtc->ih == NULL) { | | 330 | if (crtc->ih == NULL) { |
322 | DRM_ERROR("failed to establish interrupt for crtc %d\n", index); | | 331 | DRM_ERROR("failed to establish interrupt for crtc %d\n", index); |
323 | } | | 332 | } |
324 | const size_t cursor_size = 256 * 256 * 4; | | 333 | const size_t cursor_size = 256 * 256 * 4; |
325 | crtc->cursor_obj = tegra_drm_obj_alloc(ddev, cursor_size); | | 334 | crtc->cursor_obj = tegra_drm_obj_alloc(ddev, cursor_size); |
326 | if (crtc->cursor_obj == NULL) { | | 335 | if (crtc->cursor_obj == NULL) { |
327 | kmem_free(crtc, sizeof(*crtc)); | | 336 | kmem_free(crtc, sizeof(*crtc)); |
328 | return -ENOMEM; | | 337 | return -ENOMEM; |
329 | } | | 338 | } |
330 | | | 339 | |
331 | tegra_car_dc_enable(crtc->index); | | 340 | /* Enter reset */ |
| | | 341 | fdtbus_reset_assert(sc->sc_rst_dc[index]); |
| | | 342 | |
| | | 343 | /* Turn on power to display partition */ |
| | | 344 | const u_int pmc_partid = index == 0 ? PMC_PARTID_DIS : PMC_PARTID_DISB; |
| | | 345 | tegra_pmc_power(pmc_partid, true); |
| | | 346 | tegra_pmc_remove_clamping(pmc_partid); |
| | | 347 | |
| | | 348 | /* Set parent clock */ |
| | | 349 | clk_parent = clk_get("pll_d2_out0"); |
| | | 350 | if (clk_parent == NULL) { |
| | | 351 | DRM_ERROR("couldn't find pll_d2_out0\n"); |
| | | 352 | return -EIO; |
| | | 353 | } |
| | | 354 | error = clk_set_parent(sc->sc_clk_dc[index], clk_parent); |
| | | 355 | if (error) { |
| | | 356 | DRM_ERROR("failed to set crtc %d clock parent: %d\n", |
| | | 357 | index, error); |
| | | 358 | return -error; |
| | | 359 | } |
| | | 360 | |
| | | 361 | /* Enable DC clock */ |
| | | 362 | error = clk_enable(sc->sc_clk_dc[index]); |
| | | 363 | if (error) { |
| | | 364 | DRM_ERROR("failed to enable crtc %d clock: %d\n", index, error); |
| | | 365 | return -error; |
| | | 366 | } |
| | | 367 | |
| | | 368 | /* Leave reset */ |
| | | 369 | fdtbus_reset_deassert(sc->sc_rst_dc[index]); |
| | | 370 | |
| | | 371 | crtc->clk_parent = clk_parent; |
332 | | | 372 | |
333 | DC_WRITE(crtc, DC_CMD_INT_ENABLE_REG, DC_CMD_INT_V_BLANK); | | 373 | DC_WRITE(crtc, DC_CMD_INT_ENABLE_REG, DC_CMD_INT_V_BLANK); |
334 | | | 374 | |
335 | drm_crtc_init(ddev, &crtc->base, &tegra_crtc_funcs); | | 375 | drm_crtc_init(ddev, &crtc->base, &tegra_crtc_funcs); |
336 | drm_crtc_helper_add(&crtc->base, &tegra_crtc_helper_funcs); | | 376 | drm_crtc_helper_add(&crtc->base, &tegra_crtc_helper_funcs); |
337 | | | 377 | |
338 | return 0; | | 378 | return 0; |
339 | } | | 379 | } |
340 | | | 380 | |
341 | static int | | 381 | static int |
342 | tegra_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, | | 382 | tegra_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, |
343 | uint32_t handle, uint32_t width, uint32_t height) | | 383 | uint32_t handle, uint32_t width, uint32_t height) |
344 | { | | 384 | { |
| @@ -596,28 +636,28 @@ tegra_crtc_mode_set(struct drm_crtc *crt | | | @@ -596,28 +636,28 @@ tegra_crtc_mode_set(struct drm_crtc *crt |
596 | DC_DISP_DISP_SIGNAL_OPTIONS0_H_PULSE2_ENABLE); | | 636 | DC_DISP_DISP_SIGNAL_OPTIONS0_H_PULSE2_ENABLE); |
597 | DC_WRITE(tegra_crtc, DC_DISP_H_PULSE2_CONTROL_REG, | | 637 | DC_WRITE(tegra_crtc, DC_DISP_H_PULSE2_CONTROL_REG, |
598 | __SHIFTIN(DC_DISP_H_PULSE2_CONTROL_V_QUAL_VACTIVE, | | 638 | __SHIFTIN(DC_DISP_H_PULSE2_CONTROL_V_QUAL_VACTIVE, |
599 | DC_DISP_H_PULSE2_CONTROL_V_QUAL) | | | 639 | DC_DISP_H_PULSE2_CONTROL_V_QUAL) | |
600 | __SHIFTIN(DC_DISP_H_PULSE2_CONTROL_LAST_END_A, | | 640 | __SHIFTIN(DC_DISP_H_PULSE2_CONTROL_LAST_END_A, |
601 | DC_DISP_H_PULSE2_CONTROL_LAST)); | | 641 | DC_DISP_H_PULSE2_CONTROL_LAST)); |
602 | | | 642 | |
603 | const u_int pulse_start = 1 + hspw + hbp - 10; | | 643 | const u_int pulse_start = 1 + hspw + hbp - 10; |
604 | DC_WRITE(tegra_crtc, DC_DISP_H_PULSE2_POSITION_A_REG, | | 644 | DC_WRITE(tegra_crtc, DC_DISP_H_PULSE2_POSITION_A_REG, |
605 | __SHIFTIN(pulse_start, DC_DISP_H_PULSE2_POSITION_A_START) | | | 645 | __SHIFTIN(pulse_start, DC_DISP_H_PULSE2_POSITION_A_START) | |
606 | __SHIFTIN(pulse_start + 8, DC_DISP_H_PULSE2_POSITION_A_END)); | | 646 | __SHIFTIN(pulse_start + 8, DC_DISP_H_PULSE2_POSITION_A_END)); |
607 | | | 647 | |
608 | /* Pixel clock */ | | 648 | /* Pixel clock */ |
609 | const u_int div = (tegra_car_plld2_rate() * 2) / | | 649 | const u_int parent_rate = clk_get_rate(tegra_crtc->clk_parent); |
610 | (mode->crtc_clock * 1000) - 2; | | 650 | const u_int div = (parent_rate * 2) / (mode->crtc_clock * 1000) - 2; |
611 | DC_WRITE(tegra_crtc, DC_DISP_DISP_CLOCK_CONTROL_REG, | | 651 | DC_WRITE(tegra_crtc, DC_DISP_DISP_CLOCK_CONTROL_REG, |
612 | __SHIFTIN(0, DC_DISP_DISP_CLOCK_CONTROL_PIXEL_CLK_DIVIDER) | | | 652 | __SHIFTIN(0, DC_DISP_DISP_CLOCK_CONTROL_PIXEL_CLK_DIVIDER) | |
613 | __SHIFTIN(div, DC_DISP_DISP_CLOCK_CONTROL_SHIFT_CLK_DIVIDER)); | | 653 | __SHIFTIN(div, DC_DISP_DISP_CLOCK_CONTROL_SHIFT_CLK_DIVIDER)); |
614 | | | 654 | |
615 | /* Mode timings */ | | 655 | /* Mode timings */ |
616 | DC_WRITE(tegra_crtc, DC_DISP_REF_TO_SYNC_REG, | | 656 | DC_WRITE(tegra_crtc, DC_DISP_REF_TO_SYNC_REG, |
617 | __SHIFTIN(1, DC_DISP_REF_TO_SYNC_V) | | | 657 | __SHIFTIN(1, DC_DISP_REF_TO_SYNC_V) | |
618 | __SHIFTIN(1, DC_DISP_REF_TO_SYNC_H)); | | 658 | __SHIFTIN(1, DC_DISP_REF_TO_SYNC_H)); |
619 | DC_WRITE(tegra_crtc, DC_DISP_SYNC_WIDTH_REG, | | 659 | DC_WRITE(tegra_crtc, DC_DISP_SYNC_WIDTH_REG, |
620 | __SHIFTIN(vspw, DC_DISP_SYNC_WIDTH_V) | | | 660 | __SHIFTIN(vspw, DC_DISP_SYNC_WIDTH_V) | |
621 | __SHIFTIN(hspw, DC_DISP_SYNC_WIDTH_H)); | | 661 | __SHIFTIN(hspw, DC_DISP_SYNC_WIDTH_H)); |
622 | DC_WRITE(tegra_crtc, DC_DISP_BACK_PORCH_REG, | | 662 | DC_WRITE(tegra_crtc, DC_DISP_BACK_PORCH_REG, |
623 | __SHIFTIN(vbp, DC_DISP_BACK_PORCH_V) | | | 663 | __SHIFTIN(vbp, DC_DISP_BACK_PORCH_V) | |
| @@ -738,43 +778,64 @@ tegra_crtc_commit(struct drm_crtc *crtc) | | | @@ -738,43 +778,64 @@ tegra_crtc_commit(struct drm_crtc *crtc) |
738 | DC_CMD_STATE_CONTROL_GENERAL_ACT_REQ | | | 778 | DC_CMD_STATE_CONTROL_GENERAL_ACT_REQ | |
739 | DC_CMD_STATE_CONTROL_WIN_A_ACT_REQ); | | 779 | DC_CMD_STATE_CONTROL_WIN_A_ACT_REQ); |
740 | | | 780 | |
741 | tegra_crtc->enabled = true; | | 781 | tegra_crtc->enabled = true; |
742 | } | | 782 | } |
743 | | | 783 | |
744 | static int | | 784 | static int |
745 | tegra_encoder_init(struct drm_device *ddev) | | 785 | tegra_encoder_init(struct drm_device *ddev) |
746 | { | | 786 | { |
747 | struct tegra_drm_softc * const sc = tegra_drm_private(ddev); | | 787 | struct tegra_drm_softc * const sc = tegra_drm_private(ddev); |
748 | struct tegra_encoder *encoder; | | 788 | struct tegra_encoder *encoder; |
749 | int error; | | 789 | int error; |
750 | | | 790 | |
| | | 791 | if (sc->sc_clk_hdmi == NULL || |
| | | 792 | sc->sc_clk_hdmi_parent == NULL || |
| | | 793 | sc->sc_rst_hdmi == NULL) { |
| | | 794 | DRM_ERROR("no clocks configured for hdmi\n"); |
| | | 795 | DRM_ERROR("clk: hdmi %p parent %p\n", sc->sc_clk_hdmi, sc->sc_clk_hdmi_parent); |
| | | 796 | DRM_ERROR("rst: hdmi %p\n", sc->sc_rst_hdmi); |
| | | 797 | return -EIO; |
| | | 798 | } |
| | | 799 | |
751 | encoder = kmem_zalloc(sizeof(*encoder), KM_SLEEP); | | 800 | encoder = kmem_zalloc(sizeof(*encoder), KM_SLEEP); |
752 | if (encoder == NULL) | | 801 | if (encoder == NULL) |
753 | return -ENOMEM; | | 802 | return -ENOMEM; |
754 | | | 803 | |
755 | const bus_addr_t offset = TEGRA_GHOST_BASE + TEGRA_HDMI_OFFSET; | | 804 | const bus_addr_t offset = TEGRA_GHOST_BASE + TEGRA_HDMI_OFFSET; |
756 | const bus_size_t size = TEGRA_HDMI_SIZE; | | 805 | const bus_size_t size = TEGRA_HDMI_SIZE; |
757 | | | 806 | |
758 | encoder->bst = sc->sc_bst; | | 807 | encoder->bst = sc->sc_bst; |
759 | error = bus_space_map(encoder->bst, offset, size, 0, &encoder->bsh); | | 808 | error = bus_space_map(encoder->bst, offset, size, 0, &encoder->bsh); |
760 | if (error) { | | 809 | if (error) { |
761 | kmem_free(encoder, sizeof(*encoder)); | | 810 | kmem_free(encoder, sizeof(*encoder)); |
762 | return -error; | | 811 | return -error; |
763 | } | | 812 | } |
764 | encoder->size = size; | | 813 | encoder->size = size; |
765 | | | 814 | |
766 | tegra_pmc_hdmi_enable(); | | 815 | tegra_pmc_hdmi_enable(); |
767 | | | 816 | |
| | | 817 | /* Enable parent PLL */ |
| | | 818 | error = clk_set_rate(sc->sc_clk_hdmi_parent, 594000000); |
| | | 819 | if (error) { |
| | | 820 | DRM_ERROR("couldn't set hdmi parent PLL rate: %d\n", error); |
| | | 821 | return -error; |
| | | 822 | } |
| | | 823 | error = clk_enable(sc->sc_clk_hdmi_parent); |
| | | 824 | if (error) { |
| | | 825 | DRM_ERROR("couldn't enable hdmi parent PLL: %d\n", error); |
| | | 826 | return -error; |
| | | 827 | } |
| | | 828 | |
768 | drm_encoder_init(ddev, &encoder->base, &tegra_encoder_funcs, | | 829 | drm_encoder_init(ddev, &encoder->base, &tegra_encoder_funcs, |
769 | DRM_MODE_ENCODER_TMDS); | | 830 | DRM_MODE_ENCODER_TMDS); |
770 | drm_encoder_helper_add(&encoder->base, &tegra_encoder_helper_funcs); | | 831 | drm_encoder_helper_add(&encoder->base, &tegra_encoder_helper_funcs); |
771 | | | 832 | |
772 | encoder->base.possible_crtcs = (1 << 0) | (1 << 1); | | 833 | encoder->base.possible_crtcs = (1 << 0) | (1 << 1); |
773 | | | 834 | |
774 | return tegra_connector_init(ddev, &encoder->base); | | 835 | return tegra_connector_init(ddev, &encoder->base); |
775 | } | | 836 | } |
776 | | | 837 | |
777 | static void | | 838 | static void |
778 | tegra_encoder_destroy(struct drm_encoder *encoder) | | 839 | tegra_encoder_destroy(struct drm_encoder *encoder) |
779 | { | | 840 | { |
780 | struct tegra_encoder *tegra_encoder = to_tegra_encoder(encoder); | | 841 | struct tegra_encoder *tegra_encoder = to_tegra_encoder(encoder); |
| @@ -801,41 +862,76 @@ tegra_encoder_dpms(struct drm_encoder *e | | | @@ -801,41 +862,76 @@ tegra_encoder_dpms(struct drm_encoder *e |
801 | HDMI_SET_CLEAR(tegra_encoder, HDMI_NV_PDISP_SOR_BLANK_REG, | | 862 | HDMI_SET_CLEAR(tegra_encoder, HDMI_NV_PDISP_SOR_BLANK_REG, |
802 | HDMI_NV_PDISP_SOR_BLANK_OVERRIDE, 0); | | 863 | HDMI_NV_PDISP_SOR_BLANK_OVERRIDE, 0); |
803 | break; | | 864 | break; |
804 | } | | 865 | } |
805 | } | | 866 | } |
806 | | | 867 | |
807 | static bool | | 868 | static bool |
808 | tegra_encoder_mode_fixup(struct drm_encoder *encoder, | | 869 | tegra_encoder_mode_fixup(struct drm_encoder *encoder, |
809 | const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) | | 870 | const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) |
810 | { | | 871 | { |
811 | return true; | | 872 | return true; |
812 | } | | 873 | } |
813 | | | 874 | |
| | | 875 | static int |
| | | 876 | tegra_encoder_hdmi_set_clock(struct drm_encoder *encoder, u_int rate) |
| | | 877 | { |
| | | 878 | struct drm_device *ddev = encoder->dev; |
| | | 879 | struct tegra_drm_softc * const sc = tegra_drm_private(ddev); |
| | | 880 | int error; |
| | | 881 | |
| | | 882 | /* Enter reset */ |
| | | 883 | fdtbus_reset_assert(sc->sc_rst_hdmi); |
| | | 884 | |
| | | 885 | /* Set HDMI parent clock */ |
| | | 886 | error = clk_set_parent(sc->sc_clk_hdmi, sc->sc_clk_hdmi_parent); |
| | | 887 | if (error) { |
| | | 888 | DRM_ERROR("couldn't set hdmi parent: %d\n", error); |
| | | 889 | return -error; |
| | | 890 | } |
| | | 891 | |
| | | 892 | /* Set dot clock frequency */ |
| | | 893 | error = clk_set_rate(sc->sc_clk_hdmi, rate); |
| | | 894 | if (error) { |
| | | 895 | DRM_ERROR("couldn't set hdmi clock: %d\n", error); |
| | | 896 | return -error; |
| | | 897 | } |
| | | 898 | error = clk_enable(sc->sc_clk_hdmi); |
| | | 899 | if (error) { |
| | | 900 | DRM_ERROR("couldn't enable hdmi clock: %d\n", error); |
| | | 901 | return -error; |
| | | 902 | } |
| | | 903 | |
| | | 904 | /* Leave reset */ |
| | | 905 | fdtbus_reset_deassert(sc->sc_rst_hdmi); |
| | | 906 | |
| | | 907 | return 0; |
| | | 908 | } |
| | | 909 | |
814 | static void | | 910 | static void |
815 | tegra_encoder_mode_set(struct drm_encoder *encoder, | | 911 | tegra_encoder_mode_set(struct drm_encoder *encoder, |
816 | struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) | | 912 | struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) |
817 | { | | 913 | { |
818 | struct drm_device *ddev = encoder->dev; | | 914 | struct drm_device *ddev = encoder->dev; |
819 | struct tegra_encoder *tegra_encoder = to_tegra_encoder(encoder); | | 915 | struct tegra_encoder *tegra_encoder = to_tegra_encoder(encoder); |
820 | struct tegra_crtc *tegra_crtc = to_tegra_crtc(encoder->crtc); | | 916 | struct tegra_crtc *tegra_crtc = to_tegra_crtc(encoder->crtc); |
821 | struct tegra_connector *tegra_connector = NULL; | | 917 | struct tegra_connector *tegra_connector = NULL; |
822 | struct drm_connector *connector; | | 918 | struct drm_connector *connector; |
823 | const struct tegra_hdmi_tmds_config *tmds = NULL; | | 919 | const struct tegra_hdmi_tmds_config *tmds = NULL; |
824 | uint32_t input_ctrl; | | 920 | uint32_t input_ctrl; |
825 | int retry; | | 921 | int retry; |
826 | u_int i; | | 922 | u_int i; |
827 | | | 923 | |
828 | tegra_car_hdmi_enable(mode->crtc_clock * 1000); | | 924 | tegra_encoder_hdmi_set_clock(encoder, mode->crtc_clock * 1000); |
829 | | | 925 | |
830 | /* find the connector for this encoder */ | | 926 | /* find the connector for this encoder */ |
831 | list_for_each_entry(connector, &ddev->mode_config.connector_list, head) { | | 927 | list_for_each_entry(connector, &ddev->mode_config.connector_list, head) { |
832 | if (connector->encoder == encoder) { | | 928 | if (connector->encoder == encoder) { |
833 | tegra_connector = to_tegra_connector(connector); | | 929 | tegra_connector = to_tegra_connector(connector); |
834 | break; | | 930 | break; |
835 | } | | 931 | } |
836 | } | | 932 | } |
837 | | | 933 | |
838 | for (i = 0; i < __arraycount(tegra_hdmi_tmds_config); i++) { | | 934 | for (i = 0; i < __arraycount(tegra_hdmi_tmds_config); i++) { |
839 | if (tegra_hdmi_tmds_config[i].dot_clock >= mode->crtc_clock) { | | 935 | if (tegra_hdmi_tmds_config[i].dot_clock >= mode->crtc_clock) { |
840 | break; | | 936 | break; |
841 | } | | 937 | } |
--- src/sys/arch/arm/nvidia/tegra_i2c.c 2015/12/16 19:46:55 1.10
+++ src/sys/arch/arm/nvidia/tegra_i2c.c 2015/12/22 22:10:36 1.11
| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: tegra_i2c.c,v 1.10 2015/12/16 19:46:55 jmcneill Exp $ */ | | 1 | /* $NetBSD: tegra_i2c.c,v 1.11 2015/12/22 22:10:36 jmcneill Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> | | 4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -17,80 +17,60 @@ | | | @@ -17,80 +17,60 @@ |
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | | 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | | 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | | 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | | 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | | 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 24 | * 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 | | 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
26 | * SUCH DAMAGE. | | 26 | * SUCH DAMAGE. |
27 | */ | | 27 | */ |
28 | | | 28 | |
29 | #include <sys/cdefs.h> | | 29 | #include <sys/cdefs.h> |
30 | __KERNEL_RCSID(0, "$NetBSD: tegra_i2c.c,v 1.10 2015/12/16 19:46:55 jmcneill Exp $"); | | 30 | __KERNEL_RCSID(0, "$NetBSD: tegra_i2c.c,v 1.11 2015/12/22 22:10:36 jmcneill Exp $"); |
31 | | | 31 | |
32 | #include <sys/param.h> | | 32 | #include <sys/param.h> |
33 | #include <sys/bus.h> | | 33 | #include <sys/bus.h> |
34 | #include <sys/device.h> | | 34 | #include <sys/device.h> |
35 | #include <sys/intr.h> | | 35 | #include <sys/intr.h> |
36 | #include <sys/systm.h> | | 36 | #include <sys/systm.h> |
37 | #include <sys/kernel.h> | | 37 | #include <sys/kernel.h> |
38 | | | 38 | |
39 | #include <dev/i2c/i2cvar.h> | | 39 | #include <dev/i2c/i2cvar.h> |
40 | | | 40 | |
41 | #include <arm/nvidia/tegra_reg.h> | | 41 | #include <arm/nvidia/tegra_reg.h> |
42 | #include <arm/nvidia/tegra_i2creg.h> | | 42 | #include <arm/nvidia/tegra_i2creg.h> |
43 | #include <arm/nvidia/tegra_var.h> | | 43 | #include <arm/nvidia/tegra_var.h> |
44 | | | 44 | |
45 | #include <dev/fdt/fdtvar.h> | | 45 | #include <dev/fdt/fdtvar.h> |
46 | | | 46 | |
47 | /* XXX */ | | | |
48 | static int | | | |
49 | tegra_i2c_addr2port(bus_addr_t addr) | | | |
50 | { | | | |
51 | switch (addr) { | | | |
52 | case TEGRA_APB_BASE + TEGRA_I2C1_OFFSET: | | | |
53 | return 0; | | | |
54 | case TEGRA_APB_BASE + TEGRA_I2C2_OFFSET: | | | |
55 | return 1; | | | |
56 | case TEGRA_APB_BASE + TEGRA_I2C3_OFFSET: | | | |
57 | return 2; | | | |
58 | case TEGRA_APB_BASE + TEGRA_I2C4_OFFSET: | | | |
59 | return 3; | | | |
60 | case TEGRA_APB_BASE + TEGRA_I2C5_OFFSET: | | | |
61 | return 4; | | | |
62 | case TEGRA_APB_BASE + TEGRA_I2C6_OFFSET: | | | |
63 | return 5; | | | |
64 | default: | | | |
65 | return -1; | | | |
66 | } | | | |
67 | } | | | |
68 | | | | |
69 | static int tegra_i2c_match(device_t, cfdata_t, void *); | | 47 | static int tegra_i2c_match(device_t, cfdata_t, void *); |
70 | static void tegra_i2c_attach(device_t, device_t, void *); | | 48 | static void tegra_i2c_attach(device_t, device_t, void *); |
71 | | | 49 | |
72 | static i2c_tag_t tegra_i2c_get_tag(device_t); | | 50 | static i2c_tag_t tegra_i2c_get_tag(device_t); |
73 | | | 51 | |
74 | struct fdtbus_i2c_controller_func tegra_i2c_funcs = { | | 52 | struct fdtbus_i2c_controller_func tegra_i2c_funcs = { |
75 | .get_tag = tegra_i2c_get_tag | | 53 | .get_tag = tegra_i2c_get_tag |
76 | }; | | 54 | }; |
77 | | | 55 | |
78 | struct tegra_i2c_softc { | | 56 | struct tegra_i2c_softc { |
79 | device_t sc_dev; | | 57 | device_t sc_dev; |
80 | bus_space_tag_t sc_bst; | | 58 | bus_space_tag_t sc_bst; |
81 | bus_space_handle_t sc_bsh; | | 59 | bus_space_handle_t sc_bsh; |
82 | void * sc_ih; | | 60 | void * sc_ih; |
83 | u_int sc_port; | | 61 | struct clk * sc_clk; |
| | | 62 | struct fdtbus_reset * sc_rst; |
| | | 63 | u_int sc_cid; |
84 | | | 64 | |
85 | struct i2c_controller sc_ic; | | 65 | struct i2c_controller sc_ic; |
86 | kmutex_t sc_lock; | | 66 | kmutex_t sc_lock; |
87 | kcondvar_t sc_cv; | | 67 | kcondvar_t sc_cv; |
88 | device_t sc_i2cdev; | | 68 | device_t sc_i2cdev; |
89 | }; | | 69 | }; |
90 | | | 70 | |
91 | static void tegra_i2c_init(struct tegra_i2c_softc *); | | 71 | static void tegra_i2c_init(struct tegra_i2c_softc *); |
92 | static int tegra_i2c_intr(void *); | | 72 | static int tegra_i2c_intr(void *); |
93 | | | 73 | |
94 | static int tegra_i2c_acquire_bus(void *, int); | | 74 | static int tegra_i2c_acquire_bus(void *, int); |
95 | static void tegra_i2c_release_bus(void *, int); | | 75 | static void tegra_i2c_release_bus(void *, int); |
96 | static int tegra_i2c_exec(void *, i2c_op_t, i2c_addr_t, const void *, | | 76 | static int tegra_i2c_exec(void *, i2c_op_t, i2c_addr_t, const void *, |
| @@ -129,60 +109,81 @@ tegra_i2c_attach(device_t parent, device | | | @@ -129,60 +109,81 @@ tegra_i2c_attach(device_t parent, device |
129 | const int phandle = faa->faa_phandle; | | 109 | const int phandle = faa->faa_phandle; |
130 | struct i2cbus_attach_args iba; | | 110 | struct i2cbus_attach_args iba; |
131 | prop_dictionary_t devs; | | 111 | prop_dictionary_t devs; |
132 | char intrstr[128]; | | 112 | char intrstr[128]; |
133 | bus_addr_t addr; | | 113 | bus_addr_t addr; |
134 | bus_size_t size; | | 114 | bus_size_t size; |
135 | u_int address_cells; | | 115 | u_int address_cells; |
136 | int error; | | 116 | int error; |
137 | | | 117 | |
138 | if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { | | 118 | if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { |
139 | aprint_error(": couldn't get registers\n"); | | 119 | aprint_error(": couldn't get registers\n"); |
140 | return; | | 120 | return; |
141 | } | | 121 | } |
| | | 122 | sc->sc_clk = fdtbus_clock_get(phandle, "div-clk"); |
| | | 123 | if (sc->sc_clk == NULL) { |
| | | 124 | aprint_error(": couldn't get clock div-clk\n"); |
| | | 125 | return; |
| | | 126 | } |
| | | 127 | sc->sc_rst = fdtbus_reset_get(phandle, "i2c"); |
| | | 128 | if (sc->sc_rst == NULL) { |
| | | 129 | aprint_error(": couldn't get reset i2c\n"); |
| | | 130 | return; |
| | | 131 | } |
142 | | | 132 | |
143 | sc->sc_dev = self; | | 133 | sc->sc_dev = self; |
144 | sc->sc_bst = faa->faa_bst; | | 134 | sc->sc_bst = faa->faa_bst; |
| | | 135 | sc->sc_cid = device_unit(self); |
145 | error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh); | | 136 | error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh); |
146 | if (error) { | | 137 | if (error) { |
147 | aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error); | | 138 | aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error); |
148 | return; | | 139 | return; |
149 | } | | 140 | } |
150 | sc->sc_port = tegra_i2c_addr2port(addr); | | | |
151 | mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM); | | 141 | mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM); |
152 | cv_init(&sc->sc_cv, device_xname(self)); | | 142 | cv_init(&sc->sc_cv, device_xname(self)); |
153 | | | 143 | |
154 | aprint_naive("\n"); | | 144 | aprint_naive("\n"); |
155 | aprint_normal(": I2C%d\n", sc->sc_port + 1); | | 145 | aprint_normal(": I2C\n"); |
156 | | | 146 | |
157 | if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { | | 147 | if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { |
158 | aprint_error_dev(self, "failed to decode interrupt\n"); | | 148 | aprint_error_dev(self, "failed to decode interrupt\n"); |
159 | return; | | 149 | return; |
160 | } | | 150 | } |
161 | | | 151 | |
162 | sc->sc_ih = fdtbus_intr_establish(phandle, 0, IPL_VM, | | 152 | sc->sc_ih = fdtbus_intr_establish(phandle, 0, IPL_VM, |
163 | FDT_INTR_MPSAFE, tegra_i2c_intr, sc); | | 153 | FDT_INTR_MPSAFE, tegra_i2c_intr, sc); |
164 | if (sc->sc_ih == NULL) { | | 154 | if (sc->sc_ih == NULL) { |
165 | aprint_error_dev(self, "couldn't establish interrupt on %s\n", | | 155 | aprint_error_dev(self, "couldn't establish interrupt on %s\n", |
166 | intrstr); | | 156 | intrstr); |
167 | return; | | 157 | return; |
168 | } | | 158 | } |
169 | aprint_normal_dev(self, "interrupting on %s\n", intrstr); | | 159 | aprint_normal_dev(self, "interrupting on %s\n", intrstr); |
170 | | | 160 | |
171 | /* | | 161 | /* |
172 | * Recommended setting for standard mode is to use an I2C source div | | 162 | * Recommended setting for standard mode is to use an I2C source div |
173 | * of 20 (Tegra K1 Technical Reference Manual, Table 137) | | 163 | * of 20 (Tegra K1 Technical Reference Manual, Table 137) |
174 | */ | | 164 | */ |
175 | tegra_car_periph_i2c_enable(sc->sc_port, 20400000); | | 165 | fdtbus_reset_assert(sc->sc_rst); |
| | | 166 | error = clk_set_rate(sc->sc_clk, 20400000); |
| | | 167 | if (error) { |
| | | 168 | aprint_error_dev(self, "couldn't set frequency: %d\n", error); |
| | | 169 | return; |
| | | 170 | } |
| | | 171 | error = clk_enable(sc->sc_clk); |
| | | 172 | if (error) { |
| | | 173 | aprint_error_dev(self, "couldn't enable clock: %d\n", error); |
| | | 174 | return; |
| | | 175 | } |
| | | 176 | fdtbus_reset_deassert(sc->sc_rst); |
176 | | | 177 | |
177 | tegra_i2c_init(sc); | | 178 | tegra_i2c_init(sc); |
178 | | | 179 | |
179 | sc->sc_ic.ic_cookie = sc; | | 180 | sc->sc_ic.ic_cookie = sc; |
180 | sc->sc_ic.ic_acquire_bus = tegra_i2c_acquire_bus; | | 181 | sc->sc_ic.ic_acquire_bus = tegra_i2c_acquire_bus; |
181 | sc->sc_ic.ic_release_bus = tegra_i2c_release_bus; | | 182 | sc->sc_ic.ic_release_bus = tegra_i2c_release_bus; |
182 | sc->sc_ic.ic_exec = tegra_i2c_exec; | | 183 | sc->sc_ic.ic_exec = tegra_i2c_exec; |
183 | | | 184 | |
184 | fdtbus_register_i2c_controller(self, phandle, &tegra_i2c_funcs); | | 185 | fdtbus_register_i2c_controller(self, phandle, &tegra_i2c_funcs); |
185 | | | 186 | |
186 | devs = prop_dictionary_create(); | | 187 | devs = prop_dictionary_create(); |
187 | | | 188 | |
188 | if (of_getprop_uint32(phandle, "#address-cells", &address_cells)) | | 189 | if (of_getprop_uint32(phandle, "#address-cells", &address_cells)) |
| @@ -385,27 +386,27 @@ tegra_i2c_write(struct tegra_i2c_softc * | | | @@ -385,27 +386,27 @@ tegra_i2c_write(struct tegra_i2c_softc * |
385 | { | | 386 | { |
386 | const uint8_t *p = buf; | | 387 | const uint8_t *p = buf; |
387 | size_t n, resid = buflen; | | 388 | size_t n, resid = buflen; |
388 | uint32_t data; | | 389 | uint32_t data; |
389 | int retry; | | 390 | int retry; |
390 | | | 391 | |
391 | const uint32_t istatus = I2C_READ(sc, I2C_INTERRUPT_STATUS_REG); | | 392 | const uint32_t istatus = I2C_READ(sc, I2C_INTERRUPT_STATUS_REG); |
392 | I2C_WRITE(sc, I2C_INTERRUPT_STATUS_REG, istatus); | | 393 | I2C_WRITE(sc, I2C_INTERRUPT_STATUS_REG, istatus); |
393 | | | 394 | |
394 | /* Generic Header 0 */ | | 395 | /* Generic Header 0 */ |
395 | I2C_WRITE(sc, I2C_TX_PACKET_FIFO_REG, | | 396 | I2C_WRITE(sc, I2C_TX_PACKET_FIFO_REG, |
396 | __SHIFTIN(I2C_IOPACKET_WORD0_PROTHDRSZ_REQ, | | 397 | __SHIFTIN(I2C_IOPACKET_WORD0_PROTHDRSZ_REQ, |
397 | I2C_IOPACKET_WORD0_PROTHDRSZ) | | | 398 | I2C_IOPACKET_WORD0_PROTHDRSZ) | |
398 | __SHIFTIN(sc->sc_port, I2C_IOPACKET_WORD0_CONTROLLERID) | | | 399 | __SHIFTIN(sc->sc_cid, I2C_IOPACKET_WORD0_CONTROLLERID) | |
399 | __SHIFTIN(1, I2C_IOPACKET_WORD0_PKTID) | | | 400 | __SHIFTIN(1, I2C_IOPACKET_WORD0_PKTID) | |
400 | __SHIFTIN(I2C_IOPACKET_WORD0_PROTOCOL_I2C, | | 401 | __SHIFTIN(I2C_IOPACKET_WORD0_PROTOCOL_I2C, |
401 | I2C_IOPACKET_WORD0_PROTOCOL) | | | 402 | I2C_IOPACKET_WORD0_PROTOCOL) | |
402 | __SHIFTIN(I2C_IOPACKET_WORD0_PKTTYPE_REQ, | | 403 | __SHIFTIN(I2C_IOPACKET_WORD0_PKTTYPE_REQ, |
403 | I2C_IOPACKET_WORD0_PKTTYPE)); | | 404 | I2C_IOPACKET_WORD0_PKTTYPE)); |
404 | /* Generic Header 1 */ | | 405 | /* Generic Header 1 */ |
405 | I2C_WRITE(sc, I2C_TX_PACKET_FIFO_REG, | | 406 | I2C_WRITE(sc, I2C_TX_PACKET_FIFO_REG, |
406 | __SHIFTIN(buflen - 1, I2C_IOPACKET_WORD1_PAYLOADSIZE)); | | 407 | __SHIFTIN(buflen - 1, I2C_IOPACKET_WORD1_PAYLOADSIZE)); |
407 | /* I2C Master Transmit Packet Header */ | | 408 | /* I2C Master Transmit Packet Header */ |
408 | I2C_WRITE(sc, I2C_TX_PACKET_FIFO_REG, | | 409 | I2C_WRITE(sc, I2C_TX_PACKET_FIFO_REG, |
409 | I2C_IOPACKET_XMITHDR_IE | | | 410 | I2C_IOPACKET_XMITHDR_IE | |
410 | (repeat_start ? I2C_IOPACKET_XMITHDR_REPEAT_STARTSTOP : 0) | | | 411 | (repeat_start ? I2C_IOPACKET_XMITHDR_REPEAT_STARTSTOP : 0) | |
411 | __SHIFTIN((addr << 1), I2C_IOPACKET_XMITHDR_SLAVE_ADDR)); | | 412 | __SHIFTIN((addr << 1), I2C_IOPACKET_XMITHDR_SLAVE_ADDR)); |
| @@ -443,27 +444,27 @@ tegra_i2c_read(struct tegra_i2c_softc *s | | | @@ -443,27 +444,27 @@ tegra_i2c_read(struct tegra_i2c_softc *s |
443 | { | | 444 | { |
444 | uint8_t *p = buf; | | 445 | uint8_t *p = buf; |
445 | size_t n, resid = buflen; | | 446 | size_t n, resid = buflen; |
446 | uint32_t data; | | 447 | uint32_t data; |
447 | int retry; | | 448 | int retry; |
448 | | | 449 | |
449 | const uint32_t istatus = I2C_READ(sc, I2C_INTERRUPT_STATUS_REG); | | 450 | const uint32_t istatus = I2C_READ(sc, I2C_INTERRUPT_STATUS_REG); |
450 | I2C_WRITE(sc, I2C_INTERRUPT_STATUS_REG, istatus); | | 451 | I2C_WRITE(sc, I2C_INTERRUPT_STATUS_REG, istatus); |
451 | | | 452 | |
452 | /* Generic Header 0 */ | | 453 | /* Generic Header 0 */ |
453 | I2C_WRITE(sc, I2C_TX_PACKET_FIFO_REG, | | 454 | I2C_WRITE(sc, I2C_TX_PACKET_FIFO_REG, |
454 | __SHIFTIN(I2C_IOPACKET_WORD0_PROTHDRSZ_REQ, | | 455 | __SHIFTIN(I2C_IOPACKET_WORD0_PROTHDRSZ_REQ, |
455 | I2C_IOPACKET_WORD0_PROTHDRSZ) | | | 456 | I2C_IOPACKET_WORD0_PROTHDRSZ) | |
456 | __SHIFTIN(sc->sc_port, I2C_IOPACKET_WORD0_CONTROLLERID) | | | 457 | __SHIFTIN(sc->sc_cid, I2C_IOPACKET_WORD0_CONTROLLERID) | |
457 | __SHIFTIN(1, I2C_IOPACKET_WORD0_PKTID) | | | 458 | __SHIFTIN(1, I2C_IOPACKET_WORD0_PKTID) | |
458 | __SHIFTIN(I2C_IOPACKET_WORD0_PROTOCOL_I2C, | | 459 | __SHIFTIN(I2C_IOPACKET_WORD0_PROTOCOL_I2C, |
459 | I2C_IOPACKET_WORD0_PROTOCOL) | | | 460 | I2C_IOPACKET_WORD0_PROTOCOL) | |
460 | __SHIFTIN(I2C_IOPACKET_WORD0_PKTTYPE_REQ, | | 461 | __SHIFTIN(I2C_IOPACKET_WORD0_PKTTYPE_REQ, |
461 | I2C_IOPACKET_WORD0_PKTTYPE)); | | 462 | I2C_IOPACKET_WORD0_PKTTYPE)); |
462 | /* Generic Header 1 */ | | 463 | /* Generic Header 1 */ |
463 | I2C_WRITE(sc, I2C_TX_PACKET_FIFO_REG, | | 464 | I2C_WRITE(sc, I2C_TX_PACKET_FIFO_REG, |
464 | __SHIFTIN(buflen - 1, I2C_IOPACKET_WORD1_PAYLOADSIZE)); | | 465 | __SHIFTIN(buflen - 1, I2C_IOPACKET_WORD1_PAYLOADSIZE)); |
465 | /* I2C Master Transmit Packet Header */ | | 466 | /* I2C Master Transmit Packet Header */ |
466 | I2C_WRITE(sc, I2C_TX_PACKET_FIFO_REG, | | 467 | I2C_WRITE(sc, I2C_TX_PACKET_FIFO_REG, |
467 | I2C_IOPACKET_XMITHDR_IE | I2C_IOPACKET_XMITHDR_READ | | | 468 | I2C_IOPACKET_XMITHDR_IE | I2C_IOPACKET_XMITHDR_READ | |
468 | __SHIFTIN((addr << 1) | 1, I2C_IOPACKET_XMITHDR_SLAVE_ADDR)); | | 469 | __SHIFTIN((addr << 1) | 1, I2C_IOPACKET_XMITHDR_SLAVE_ADDR)); |
469 | | | 470 | |
--- src/sys/arch/arm/nvidia/Attic/tegra_fdt.c 2015/12/13 17:39:19 1.1
+++ src/sys/arch/arm/nvidia/Attic/tegra_fdt.c 2015/12/22 22:10:36 1.2
| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: tegra_fdt.c,v 1.1 2015/12/13 17:39:19 jmcneill Exp $ */ | | 1 | /* $NetBSD: tegra_fdt.c,v 1.2 2015/12/22 22:10:36 jmcneill Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> | | 4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -19,27 +19,27 @@ | | | @@ -19,27 +19,27 @@ |
19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | | 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | | 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | | 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | | 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 24 | * 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 | | 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
26 | * SUCH DAMAGE. | | 26 | * SUCH DAMAGE. |
27 | */ | | 27 | */ |
28 | | | 28 | |
29 | #include "opt_tegra.h" | | 29 | #include "opt_tegra.h" |
30 | | | 30 | |
31 | #include <sys/cdefs.h> | | 31 | #include <sys/cdefs.h> |
32 | __KERNEL_RCSID(0, "$NetBSD: tegra_fdt.c,v 1.1 2015/12/13 17:39:19 jmcneill Exp $"); | | 32 | __KERNEL_RCSID(0, "$NetBSD: tegra_fdt.c,v 1.2 2015/12/22 22:10:36 jmcneill Exp $"); |
33 | | | 33 | |
34 | #include <sys/param.h> | | 34 | #include <sys/param.h> |
35 | #include <sys/systm.h> | | 35 | #include <sys/systm.h> |
36 | #include <sys/device.h> | | 36 | #include <sys/device.h> |
37 | | | 37 | |
38 | #include <machine/cpu.h> | | 38 | #include <machine/cpu.h> |
39 | #include <sys/bus.h> | | 39 | #include <sys/bus.h> |
40 | | | 40 | |
41 | #include <arm/mainbus/mainbus.h> | | 41 | #include <arm/mainbus/mainbus.h> |
42 | #include <arm/nvidia/tegra_reg.h> | | 42 | #include <arm/nvidia/tegra_reg.h> |
43 | #include <arm/nvidia/tegra_var.h> | | 43 | #include <arm/nvidia/tegra_var.h> |
44 | | | 44 | |
45 | #include <dev/fdt/fdtvar.h> | | 45 | #include <dev/fdt/fdtvar.h> |
| @@ -60,36 +60,39 @@ tegrafdt_match(device_t parent, cfdata_t | | | @@ -60,36 +60,39 @@ tegrafdt_match(device_t parent, cfdata_t |
60 | return 0; | | 60 | return 0; |
61 | return 1; | | 61 | return 1; |
62 | } | | 62 | } |
63 | | | 63 | |
64 | void | | 64 | void |
65 | tegrafdt_attach(device_t parent, device_t self, void *aux) | | 65 | tegrafdt_attach(device_t parent, device_t self, void *aux) |
66 | { | | 66 | { |
67 | const char *tegrafdt_init[] = { | | 67 | const char *tegrafdt_init[] = { |
68 | "interrupt-controller", | | 68 | "interrupt-controller", |
69 | "clock", | | 69 | "clock", |
70 | "pinmux", | | 70 | "pinmux", |
71 | "gpio", | | 71 | "gpio", |
72 | "regulators", | | 72 | "regulators", |
| | | 73 | "fuse", |
73 | "dma", | | 74 | "dma", |
74 | "pmc", | | 75 | "pmc", |
75 | "memory-controller", | | 76 | "memory-controller", |
76 | "i2c", | | 77 | "i2c", |
77 | "usb-phy" | | 78 | "usb-phy" |
78 | }; | | 79 | }; |
79 | | | 80 | |
80 | tegrafdt_found = true; | | 81 | tegrafdt_found = true; |
81 | | | 82 | |
82 | aprint_naive("\n"); | | 83 | aprint_naive("\n"); |
83 | aprint_normal("\n"); | | 84 | aprint_normal("\n"); |
84 | | | 85 | |
85 | struct fdt_attach_args faa = { | | 86 | struct fdt_attach_args faa = { |
86 | .faa_name = "", | | 87 | .faa_name = "", |
87 | .faa_bst = &armv7_generic_bs_tag, | | 88 | .faa_bst = &armv7_generic_bs_tag, |
88 | .faa_a4x_bst = &armv7_generic_a4x_bs_tag, | | 89 | .faa_a4x_bst = &armv7_generic_a4x_bs_tag, |
89 | .faa_dmat = &tegra_dma_tag, | | 90 | .faa_dmat = &tegra_dma_tag, |
90 | .faa_phandle = OF_peer(0), | | 91 | .faa_phandle = OF_peer(0), |
91 | .faa_init = tegrafdt_init, | | 92 | .faa_init = tegrafdt_init, |
92 | .faa_ninit = __arraycount(tegrafdt_init) | | 93 | .faa_ninit = __arraycount(tegrafdt_init) |
93 | }; | | 94 | }; |
94 | config_found(self, &faa, NULL); | | 95 | config_found(self, &faa, NULL); |
| | | 96 | |
| | | 97 | tegra_cpuinit(); |
95 | } | | 98 | } |
--- src/sys/arch/arm/nvidia/tegra_timerreg.h 2015/05/30 13:25:55 1.1
+++ src/sys/arch/arm/nvidia/tegra_timerreg.h 2015/12/22 22:10:36 1.2
| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: tegra_timerreg.h,v 1.1 2015/05/30 13:25:55 jmcneill Exp $ */ | | 1 | /* $NetBSD: tegra_timerreg.h,v 1.2 2015/12/22 22:10:36 jmcneill Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> | | 4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -23,26 +23,29 @@ | | | @@ -23,26 +23,29 @@ |
23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | | 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 24 | * 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 | | 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
26 | * SUCH DAMAGE. | | 26 | * SUCH DAMAGE. |
27 | */ | | 27 | */ |
28 | | | 28 | |
29 | #ifndef _ARM_TEGRA_TIMERREG_H | | 29 | #ifndef _ARM_TEGRA_TIMERREG_H |
30 | #define _ARM_TEGRA_TIMERREG_H | | 30 | #define _ARM_TEGRA_TIMERREG_H |
31 | | | 31 | |
32 | #define TMR1_PTV_REG 0x00 | | 32 | #define TMR1_PTV_REG 0x00 |
33 | #define TMR1_PCR_REG 0x04 | | 33 | #define TMR1_PCR_REG 0x04 |
34 | #define TMR2_PTV_REG 0x08 | | 34 | #define TMR2_PTV_REG 0x08 |
35 | #define TMR2_PCR_REG 0x0c | | 35 | #define TMR2_PCR_REG 0x0c |
| | | 36 | #define TMRUS_CNTR_1US_REG 0x10 |
| | | 37 | #define TMRUS_USEC_CFG_REG 0x14 |
| | | 38 | #define TMRUS_CNTR_FREEZE_REG 0x18 |
36 | #define TMR3_PTV_REG 0x50 | | 39 | #define TMR3_PTV_REG 0x50 |
37 | #define TMR3_PCR_REG 0x54 | | 40 | #define TMR3_PCR_REG 0x54 |
38 | #define TMR4_PTV_REG 0x58 | | 41 | #define TMR4_PTV_REG 0x58 |
39 | #define TMR4_PCR_REG 0x5c | | 42 | #define TMR4_PCR_REG 0x5c |
40 | #define TMR5_PTV_REG 0x60 | | 43 | #define TMR5_PTV_REG 0x60 |
41 | #define TMR5_PCR_REG 0x64 | | 44 | #define TMR5_PCR_REG 0x64 |
42 | #define TMR6_PTV_REG 0x68 | | 45 | #define TMR6_PTV_REG 0x68 |
43 | #define TMR6_PCR_REG 0x6c | | 46 | #define TMR6_PCR_REG 0x6c |
44 | #define TMR7_PTV_REG 0x70 | | 47 | #define TMR7_PTV_REG 0x70 |
45 | #define TMR7_PCR_REG 0x74 | | 48 | #define TMR7_PCR_REG 0x74 |
46 | #define TMR8_PTV_REG 0x78 | | 49 | #define TMR8_PTV_REG 0x78 |
47 | #define TMR8_PCR_REG 0x7c | | 50 | #define TMR8_PCR_REG 0x7c |
48 | #define TMR9_PTV_REG 0x80 | | 51 | #define TMR9_PTV_REG 0x80 |
--- src/sys/arch/arm/nvidia/tegra_fuse.c 2015/12/13 17:39:19 1.3
+++ src/sys/arch/arm/nvidia/tegra_fuse.c 2015/12/22 22:10:36 1.4
| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: tegra_fuse.c,v 1.3 2015/12/13 17:39:19 jmcneill Exp $ */ | | 1 | /* $NetBSD: tegra_fuse.c,v 1.4 2015/12/22 22:10:36 jmcneill Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> | | 4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -16,50 +16,51 @@ | | | @@ -16,50 +16,51 @@ |
16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | | 16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | | 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | | 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | | 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | | 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | | 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 24 | * 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 | | 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
26 | * SUCH DAMAGE. | | 26 | * SUCH DAMAGE. |
27 | */ | | 27 | */ |
28 | | | 28 | |
29 | #include "locators.h" | | | |
30 | | | | |
31 | #include <sys/cdefs.h> | | 29 | #include <sys/cdefs.h> |
32 | __KERNEL_RCSID(0, "$NetBSD: tegra_fuse.c,v 1.3 2015/12/13 17:39:19 jmcneill Exp $"); | | 30 | __KERNEL_RCSID(0, "$NetBSD: tegra_fuse.c,v 1.4 2015/12/22 22:10:36 jmcneill Exp $"); |
33 | | | 31 | |
34 | #include <sys/param.h> | | 32 | #include <sys/param.h> |
35 | #include <sys/bus.h> | | 33 | #include <sys/bus.h> |
36 | #include <sys/device.h> | | 34 | #include <sys/device.h> |
37 | #include <sys/intr.h> | | 35 | #include <sys/intr.h> |
38 | #include <sys/systm.h> | | 36 | #include <sys/systm.h> |
39 | #include <sys/kernel.h> | | 37 | #include <sys/kernel.h> |
40 | | | 38 | |
41 | #include <arm/nvidia/tegra_reg.h> | | 39 | #include <arm/nvidia/tegra_reg.h> |
42 | #include <arm/nvidia/tegra_var.h> | | 40 | #include <arm/nvidia/tegra_var.h> |
43 | | | 41 | |
44 | #include <dev/fdt/fdtvar.h> | | 42 | #include <dev/fdt/fdtvar.h> |
45 | | | 43 | |
46 | static int tegra_fuse_match(device_t, cfdata_t, void *); | | 44 | static int tegra_fuse_match(device_t, cfdata_t, void *); |
47 | static void tegra_fuse_attach(device_t, device_t, void *); | | 45 | static void tegra_fuse_attach(device_t, device_t, void *); |
48 | | | 46 | |
49 | struct tegra_fuse_softc { | | 47 | struct tegra_fuse_softc { |
50 | device_t sc_dev; | | 48 | device_t sc_dev; |
51 | bus_space_tag_t sc_bst; | | 49 | bus_space_tag_t sc_bst; |
52 | bus_space_handle_t sc_bsh; | | 50 | bus_space_handle_t sc_bsh; |
| | | 51 | |
| | | 52 | struct clk *sc_clk; |
| | | 53 | struct fdtbus_reset *sc_rst; |
53 | }; | | 54 | }; |
54 | | | 55 | |
55 | static struct tegra_fuse_softc *fuse_softc = NULL; | | 56 | static struct tegra_fuse_softc *fuse_softc = NULL; |
56 | | | 57 | |
57 | CFATTACH_DECL_NEW(tegra_fuse, sizeof(struct tegra_fuse_softc), | | 58 | CFATTACH_DECL_NEW(tegra_fuse, sizeof(struct tegra_fuse_softc), |
58 | tegra_fuse_match, tegra_fuse_attach, NULL, NULL); | | 59 | tegra_fuse_match, tegra_fuse_attach, NULL, NULL); |
59 | | | 60 | |
60 | static int | | 61 | static int |
61 | tegra_fuse_match(device_t parent, cfdata_t cf, void *aux) | | 62 | tegra_fuse_match(device_t parent, cfdata_t cf, void *aux) |
62 | { | | 63 | { |
63 | const char * const compatible[] = { "nvidia,tegra124-efuse", NULL }; | | 64 | const char * const compatible[] = { "nvidia,tegra124-efuse", NULL }; |
64 | struct fdt_attach_args * const faa = aux; | | 65 | struct fdt_attach_args * const faa = aux; |
65 | | | 66 | |
| @@ -69,50 +70,56 @@ tegra_fuse_match(device_t parent, cfdata | | | @@ -69,50 +70,56 @@ tegra_fuse_match(device_t parent, cfdata |
69 | static void | | 70 | static void |
70 | tegra_fuse_attach(device_t parent, device_t self, void *aux) | | 71 | tegra_fuse_attach(device_t parent, device_t self, void *aux) |
71 | { | | 72 | { |
72 | struct tegra_fuse_softc * const sc = device_private(self); | | 73 | struct tegra_fuse_softc * const sc = device_private(self); |
73 | struct fdt_attach_args * const faa = aux; | | 74 | struct fdt_attach_args * const faa = aux; |
74 | bus_addr_t addr; | | 75 | bus_addr_t addr; |
75 | bus_size_t size; | | 76 | bus_size_t size; |
76 | int error; | | 77 | int error; |
77 | | | 78 | |
78 | if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) { | | 79 | if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) { |
79 | aprint_error(": couldn't get registers\n"); | | 80 | aprint_error(": couldn't get registers\n"); |
80 | return; | | 81 | return; |
81 | } | | 82 | } |
| | | 83 | sc->sc_clk = fdtbus_clock_get(faa->faa_phandle, "fuse"); |
| | | 84 | if (sc->sc_clk == NULL) { |
| | | 85 | aprint_error(": couldn't get clock fuse\n"); |
| | | 86 | return; |
| | | 87 | } |
| | | 88 | sc->sc_rst = fdtbus_reset_get(faa->faa_phandle, "fuse"); |
| | | 89 | if (sc->sc_rst == NULL) { |
| | | 90 | aprint_error(": couldn't get reset fuse\n"); |
| | | 91 | return; |
| | | 92 | } |
82 | | | 93 | |
83 | sc->sc_dev = self; | | 94 | sc->sc_dev = self; |
84 | sc->sc_bst = faa->faa_bst; | | 95 | sc->sc_bst = faa->faa_bst; |
85 | error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh); | | 96 | error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh); |
86 | if (error) { | | 97 | if (error) { |
87 | aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error); | | 98 | aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error); |
88 | return; | | 99 | return; |
89 | } | | 100 | } |
90 | | | 101 | |
91 | KASSERT(fuse_softc == NULL); | | 102 | KASSERT(fuse_softc == NULL); |
92 | fuse_softc = sc; | | 103 | fuse_softc = sc; |
93 | | | 104 | |
94 | aprint_naive("\n"); | | 105 | aprint_naive("\n"); |
95 | aprint_normal(": FUSE\n"); | | 106 | aprint_normal(": FUSE\n"); |
96 | } | | 107 | } |
97 | | | 108 | |
98 | uint32_t | | 109 | uint32_t |
99 | tegra_fuse_read(u_int offset) | | 110 | tegra_fuse_read(u_int offset) |
100 | { | | 111 | { |
101 | bus_space_tag_t bst; | | 112 | bus_space_tag_t bst; |
102 | bus_space_handle_t bsh; | | 113 | bus_space_handle_t bsh; |
103 | | | 114 | |
104 | if (fuse_softc) { | | 115 | KASSERT(fuse_softc != NULL); |
105 | bst = fuse_softc->sc_bst; | | 116 | |
106 | bsh = fuse_softc->sc_bsh; | | 117 | bst = fuse_softc->sc_bst; |
107 | } else { | | 118 | bsh = fuse_softc->sc_bsh; |
108 | bst = &armv7_generic_bs_tag; | | | |
109 | bus_space_subregion(bst, tegra_apb_bsh, | | | |
110 | TEGRA_FUSE_OFFSET, TEGRA_FUSE_SIZE, &bsh); | | | |
111 | } | | | |
112 | | | 119 | |
113 | tegra_car_fuse_enable(); | | 120 | clk_enable(fuse_softc->sc_clk); |
114 | const uint32_t v = bus_space_read_4(bst, bsh, 0x100 + offset); | | 121 | const uint32_t v = bus_space_read_4(bst, bsh, 0x100 + offset); |
115 | tegra_car_fuse_disable(); | | 122 | clk_disable(fuse_softc->sc_clk); |
116 | | | 123 | |
117 | return v; | | 124 | return v; |
118 | } | | 125 | } |
--- src/sys/arch/arm/nvidia/tegra_sdhc.c 2015/12/16 19:46:55 1.14
+++ src/sys/arch/arm/nvidia/tegra_sdhc.c 2015/12/22 22:10:36 1.15
| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: tegra_sdhc.c,v 1.14 2015/12/16 19:46:55 jmcneill Exp $ */ | | 1 | /* $NetBSD: tegra_sdhc.c,v 1.15 2015/12/22 22:10:36 jmcneill Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> | | 4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -19,72 +19,55 @@ | | | @@ -19,72 +19,55 @@ |
19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | | 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | | 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | | 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | | 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 24 | * 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 | | 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
26 | * SUCH DAMAGE. | | 26 | * SUCH DAMAGE. |
27 | */ | | 27 | */ |
28 | | | 28 | |
29 | #include "locators.h" | | 29 | #include "locators.h" |
30 | | | 30 | |
31 | #include <sys/cdefs.h> | | 31 | #include <sys/cdefs.h> |
32 | __KERNEL_RCSID(0, "$NetBSD: tegra_sdhc.c,v 1.14 2015/12/16 19:46:55 jmcneill Exp $"); | | 32 | __KERNEL_RCSID(0, "$NetBSD: tegra_sdhc.c,v 1.15 2015/12/22 22:10:36 jmcneill Exp $"); |
33 | | | 33 | |
34 | #include <sys/param.h> | | 34 | #include <sys/param.h> |
35 | #include <sys/bus.h> | | 35 | #include <sys/bus.h> |
36 | #include <sys/device.h> | | 36 | #include <sys/device.h> |
37 | #include <sys/intr.h> | | 37 | #include <sys/intr.h> |
38 | #include <sys/systm.h> | | 38 | #include <sys/systm.h> |
39 | #include <sys/kernel.h> | | 39 | #include <sys/kernel.h> |
40 | | | 40 | |
41 | #include <dev/sdmmc/sdhcreg.h> | | 41 | #include <dev/sdmmc/sdhcreg.h> |
42 | #include <dev/sdmmc/sdhcvar.h> | | 42 | #include <dev/sdmmc/sdhcvar.h> |
43 | #include <dev/sdmmc/sdmmcvar.h> | | 43 | #include <dev/sdmmc/sdmmcvar.h> |
44 | | | 44 | |
45 | #include <arm/nvidia/tegra_reg.h> | | 45 | #include <arm/nvidia/tegra_reg.h> |
46 | #include <arm/nvidia/tegra_var.h> | | 46 | #include <arm/nvidia/tegra_var.h> |
47 | | | 47 | |
48 | #include <dev/fdt/fdtvar.h> | | 48 | #include <dev/fdt/fdtvar.h> |
49 | | | 49 | |
50 | /* XXX */ | | | |
51 | static int | | | |
52 | tegra_sdhc_addr2port(bus_addr_t addr) | | | |
53 | { | | | |
54 | switch (addr) { | | | |
55 | case TEGRA_APB_BASE + TEGRA_SDMMC1_OFFSET: | | | |
56 | return 0; | | | |
57 | case TEGRA_APB_BASE + TEGRA_SDMMC2_OFFSET: | | | |
58 | return 1; | | | |
59 | case TEGRA_APB_BASE + TEGRA_SDMMC3_OFFSET: | | | |
60 | return 2; | | | |
61 | case TEGRA_APB_BASE + TEGRA_SDMMC4_OFFSET: | | | |
62 | return 3; | | | |
63 | default: | | | |
64 | return -1; | | | |
65 | } | | | |
66 | } | | | |
67 | | | | |
68 | static int tegra_sdhc_match(device_t, cfdata_t, void *); | | 50 | static int tegra_sdhc_match(device_t, cfdata_t, void *); |
69 | static void tegra_sdhc_attach(device_t, device_t, void *); | | 51 | static void tegra_sdhc_attach(device_t, device_t, void *); |
70 | | | 52 | |
71 | static int tegra_sdhc_card_detect(struct sdhc_softc *); | | 53 | static int tegra_sdhc_card_detect(struct sdhc_softc *); |
72 | static int tegra_sdhc_write_protect(struct sdhc_softc *); | | 54 | static int tegra_sdhc_write_protect(struct sdhc_softc *); |
73 | | | 55 | |
74 | struct tegra_sdhc_softc { | | 56 | struct tegra_sdhc_softc { |
75 | struct sdhc_softc sc; | | 57 | struct sdhc_softc sc; |
76 | | | 58 | |
77 | u_int sc_port; | | 59 | struct clk *sc_clk; |
| | | 60 | struct fdtbus_reset *sc_rst; |
78 | | | 61 | |
79 | bus_space_tag_t sc_bst; | | 62 | bus_space_tag_t sc_bst; |
80 | bus_space_handle_t sc_bsh; | | 63 | bus_space_handle_t sc_bsh; |
81 | bus_size_t sc_bsz; | | 64 | bus_size_t sc_bsz; |
82 | struct sdhc_host *sc_host; | | 65 | struct sdhc_host *sc_host; |
83 | void *sc_ih; | | 66 | void *sc_ih; |
84 | | | 67 | |
85 | struct fdtbus_gpio_pin *sc_pin_cd; | | 68 | struct fdtbus_gpio_pin *sc_pin_cd; |
86 | struct fdtbus_gpio_pin *sc_pin_power; | | 69 | struct fdtbus_gpio_pin *sc_pin_power; |
87 | struct fdtbus_gpio_pin *sc_pin_wp; | | 70 | struct fdtbus_gpio_pin *sc_pin_wp; |
88 | }; | | 71 | }; |
89 | | | 72 | |
90 | CFATTACH_DECL_NEW(tegra_sdhc, sizeof(struct tegra_sdhc_softc), | | 73 | CFATTACH_DECL_NEW(tegra_sdhc, sizeof(struct tegra_sdhc_softc), |
| @@ -129,51 +112,73 @@ tegra_sdhc_attach(device_t parent, devic | | | @@ -129,51 +112,73 @@ tegra_sdhc_attach(device_t parent, devic |
129 | SDHC_FLAG_USE_ADMA2; | | 112 | SDHC_FLAG_USE_ADMA2; |
130 | if (bus_width == 8) { | | 113 | if (bus_width == 8) { |
131 | sc->sc.sc_flags |= SDHC_FLAG_8BIT_MODE; | | 114 | sc->sc.sc_flags |= SDHC_FLAG_8BIT_MODE; |
132 | } | | 115 | } |
133 | sc->sc.sc_host = &sc->sc_host; | | 116 | sc->sc.sc_host = &sc->sc_host; |
134 | | | 117 | |
135 | sc->sc_bst = faa->faa_bst; | | 118 | sc->sc_bst = faa->faa_bst; |
136 | error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh); | | 119 | error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh); |
137 | if (error) { | | 120 | if (error) { |
138 | aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error); | | 121 | aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error); |
139 | return; | | 122 | return; |
140 | } | | 123 | } |
141 | sc->sc_bsz = size; | | 124 | sc->sc_bsz = size; |
142 | sc->sc_port = tegra_sdhc_addr2port(addr); | | | |
143 | | | 125 | |
144 | sc->sc_pin_power = fdtbus_gpio_acquire(faa->faa_phandle, | | 126 | sc->sc_pin_power = fdtbus_gpio_acquire(faa->faa_phandle, |
145 | "power-gpios", GPIO_PIN_OUTPUT); | | 127 | "power-gpios", GPIO_PIN_OUTPUT); |
146 | if (sc->sc_pin_power) | | 128 | if (sc->sc_pin_power) |
147 | fdtbus_gpio_write(sc->sc_pin_power, 1); | | 129 | fdtbus_gpio_write(sc->sc_pin_power, 1); |
148 | | | 130 | |
149 | sc->sc_pin_cd = fdtbus_gpio_acquire(faa->faa_phandle, | | 131 | sc->sc_pin_cd = fdtbus_gpio_acquire(faa->faa_phandle, |
150 | "cd-gpios", GPIO_PIN_INPUT); | | 132 | "cd-gpios", GPIO_PIN_INPUT); |
151 | sc->sc_pin_wp = fdtbus_gpio_acquire(faa->faa_phandle, | | 133 | sc->sc_pin_wp = fdtbus_gpio_acquire(faa->faa_phandle, |
152 | "wp-gpios", GPIO_PIN_INPUT); | | 134 | "wp-gpios", GPIO_PIN_INPUT); |
153 | | | 135 | |
154 | if (sc->sc_pin_cd) { | | 136 | if (sc->sc_pin_cd) { |
155 | sc->sc.sc_vendor_card_detect = tegra_sdhc_card_detect; | | 137 | sc->sc.sc_vendor_card_detect = tegra_sdhc_card_detect; |
156 | sc->sc.sc_flags |= SDHC_FLAG_POLL_CARD_DET; | | 138 | sc->sc.sc_flags |= SDHC_FLAG_POLL_CARD_DET; |
157 | } | | 139 | } |
158 | if (sc->sc_pin_wp) { | | 140 | if (sc->sc_pin_wp) { |
159 | sc->sc.sc_vendor_write_protect = tegra_sdhc_write_protect; | | 141 | sc->sc.sc_vendor_write_protect = tegra_sdhc_write_protect; |
160 | } | | 142 | } |
161 | | | 143 | |
162 | tegra_car_periph_sdmmc_set_rate(sc->sc_port, 204000000); | | 144 | sc->sc_clk = fdtbus_clock_get_index(faa->faa_phandle, 0); |
163 | sc->sc.sc_clkbase = tegra_car_periph_sdmmc_rate(sc->sc_port) / 1000; | | 145 | if (sc->sc_clk == NULL) { |
| | | 146 | aprint_error(": couldn't get clock\n"); |
| | | 147 | return; |
| | | 148 | } |
| | | 149 | sc->sc_rst = fdtbus_reset_get(faa->faa_phandle, "sdhci"); |
| | | 150 | if (sc->sc_rst == NULL) { |
| | | 151 | aprint_error(": couldn't get reset\n"); |
| | | 152 | return; |
| | | 153 | } |
| | | 154 | |
| | | 155 | fdtbus_reset_assert(sc->sc_rst); |
| | | 156 | error = clk_set_rate(sc->sc_clk, 204000000); |
| | | 157 | if (error) { |
| | | 158 | aprint_error(": couldn't set frequency: %d\n", error); |
| | | 159 | return; |
| | | 160 | } |
| | | 161 | error = clk_enable(sc->sc_clk); |
| | | 162 | if (error) { |
| | | 163 | aprint_error(": couldn't enable clock: %d\n", error); |
| | | 164 | return; |
| | | 165 | } |
| | | 166 | fdtbus_reset_deassert(sc->sc_rst); |
| | | 167 | |
| | | 168 | sc->sc.sc_clkbase = clk_get_rate(sc->sc_clk) / 1000; |
164 | | | 169 | |
165 | aprint_naive("\n"); | | 170 | aprint_naive("\n"); |
166 | aprint_normal(": SDMMC%d\n", sc->sc_port + 1); | | 171 | aprint_normal(": SDMMC\n"); |
167 | | | 172 | |
168 | if (sc->sc.sc_clkbase == 0) { | | 173 | if (sc->sc.sc_clkbase == 0) { |
169 | aprint_error_dev(self, "couldn't determine frequency\n"); | | 174 | aprint_error_dev(self, "couldn't determine frequency\n"); |
170 | return; | | 175 | return; |
171 | } | | 176 | } |
172 | | | 177 | |
173 | if (!fdtbus_intr_str(faa->faa_phandle, 0, intrstr, sizeof(intrstr))) { | | 178 | if (!fdtbus_intr_str(faa->faa_phandle, 0, intrstr, sizeof(intrstr))) { |
174 | aprint_error_dev(self, "failed to decode interrupt\n"); | | 179 | aprint_error_dev(self, "failed to decode interrupt\n"); |
175 | return; | | 180 | return; |
176 | } | | 181 | } |
177 | | | 182 | |
178 | sc->sc_ih = fdtbus_intr_establish(faa->faa_phandle, 0, IPL_SDMMC, 0, | | 183 | sc->sc_ih = fdtbus_intr_establish(faa->faa_phandle, 0, IPL_SDMMC, 0, |
179 | sdhc_intr, &sc->sc); | | 184 | sdhc_intr, &sc->sc); |
--- src/sys/arch/arm/nvidia/tegra_soc.c 2015/11/19 22:09:16 1.7
+++ src/sys/arch/arm/nvidia/tegra_soc.c 2015/12/22 22:10:36 1.8
| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: tegra_soc.c,v 1.7 2015/11/19 22:09:16 jmcneill Exp $ */ | | 1 | /* $NetBSD: tegra_soc.c,v 1.8 2015/12/22 22:10:36 jmcneill Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> | | 4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -20,27 +20,27 @@ | | | @@ -20,27 +20,27 @@ |
20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | | 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | | 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | | 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | | 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 24 | * 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 | | 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
26 | * SUCH DAMAGE. | | 26 | * SUCH DAMAGE. |
27 | */ | | 27 | */ |
28 | | | 28 | |
29 | #include "opt_tegra.h" | | 29 | #include "opt_tegra.h" |
30 | #include "opt_multiprocessor.h" | | 30 | #include "opt_multiprocessor.h" |
31 | | | 31 | |
32 | #include <sys/cdefs.h> | | 32 | #include <sys/cdefs.h> |
33 | __KERNEL_RCSID(0, "$NetBSD: tegra_soc.c,v 1.7 2015/11/19 22:09:16 jmcneill Exp $"); | | 33 | __KERNEL_RCSID(0, "$NetBSD: tegra_soc.c,v 1.8 2015/12/22 22:10:36 jmcneill Exp $"); |
34 | | | 34 | |
35 | #define _ARM32_BUS_DMA_PRIVATE | | 35 | #define _ARM32_BUS_DMA_PRIVATE |
36 | #include <sys/param.h> | | 36 | #include <sys/param.h> |
37 | #include <sys/bus.h> | | 37 | #include <sys/bus.h> |
38 | #include <sys/cpu.h> | | 38 | #include <sys/cpu.h> |
39 | #include <sys/device.h> | | 39 | #include <sys/device.h> |
40 | | | 40 | |
41 | #include <uvm/uvm_extern.h> | | 41 | #include <uvm/uvm_extern.h> |
42 | | | 42 | |
43 | #include <arm/bootconfig.h> | | 43 | #include <arm/bootconfig.h> |
44 | #include <arm/cpufunc.h> | | 44 | #include <arm/cpufunc.h> |
45 | | | 45 | |
46 | #include <arm/nvidia/tegra_reg.h> | | 46 | #include <arm/nvidia/tegra_reg.h> |
| @@ -61,28 +61,26 @@ static void tegra_mpinit(void); | | | @@ -61,28 +61,26 @@ static void tegra_mpinit(void); |
61 | | | 61 | |
62 | void | | 62 | void |
63 | tegra_bootstrap(void) | | 63 | tegra_bootstrap(void) |
64 | { | | 64 | { |
65 | if (bus_space_map(&armv7_generic_bs_tag, | | 65 | if (bus_space_map(&armv7_generic_bs_tag, |
66 | TEGRA_PPSB_BASE, TEGRA_PPSB_SIZE, 0, | | 66 | TEGRA_PPSB_BASE, TEGRA_PPSB_SIZE, 0, |
67 | &tegra_ppsb_bsh) != 0) | | 67 | &tegra_ppsb_bsh) != 0) |
68 | panic("couldn't map PPSB"); | | 68 | panic("couldn't map PPSB"); |
69 | if (bus_space_map(&armv7_generic_bs_tag, | | 69 | if (bus_space_map(&armv7_generic_bs_tag, |
70 | TEGRA_APB_BASE, TEGRA_APB_SIZE, 0, | | 70 | TEGRA_APB_BASE, TEGRA_APB_SIZE, 0, |
71 | &tegra_apb_bsh) != 0) | | 71 | &tegra_apb_bsh) != 0) |
72 | panic("couldn't map APB"); | | 72 | panic("couldn't map APB"); |
73 | | | 73 | |
74 | curcpu()->ci_data.cpu_cc_freq = tegra_car_pllx_rate(); | | | |
75 | | | | |
76 | tegra_mpinit(); | | 74 | tegra_mpinit(); |
77 | } | | 75 | } |
78 | | | 76 | |
79 | void | | 77 | void |
80 | tegra_dma_bootstrap(psize_t psize) | | 78 | tegra_dma_bootstrap(psize_t psize) |
81 | { | | 79 | { |
82 | } | | 80 | } |
83 | | | 81 | |
84 | void | | 82 | void |
85 | tegra_cpuinit(void) | | 83 | tegra_cpuinit(void) |
86 | { | | 84 | { |
87 | switch (tegra_chip_id()) { | | 85 | switch (tegra_chip_id()) { |
88 | #ifdef SOC_TEGRA124 | | 86 | #ifdef SOC_TEGRA124 |
--- src/sys/arch/evbarm/conf/Attic/TEGRA 2015/12/16 12:26:14 1.5
+++ src/sys/arch/evbarm/conf/Attic/TEGRA 2015/12/22 22:10:36 1.6
| @@ -1,15 +1,15 @@ | | | @@ -1,15 +1,15 @@ |
1 | # | | 1 | # |
2 | # $NetBSD: TEGRA,v 1.5 2015/12/16 12:26:14 jmcneill Exp $ | | 2 | # $NetBSD: TEGRA,v 1.6 2015/12/22 22:10:36 jmcneill Exp $ |
3 | # | | 3 | # |
4 | # NVIDIA Tegra K1 (T124) | | 4 | # NVIDIA Tegra K1 (T124) |
5 | # | | 5 | # |
6 | | | 6 | |
7 | include "arch/evbarm/conf/std.tegra" | | 7 | include "arch/evbarm/conf/std.tegra" |
8 | include "arch/evbarm/conf/GENERIC.common" | | 8 | include "arch/evbarm/conf/GENERIC.common" |
9 | | | 9 | |
10 | options CPU_CORTEXA15 | | 10 | options CPU_CORTEXA15 |
11 | options SOC_TEGRA124 | | 11 | options SOC_TEGRA124 |
12 | options MULTIPROCESSOR | | 12 | options MULTIPROCESSOR |
13 | | | 13 | |
14 | pseudo-device openfirm # /dev/openfirm | | 14 | pseudo-device openfirm # /dev/openfirm |
15 | | | 15 | |
| @@ -45,27 +45,27 @@ gpiokeys* at fdt? | | | @@ -45,27 +45,27 @@ gpiokeys* at fdt? |
45 | tegralic* at fdt? # LIC | | 45 | tegralic* at fdt? # LIC |
46 | gic* at fdt? # GIC | | 46 | gic* at fdt? # GIC |
47 | | | 47 | |
48 | # Memory controller | | 48 | # Memory controller |
49 | tegramc* at fdt? # MC | | 49 | tegramc* at fdt? # MC |
50 | | | 50 | |
51 | # FUSE controller | | 51 | # FUSE controller |
52 | tegrafuse* at fdt? # FUSE | | 52 | tegrafuse* at fdt? # FUSE |
53 | | | 53 | |
54 | # Power management controller | | 54 | # Power management controller |
55 | tegrapmc* at fdt? # PMC | | 55 | tegrapmc* at fdt? # PMC |
56 | | | 56 | |
57 | # Clock and Reset controller | | 57 | # Clock and Reset controller |
58 | tegracar0 at fdt? # CAR | | 58 | tegra124car* at fdt? # CAR |
59 | | | 59 | |
60 | # GPIO controller | | 60 | # GPIO controller |
61 | tegragpio* at fdt? # GPIO | | 61 | tegragpio* at fdt? # GPIO |
62 | gpio* at gpiobus? | | 62 | gpio* at gpiobus? |
63 | | | 63 | |
64 | # Timers | | 64 | # Timers |
65 | tegratimer* at fdt? # Timers | | 65 | tegratimer* at fdt? # Timers |
66 | | | 66 | |
67 | # MPIO / Pinmux | | 67 | # MPIO / Pinmux |
68 | tegrampio* at fdt? # MPIO | | 68 | tegrampio* at fdt? # MPIO |
69 | | | 69 | |
70 | # XUSB PADCTL | | 70 | # XUSB PADCTL |
71 | tegraxusbpad* at fdt? # XUSB PADCTL | | 71 | tegraxusbpad* at fdt? # XUSB PADCTL |
--- src/sys/arch/evbarm/conf/Attic/std.tegra 2015/12/16 12:26:14 1.11
+++ src/sys/arch/evbarm/conf/Attic/std.tegra 2015/12/22 22:10:36 1.12
| @@ -1,26 +1,25 @@ | | | @@ -1,26 +1,25 @@ |
1 | # $NetBSD: std.tegra,v 1.11 2015/12/16 12:26:14 jmcneill Exp $ | | 1 | # $NetBSD: std.tegra,v 1.12 2015/12/22 22:10:36 jmcneill Exp $ |
2 | # | | 2 | # |
3 | | | 3 | |
4 | machine evbarm arm | | 4 | machine evbarm arm |
5 | include "arch/evbarm/conf/std.evbarm" | | 5 | include "arch/evbarm/conf/std.evbarm" |
6 | | | 6 | |
7 | include "arch/evbarm/conf/files.tegra" | | 7 | include "arch/evbarm/conf/files.tegra" |
8 | | | 8 | |
9 | options FDT # Flattened Device Tree support | | 9 | options FDT # Flattened Device Tree support |
10 | options MODULAR | | 10 | options MODULAR |
11 | options MODULAR_DEFAULT_AUTOLOAD | | 11 | options MODULAR_DEFAULT_AUTOLOAD |
12 | options __HAVE_CPU_COUNTER | | 12 | options __HAVE_CPU_COUNTER |
13 | options CORTEX_PMC | | | |
14 | options __HAVE_FAST_SOFTINTS # should be in types.h | | 13 | options __HAVE_FAST_SOFTINTS # should be in types.h |
15 | options ARM_HAS_VBAR | | 14 | options ARM_HAS_VBAR |
16 | #options __HAVE_MM_MD_DIRECT_MAPPED_PHYS | | 15 | #options __HAVE_MM_MD_DIRECT_MAPPED_PHYS |
17 | #options PMAP_NEED_ALLOC_POOLPAGE | | 16 | #options PMAP_NEED_ALLOC_POOLPAGE |
18 | options TPIDRPRW_IS_CURCPU | | 17 | options TPIDRPRW_IS_CURCPU |
19 | options KERNEL_BASE_EXT=0x80000000 | | 18 | options KERNEL_BASE_EXT=0x80000000 |
20 | options FPU_VFP | | 19 | options FPU_VFP |
21 | options PCI_NETBSD_CONFIGURE | | 20 | options PCI_NETBSD_CONFIGURE |
22 | options __HAVE_PCI_CONF_HOOK | | 21 | options __HAVE_PCI_CONF_HOOK |
23 | options __BUS_SPACE_HAS_STREAM_METHODS | | 22 | options __BUS_SPACE_HAS_STREAM_METHODS |
24 | | | 23 | |
25 | makeoptions KERNEL_BASE_PHYS="0x81000000" | | 24 | makeoptions KERNEL_BASE_PHYS="0x81000000" |
26 | makeoptions KERNEL_BASE_VIRT="0x81000000" | | 25 | makeoptions KERNEL_BASE_VIRT="0x81000000" |
--- src/sys/arch/evbarm/tegra/Attic/tegra_machdep.c 2015/12/16 12:18:02 1.36
+++ src/sys/arch/evbarm/tegra/Attic/tegra_machdep.c 2015/12/22 22:10:36 1.37
| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: tegra_machdep.c,v 1.36 2015/12/16 12:18:02 jmcneill Exp $ */ | | 1 | /* $NetBSD: tegra_machdep.c,v 1.37 2015/12/22 22:10:36 jmcneill Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> | | 4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -17,27 +17,27 @@ | | | @@ -17,27 +17,27 @@ |
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | | 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | | 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | | 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | | 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | | 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 24 | * 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 | | 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
26 | * SUCH DAMAGE. | | 26 | * SUCH DAMAGE. |
27 | */ | | 27 | */ |
28 | | | 28 | |
29 | #include <sys/cdefs.h> | | 29 | #include <sys/cdefs.h> |
30 | __KERNEL_RCSID(0, "$NetBSD: tegra_machdep.c,v 1.36 2015/12/16 12:18:02 jmcneill Exp $"); | | 30 | __KERNEL_RCSID(0, "$NetBSD: tegra_machdep.c,v 1.37 2015/12/22 22:10:36 jmcneill Exp $"); |
31 | | | 31 | |
32 | #include "opt_tegra.h" | | 32 | #include "opt_tegra.h" |
33 | #include "opt_machdep.h" | | 33 | #include "opt_machdep.h" |
34 | #include "opt_ddb.h" | | 34 | #include "opt_ddb.h" |
35 | #include "opt_md.h" | | 35 | #include "opt_md.h" |
36 | #include "opt_arm_debug.h" | | 36 | #include "opt_arm_debug.h" |
37 | #include "opt_multiprocessor.h" | | 37 | #include "opt_multiprocessor.h" |
38 | | | 38 | |
39 | #include "com.h" | | 39 | #include "com.h" |
40 | #include "ukbd.h" | | 40 | #include "ukbd.h" |
41 | #include "genfb.h" | | 41 | #include "genfb.h" |
42 | #include "ether.h" | | 42 | #include "ether.h" |
43 | #include "as3722pmic.h" | | 43 | #include "as3722pmic.h" |
| @@ -371,27 +371,27 @@ initarm(void *arg) | | | @@ -371,27 +371,27 @@ initarm(void *arg) |
371 | #endif | | 371 | #endif |
372 | | | 372 | |
373 | void | | 373 | void |
374 | consinit(void) | | 374 | consinit(void) |
375 | { | | 375 | { |
376 | static bool consinit_called = false; | | 376 | static bool consinit_called = false; |
377 | | | 377 | |
378 | if (consinit_called) | | 378 | if (consinit_called) |
379 | return; | | 379 | return; |
380 | consinit_called = true; | | 380 | consinit_called = true; |
381 | | | 381 | |
382 | #if NCOM > 0 | | 382 | #if NCOM > 0 |
383 | const bus_space_tag_t bst = &armv7_generic_a4x_bs_tag; | | 383 | const bus_space_tag_t bst = &armv7_generic_a4x_bs_tag; |
384 | const u_int freq = tegra_car_uart_rate(3); | | 384 | const u_int freq = 408000000; /* 408MHz PLLP_OUT0 */ |
385 | if (comcnattach(bst, CONSADDR, CONSPEED, freq, | | 385 | if (comcnattach(bst, CONSADDR, CONSPEED, freq, |
386 | COM_TYPE_TEGRA, CONMODE)) { | | 386 | COM_TYPE_TEGRA, CONMODE)) { |
387 | panic("Serial console cannot be initialized."); | | 387 | panic("Serial console cannot be initialized."); |
388 | } | | 388 | } |
389 | #else | | 389 | #else |
390 | #error only COM console is supported | | 390 | #error only COM console is supported |
391 | #endif | | 391 | #endif |
392 | } | | 392 | } |
393 | | | 393 | |
394 | static bool | | 394 | static bool |
395 | tegra_bootconf_match(const char *key, const char *val) | | 395 | tegra_bootconf_match(const char *key, const char *val) |
396 | { | | 396 | { |
397 | char *s; | | 397 | char *s; |
| @@ -432,30 +432,26 @@ tegra_device_register(device_t self, voi | | | @@ -432,30 +432,26 @@ tegra_device_register(device_t self, voi |
432 | | | 432 | |
433 | if (device_is_a(self, "armperiph") | | 433 | if (device_is_a(self, "armperiph") |
434 | && device_is_a(device_parent(self), "mainbus")) { | | 434 | && device_is_a(device_parent(self), "mainbus")) { |
435 | struct mainbus_attach_args * const mb = aux; | | 435 | struct mainbus_attach_args * const mb = aux; |
436 | mb->mb_iot = &armv7_generic_bs_tag; | | 436 | mb->mb_iot = &armv7_generic_bs_tag; |
437 | return; | | 437 | return; |
438 | } | | 438 | } |
439 | | | 439 | |
440 | if (device_is_a(self, "armgtmr")) { | | 440 | if (device_is_a(self, "armgtmr")) { |
441 | prop_dictionary_set_uint32(dict, "frequency", TEGRA_REF_FREQ); | | 441 | prop_dictionary_set_uint32(dict, "frequency", TEGRA_REF_FREQ); |
442 | return; | | 442 | return; |
443 | } | | 443 | } |
444 | | | 444 | |
445 | if (device_is_a(self, "cpu") && device_unit(self) == 0) { | | | |
446 | tegra_cpuinit(); | | | |
447 | } | | | |
448 | | | | |
449 | if (device_is_a(self, "tegrafb") | | 445 | if (device_is_a(self, "tegrafb") |
450 | && tegra_bootconf_match("console", "fb")) { | | 446 | && tegra_bootconf_match("console", "fb")) { |
451 | prop_dictionary_set_bool(dict, "is_console", true); | | 447 | prop_dictionary_set_bool(dict, "is_console", true); |
452 | #if NUKBD > 0 | | 448 | #if NUKBD > 0 |
453 | ukbd_cnattach(); | | 449 | ukbd_cnattach(); |
454 | #endif | | 450 | #endif |
455 | } | | 451 | } |
456 | | | 452 | |
457 | if (device_is_a(self, "tegradrm")) { | | 453 | if (device_is_a(self, "tegradrm")) { |
458 | const char *video = tegra_bootconf_strdup("video"); | | 454 | const char *video = tegra_bootconf_strdup("video"); |
459 | | | 455 | |
460 | if (tegra_bootconf_match("hdmi.forcemode", "dvi")) { | | 456 | if (tegra_bootconf_match("hdmi.forcemode", "dvi")) { |
461 | prop_dictionary_set_bool(dict, "force-dvi", true); | | 457 | prop_dictionary_set_bool(dict, "force-dvi", true); |