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

cvs diff -r1.27 -r1.28 src/sys/arch/arm/nvidia/files.tegra (expand / switch to unified diff)

--- 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
6include "arch/arm/pic/files.pic" 6include "arch/arm/pic/files.pic"
7include "arch/arm/cortex/files.cortex" 7include "arch/arm/cortex/files.cortex"
8 8
9file arch/arm/arm32/arm32_boot.c 9file arch/arm/arm32/arm32_boot.c
10file arch/arm/arm32/arm32_kvminit.c 10file arch/arm/arm32/arm32_kvminit.c
11file arch/arm/arm32/arm32_reboot.c 11file arch/arm/arm32/arm32_reboot.c
12file arch/arm/arm32/irq_dispatch.S 12file arch/arm/arm32/irq_dispatch.S
13file arch/arm/arm32/armv7_generic_space.c 13file arch/arm/arm32/armv7_generic_space.c
14file arch/arm/arm/bus_space_a4x.S 14file 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
33file arch/arm/nvidia/tegra_mc.c tegra_mc 33file arch/arm/nvidia/tegra_mc.c tegra_mc
34 34
35# Power management controller 35# Power management controller
36device tegrapmc 36device tegrapmc
37attach tegrapmc at fdt with tegra_pmc 37attach tegrapmc at fdt with tegra_pmc
38file arch/arm/nvidia/tegra_pmc.c tegra_pmc 38file arch/arm/nvidia/tegra_pmc.c tegra_pmc
39 39
40# eFUSE 40# eFUSE
41device tegrafuse 41device tegrafuse
42attach tegrafuse at fdt with tegra_fuse 42attach tegrafuse at fdt with tegra_fuse
43file arch/arm/nvidia/tegra_fuse.c tegra_fuse 43file arch/arm/nvidia/tegra_fuse.c tegra_fuse
44 44
45# Clock and Reset controller 45# Clock and Reset controller
46device tegracar 46device tegra124car: clk
47attach tegracar at fdt with tegra_car 47attach tegra124car at fdt with tegra124_car
48file arch/arm/nvidia/tegra_car.c tegra_car 48file arch/arm/nvidia/tegra124_car.c tegra124_car
49 49
50# GPIO controller 50# GPIO controller
51device tegragpio: gpiobus 51device tegragpio: gpiobus
52attach tegragpio at fdt with tegra_gpio 52attach tegragpio at fdt with tegra_gpio
53file arch/arm/nvidia/tegra_gpio.c tegra_gpio 53file arch/arm/nvidia/tegra_gpio.c tegra_gpio
54 54
55# Timers 55# Timers
56device tegratimer: sysmon_wdog 56device tegratimer: sysmon_wdog
57attach tegratimer at fdt with tegra_timer 57attach tegratimer at fdt with tegra_timer
58file arch/arm/nvidia/tegra_timer.c tegra_timer 58file arch/arm/nvidia/tegra_timer.c tegra_timer
59 59
60# MPIO / Pinmux 60# MPIO / Pinmux
61device tegrampio 61device tegrampio

cvs diff -r1.11 -r1.12 src/sys/arch/arm/nvidia/soc_tegra124.c (expand / switch to unified diff)

--- 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
100static struct tegra124_speedo { 104static 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
 114static struct clk *tegra124_clk_pllx = NULL;
 115
110void 116void
111tegra124_cpuinit(void) 117tegra124_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
126static void 153static void
127tegra124_speedo_init(void) 154tegra124_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
135static int 162static 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
214static u_int 239static u_int
215tegra124_cpufreq_get_rate(void) 240tegra124_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
220static size_t 245static size_t
221tegra124_cpufreq_get_available(u_int *pavail, size_t maxavail) 246tegra124_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;

cvs diff -r1.11 -r1.12 src/sys/arch/arm/nvidia/tegra_ehci.c (expand / switch to unified diff)

--- 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 */ 
53static int 
54tegra_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
70static int tegra_ehci_match(device_t, cfdata_t, void *); 54static int tegra_ehci_match(device_t, cfdata_t, void *);
71static void tegra_ehci_attach(device_t, device_t, void *); 55static void tegra_ehci_attach(device_t, device_t, void *);
72 56
73static void tegra_ehci_init(struct ehci_softc *); 57static void tegra_ehci_init(struct ehci_softc *);
74 58
75struct tegra_ehci_softc { 59struct 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
83static int tegra_ehci_port_status(struct ehci_softc *sc, uint32_t v, 66static int tegra_ehci_port_status(struct ehci_softc *sc, uint32_t v,
84 int i); 67 int i);
85 68
86CFATTACH_DECL2_NEW(tegra_ehci, sizeof(struct tegra_ehci_softc), 69CFATTACH_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
90static int 73static int
91tegra_ehci_match(device_t parent, cfdata_t cf, void *aux) 74tegra_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);

File Added: src/sys/arch/arm/nvidia/tegra124_car.c
/* $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;
}

File Added: src/sys/arch/arm/nvidia/tegra124_carreg.h
/* $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 */

File Added: src/sys/arch/arm/nvidia/tegra_clock.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 */

cvs diff -r1.8 -r1.9 src/sys/arch/arm/nvidia/tegra_ahcisata.c (expand / switch to unified diff)

--- 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
49static int tegra_ahcisata_match(device_t, cfdata_t, void *); 50static int tegra_ahcisata_match(device_t, cfdata_t, void *);
50static void tegra_ahcisata_attach(device_t, device_t, void *); 51static void tegra_ahcisata_attach(device_t, device_t, void *);
51 52
52struct tegra_ahcisata_softc { 53struct 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
61static const char * const tegra_ahcisata_supplies[] = { 69static 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
69static void tegra_ahcisata_init(struct tegra_ahcisata_softc *); 77static void tegra_ahcisata_init(struct tegra_ahcisata_softc *);
 78static int tegra_ahcisata_init_clocks(struct tegra_ahcisata_softc *);
70 79
71CFATTACH_DECL_NEW(tegra_ahcisata, sizeof(struct tegra_ahcisata_softc), 80CFATTACH_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
74static int 83static int
75tegra_ahcisata_match(device_t parent, cfdata_t cf, void *aux) 84tegra_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
 283static int
 284tegra_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}

cvs diff -r1.8 -r1.9 src/sys/arch/arm/nvidia/tegra_nouveau.c (expand / switch to unified diff)

--- 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
48extern char *nouveau_config; 49extern char *nouveau_config;
49extern char *nouveau_debug; 50extern char *nouveau_debug;
50extern struct drm_driver *const nouveau_drm_driver; 51extern struct drm_driver *const nouveau_drm_driver;
51 52
52static int tegra_nouveau_match(device_t, cfdata_t, void *); 53static int tegra_nouveau_match(device_t, cfdata_t, void *);
53static void tegra_nouveau_attach(device_t, device_t, void *); 54static void tegra_nouveau_attach(device_t, device_t, void *);
54 55
55struct tegra_nouveau_softc { 56struct 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
65static void tegra_nouveau_init(device_t); 69static void tegra_nouveau_init(device_t);
66 70
67static int tegra_nouveau_get_irq(struct drm_device *); 71static int tegra_nouveau_get_irq(struct drm_device *);
68static const char *tegra_nouveau_get_name(struct drm_device *); 72static const char *tegra_nouveau_get_name(struct drm_device *);
69static int tegra_nouveau_set_busid(struct drm_device *, 73static int tegra_nouveau_set_busid(struct drm_device *,
70 struct drm_master *); 74 struct drm_master *);
71static int tegra_nouveau_irq_install(struct drm_device *, 75static 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
99static void 103static void
100tegra_nouveau_attach(device_t parent, device_t self, void *aux) 104tegra_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

File Deleted: src/sys/arch/arm/nvidia/Attic/tegra_car.c

File Deleted: src/sys/arch/arm/nvidia/Attic/tegra_carreg.h

cvs diff -r1.2 -r1.3 src/sys/arch/arm/nvidia/tegra_cec.c (expand / switch to unified diff)

--- 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
54static int tegra_cec_match(device_t, cfdata_t, void *); 54static int tegra_cec_match(device_t, cfdata_t, void *);
55static void tegra_cec_attach(device_t, device_t, void *); 55static void tegra_cec_attach(device_t, device_t, void *);
56 56
57static int tegra_cec_intr(void *); 57static int tegra_cec_intr(void *);
58 58
59struct tegra_cec_softc { 59struct 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

cvs diff -r1.2 -r1.3 src/sys/arch/arm/nvidia/tegra_cpufreq.c (expand / switch to unified diff)

--- 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
47static u_int cpufreq_busy; 47static u_int cpufreq_busy;
48static struct sysctllog *cpufreq_log; 48static struct sysctllog *cpufreq_log;
49static int cpufreq_node_target, cpufreq_node_current, cpufreq_node_available; 49static int cpufreq_node_target, cpufreq_node_current, cpufreq_node_available;
50 50
51static const struct tegra_cpufreq_func *cpufreq_func = NULL; 51static const struct tegra_cpufreq_func *cpufreq_func = NULL;
52 52
53static void tegra_cpufreq_post(void *, void *); 
54static int tegra_cpufreq_freq_helper(SYSCTLFN_PROTO); 53static int tegra_cpufreq_freq_helper(SYSCTLFN_PROTO);
55static char tegra_cpufreq_available[TEGRA_CPUFREQ_MAX * 5]; 54static 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
61void 60void
62tegra_cpufreq_register(const struct tegra_cpufreq_func *cf) 61tegra_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
136sysctl_failed: 136sysctl_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
141static void 
142tegra_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 
149static int 141static int
150tegra_cpufreq_freq_helper(SYSCTLFN_ARGS) 142tegra_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}

cvs diff -r1.2 -r1.3 src/sys/arch/arm/nvidia/tegra_soctherm.c (expand / switch to unified diff)

--- 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
119struct tegra_soctherm_softc { 119struct 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
 137static int tegra_soctherm_init_clocks(struct tegra_soctherm_softc *);
134static void tegra_soctherm_init_sensors(struct tegra_soctherm_softc *); 138static void tegra_soctherm_init_sensors(struct tegra_soctherm_softc *);
135static void tegra_soctherm_init_sensor(struct tegra_soctherm_softc *, 139static void tegra_soctherm_init_sensor(struct tegra_soctherm_softc *,
136 struct tegra_soctherm_sensor *); 140 struct tegra_soctherm_sensor *);
137static void tegra_soctherm_refresh(struct sysmon_envsys *, envsys_data_t *); 141static void tegra_soctherm_refresh(struct sysmon_envsys *, envsys_data_t *);
138static int tegra_soctherm_decodeint(uint32_t, uint32_t); 142static int tegra_soctherm_decodeint(uint32_t, uint32_t);
139static int64_t tegra_soctherm_divide(int64_t, int64_t); 143static int64_t tegra_soctherm_divide(int64_t, int64_t);
140 144
141CFATTACH_DECL_NEW(tegra_soctherm, sizeof(struct tegra_soctherm_softc), 145CFATTACH_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
167static void 171static void
168tegra_soctherm_attach(device_t parent, device_t self, void *aux) 172tegra_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
 226static int
 227tegra_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
206static void 291static void
207tegra_soctherm_init_sensors(struct tegra_soctherm_softc *sc) 292tegra_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);

cvs diff -r1.2 -r1.3 src/sys/arch/arm/nvidia/tegra_timer.c (expand / switch to unified diff)

--- 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
50static int tegra_timer_match(device_t, cfdata_t, void *); 50static int tegra_timer_match(device_t, cfdata_t, void *);
51static void tegra_timer_attach(device_t, device_t, void *); 51static void tegra_timer_attach(device_t, device_t, void *);
52 52
53struct tegra_timer_softc { 53struct 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
61static int tegra_timer_wdt_setmode(struct sysmon_wdog *); 62static int tegra_timer_wdt_setmode(struct sysmon_wdog *);
62static int tegra_timer_wdt_tickle(struct sysmon_wdog *); 63static int tegra_timer_wdt_tickle(struct sysmon_wdog *);
63 64
64CFATTACH_DECL_NEW(tegra_timer, sizeof(struct tegra_timer_softc), 65CFATTACH_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
83static void 84static void
84tegra_timer_attach(device_t parent, device_t self, void *aux) 85tegra_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
121static int 128static int
122tegra_timer_wdt_setmode(struct sysmon_wdog *smw) 129tegra_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
147static int 152static int
148tegra_timer_wdt_tickle(struct sysmon_wdog *smw) 153tegra_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
 162void
 163delay(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}

cvs diff -r1.4 -r1.5 src/sys/arch/arm/nvidia/tegra_com.c (expand / switch to unified diff)

--- 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 */ 
52static int 
53tegra_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 
69static int tegra_com_match(device_t, cfdata_t, void *); 51static int tegra_com_match(device_t, cfdata_t, void *);
70static void tegra_com_attach(device_t, device_t, void *); 52static void tegra_com_attach(device_t, device_t, void *);
71 53
72struct tegra_com_softc { 54struct 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
77CFATTACH_DECL_NEW(tegra_com, sizeof(struct tegra_com_softc), 62CFATTACH_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
80static int 65static int
81tegra_com_match(device_t parent, cfdata_t cf, void *aux) 66tegra_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

cvs diff -r1.4 -r1.5 src/sys/arch/arm/nvidia/tegra_drm.c (expand / switch to unified diff)

--- 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
115static void 115static void
116tegra_drm_attach(device_t parent, device_t self, void *aux) 116tegra_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) {

cvs diff -r1.4 -r1.5 src/sys/arch/arm/nvidia/tegra_usbphy.c (expand / switch to unified diff)

--- 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 */ 
46static int 
47tegra_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 
61static int tegra_usbphy_match(device_t, cfdata_t, void *); 46static int tegra_usbphy_match(device_t, cfdata_t, void *);
62static void tegra_usbphy_attach(device_t, device_t, void *); 47static void tegra_usbphy_attach(device_t, device_t, void *);
63 48
64struct tegra_usbphy_softc { 49struct 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
99static void 88static void
100tegra_usbphy_attach(device_t parent, device_t self, void *aux) 89tegra_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
147static int 167static int
148tegra_usbphy_parse_properties(struct tegra_usbphy_softc *sc) 168tegra_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
172static void 192static void
173tegra_usbphy_utmip_init(struct tegra_usbphy_softc *sc) 193tegra_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}

cvs diff -r1.5 -r1.6 src/sys/arch/arm/nvidia/tegra_drm.h (expand / switch to unified diff)

--- 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 @@
44struct tegra_framebuffer; 44struct tegra_framebuffer;
45 45
46struct tegra_gem_object; 46struct tegra_gem_object;
47 47
48struct tegra_drm_softc { 48struct 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
68struct tegra_drmfb_attach_args { 76struct 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
76struct tegra_crtc { 84struct 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
91struct tegra_encoder { 100struct 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

cvs diff -r1.5 -r1.6 src/sys/arch/arm/nvidia/tegra_hdaudio.c (expand / switch to unified diff)

--- 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,
57static void tegra_hdaudio_attach(device_t, device_t, void *); 57static void tegra_hdaudio_attach(device_t, device_t, void *);
58static int tegra_hdaudio_detach(device_t, int); 58static int tegra_hdaudio_detach(device_t, int);
59static int tegra_hdaudio_rescan(device_t, const char *, const int *); 59static int tegra_hdaudio_rescan(device_t, const char *, const int *);
60static void tegra_hdaudio_childdet(device_t, device_t); 60static void tegra_hdaudio_childdet(device_t, device_t);
61 61
62static int tegra_hdaudio_intr(void *); 62static int tegra_hdaudio_intr(void *);
63 63
64struct tegra_hdaudio_softc { 64struct 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
 78static int tegra_hdaudio_init_clocks(struct tegra_hdaudio_softc *);
72static void tegra_hdaudio_init(struct tegra_hdaudio_softc *); 79static void tegra_hdaudio_init(struct tegra_hdaudio_softc *);
73 80
74CFATTACH_DECL2_NEW(tegra_hdaudio, sizeof(struct tegra_hdaudio_softc), 81CFATTACH_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
78static int 85static int
79tegra_hdaudio_match(device_t parent, cfdata_t cf, void *aux) 86tegra_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
87static void 94static void
88tegra_hdaudio_attach(device_t parent, device_t self, void *aux) 95tegra_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
 183static int
 184tegra_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
141static void 256static void
142tegra_hdaudio_init(struct tegra_hdaudio_softc *sc) 257tegra_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);

cvs diff -r1.10 -r1.11 src/sys/arch/arm/nvidia/tegra_drm_mode.c (expand / switch to unified diff)

--- 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
48static struct drm_framebuffer *tegra_fb_create(struct drm_device *, 49static 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
51static const struct drm_mode_config_funcs tegra_mode_config_funcs = { 52static 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
281static int 282static int
282tegra_crtc_init(struct drm_device *ddev, int index) 283tegra_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
341static int 381static int
342tegra_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, 382tegra_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
744static int 784static int
745tegra_encoder_init(struct drm_device *ddev) 785tegra_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
777static void 838static void
778tegra_encoder_destroy(struct drm_encoder *encoder) 839tegra_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
807static bool 868static bool
808tegra_encoder_mode_fixup(struct drm_encoder *encoder, 869tegra_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
 875static int
 876tegra_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
814static void 910static void
815tegra_encoder_mode_set(struct drm_encoder *encoder, 911tegra_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 }

cvs diff -r1.10 -r1.11 src/sys/arch/arm/nvidia/tegra_i2c.c (expand / switch to unified diff)

--- 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 */ 
48static int 
49tegra_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 
69static int tegra_i2c_match(device_t, cfdata_t, void *); 47static int tegra_i2c_match(device_t, cfdata_t, void *);
70static void tegra_i2c_attach(device_t, device_t, void *); 48static void tegra_i2c_attach(device_t, device_t, void *);
71 49
72static i2c_tag_t tegra_i2c_get_tag(device_t); 50static i2c_tag_t tegra_i2c_get_tag(device_t);
73 51
74struct fdtbus_i2c_controller_func tegra_i2c_funcs = { 52struct 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
78struct tegra_i2c_softc { 56struct 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
91static void tegra_i2c_init(struct tegra_i2c_softc *); 71static void tegra_i2c_init(struct tegra_i2c_softc *);
92static int tegra_i2c_intr(void *); 72static int tegra_i2c_intr(void *);
93 73
94static int tegra_i2c_acquire_bus(void *, int); 74static int tegra_i2c_acquire_bus(void *, int);
95static void tegra_i2c_release_bus(void *, int); 75static void tegra_i2c_release_bus(void *, int);
96static int tegra_i2c_exec(void *, i2c_op_t, i2c_addr_t, const void *, 76static 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

cvs diff -r1.1 -r1.2 src/sys/arch/arm/nvidia/Attic/tegra_fdt.c (expand / switch to unified diff)

--- 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
64void 64void
65tegrafdt_attach(device_t parent, device_t self, void *aux) 65tegrafdt_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}

cvs diff -r1.1 -r1.2 src/sys/arch/arm/nvidia/tegra_timerreg.h (expand / switch to unified diff)

--- 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

cvs diff -r1.3 -r1.4 src/sys/arch/arm/nvidia/tegra_fuse.c (expand / switch to unified diff)

--- 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
46static int tegra_fuse_match(device_t, cfdata_t, void *); 44static int tegra_fuse_match(device_t, cfdata_t, void *);
47static void tegra_fuse_attach(device_t, device_t, void *); 45static void tegra_fuse_attach(device_t, device_t, void *);
48 46
49struct tegra_fuse_softc { 47struct 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
55static struct tegra_fuse_softc *fuse_softc = NULL; 56static struct tegra_fuse_softc *fuse_softc = NULL;
56 57
57CFATTACH_DECL_NEW(tegra_fuse, sizeof(struct tegra_fuse_softc), 58CFATTACH_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
60static int 61static int
61tegra_fuse_match(device_t parent, cfdata_t cf, void *aux) 62tegra_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
69static void 70static void
70tegra_fuse_attach(device_t parent, device_t self, void *aux) 71tegra_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
98uint32_t 109uint32_t
99tegra_fuse_read(u_int offset) 110tegra_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}

cvs diff -r1.14 -r1.15 src/sys/arch/arm/nvidia/tegra_sdhc.c (expand / switch to unified diff)

--- 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 */ 
51static int 
52tegra_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 
68static int tegra_sdhc_match(device_t, cfdata_t, void *); 50static int tegra_sdhc_match(device_t, cfdata_t, void *);
69static void tegra_sdhc_attach(device_t, device_t, void *); 51static void tegra_sdhc_attach(device_t, device_t, void *);
70 52
71static int tegra_sdhc_card_detect(struct sdhc_softc *); 53static int tegra_sdhc_card_detect(struct sdhc_softc *);
72static int tegra_sdhc_write_protect(struct sdhc_softc *); 54static int tegra_sdhc_write_protect(struct sdhc_softc *);
73 55
74struct tegra_sdhc_softc { 56struct 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
90CFATTACH_DECL_NEW(tegra_sdhc, sizeof(struct tegra_sdhc_softc), 73CFATTACH_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);

cvs diff -r1.7 -r1.8 src/sys/arch/arm/nvidia/tegra_soc.c (expand / switch to unified diff)

--- 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
62void 62void
63tegra_bootstrap(void) 63tegra_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
79void 77void
80tegra_dma_bootstrap(psize_t psize) 78tegra_dma_bootstrap(psize_t psize)
81{ 79{
82} 80}
83 81
84void 82void
85tegra_cpuinit(void) 83tegra_cpuinit(void)
86{ 84{
87 switch (tegra_chip_id()) { 85 switch (tegra_chip_id()) {
88#ifdef SOC_TEGRA124 86#ifdef SOC_TEGRA124

cvs diff -r1.5 -r1.6 src/sys/arch/evbarm/conf/Attic/TEGRA (expand / switch to unified diff)

--- 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
7include "arch/evbarm/conf/std.tegra" 7include "arch/evbarm/conf/std.tegra"
8include "arch/evbarm/conf/GENERIC.common" 8include "arch/evbarm/conf/GENERIC.common"
9 9
10options CPU_CORTEXA15 10options CPU_CORTEXA15
11options SOC_TEGRA124 11options SOC_TEGRA124
12options MULTIPROCESSOR 12options MULTIPROCESSOR
13 13
14pseudo-device openfirm # /dev/openfirm 14pseudo-device openfirm # /dev/openfirm
15 15
@@ -45,27 +45,27 @@ gpiokeys* at fdt? @@ -45,27 +45,27 @@ gpiokeys* at fdt?
45tegralic* at fdt? # LIC 45tegralic* at fdt? # LIC
46gic* at fdt? # GIC 46gic* at fdt? # GIC
47 47
48# Memory controller 48# Memory controller
49tegramc* at fdt? # MC 49tegramc* at fdt? # MC
50 50
51# FUSE controller 51# FUSE controller
52tegrafuse* at fdt? # FUSE 52tegrafuse* at fdt? # FUSE
53 53
54# Power management controller 54# Power management controller
55tegrapmc* at fdt? # PMC 55tegrapmc* at fdt? # PMC
56 56
57# Clock and Reset controller 57# Clock and Reset controller
58tegracar0 at fdt? # CAR 58tegra124car* at fdt? # CAR
59 59
60# GPIO controller 60# GPIO controller
61tegragpio* at fdt? # GPIO 61tegragpio* at fdt? # GPIO
62gpio* at gpiobus? 62gpio* at gpiobus?
63 63
64# Timers 64# Timers
65tegratimer* at fdt? # Timers 65tegratimer* at fdt? # Timers
66 66
67# MPIO / Pinmux 67# MPIO / Pinmux
68tegrampio* at fdt? # MPIO 68tegrampio* at fdt? # MPIO
69 69
70# XUSB PADCTL 70# XUSB PADCTL
71tegraxusbpad* at fdt? # XUSB PADCTL 71tegraxusbpad* at fdt? # XUSB PADCTL

cvs diff -r1.11 -r1.12 src/sys/arch/evbarm/conf/Attic/std.tegra (expand / switch to unified diff)

--- 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
4machine evbarm arm 4machine evbarm arm
5include "arch/evbarm/conf/std.evbarm" 5include "arch/evbarm/conf/std.evbarm"
6 6
7include "arch/evbarm/conf/files.tegra" 7include "arch/evbarm/conf/files.tegra"
8 8
9options FDT # Flattened Device Tree support 9options FDT # Flattened Device Tree support
10options MODULAR 10options MODULAR
11options MODULAR_DEFAULT_AUTOLOAD 11options MODULAR_DEFAULT_AUTOLOAD
12options __HAVE_CPU_COUNTER 12options __HAVE_CPU_COUNTER
13options CORTEX_PMC 
14options __HAVE_FAST_SOFTINTS # should be in types.h 13options __HAVE_FAST_SOFTINTS # should be in types.h
15options ARM_HAS_VBAR 14options 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
18options TPIDRPRW_IS_CURCPU 17options TPIDRPRW_IS_CURCPU
19options KERNEL_BASE_EXT=0x80000000 18options KERNEL_BASE_EXT=0x80000000
20options FPU_VFP 19options FPU_VFP
21options PCI_NETBSD_CONFIGURE 20options PCI_NETBSD_CONFIGURE
22options __HAVE_PCI_CONF_HOOK 21options __HAVE_PCI_CONF_HOOK
23options __BUS_SPACE_HAS_STREAM_METHODS 22options __BUS_SPACE_HAS_STREAM_METHODS
24 23
25makeoptions KERNEL_BASE_PHYS="0x81000000" 24makeoptions KERNEL_BASE_PHYS="0x81000000"
26makeoptions KERNEL_BASE_VIRT="0x81000000" 25makeoptions KERNEL_BASE_VIRT="0x81000000"

cvs diff -r1.36 -r1.37 src/sys/arch/evbarm/tegra/Attic/tegra_machdep.c (expand / switch to unified diff)

--- 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
373void 373void
374consinit(void) 374consinit(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
394static bool 394static bool
395tegra_bootconf_match(const char *key, const char *val) 395tegra_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);