Since we're using designated initialisers for compat data, we should use a completely empty initializer for the sentinel.diff -r1.3 -r1.4 src/sys/dev/fdt/amdccp_fdt.c
(thorpej)
--- src/sys/dev/fdt/amdccp_fdt.c 2021/01/18 02:35:49 1.3
+++ src/sys/dev/fdt/amdccp_fdt.c 2021/01/25 14:25:09 1.4
@@ -1,93 +1,92 @@ | @@ -1,93 +1,92 @@ | |||
1 | /* $NetBSD: amdccp_fdt.c,v 1.3 2021/01/18 02:35:49 thorpej Exp $ */ | 1 | /* $NetBSD: amdccp_fdt.c,v 1.4 2021/01/25 14:25:09 thorpej Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2018 Jonathan A. Kollasch | 4 | * Copyright (c) 2018 Jonathan A. Kollasch | |
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. | |
15 | * | 15 | * | |
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
17 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 17 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR | 19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR | |
20 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | 20 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
21 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 21 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
22 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | 22 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | |
23 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | 23 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | |
24 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | 24 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | |
25 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | 25 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |
26 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
27 | */ | 27 | */ | |
28 | 28 | |||
29 | #include <sys/cdefs.h> | 29 | #include <sys/cdefs.h> | |
30 | 30 | |||
31 | __KERNEL_RCSID(0, "$NetBSD: amdccp_fdt.c,v 1.3 2021/01/18 02:35:49 thorpej Exp $"); | 31 | __KERNEL_RCSID(0, "$NetBSD: amdccp_fdt.c,v 1.4 2021/01/25 14:25:09 thorpej Exp $"); | |
32 | 32 | |||
33 | #include <sys/param.h> | 33 | #include <sys/param.h> | |
34 | #include <sys/systm.h> | 34 | #include <sys/systm.h> | |
35 | #include <sys/device.h> | 35 | #include <sys/device.h> | |
36 | #include <sys/bus.h> | 36 | #include <sys/bus.h> | |
37 | 37 | |||
38 | #include <dev/fdt/fdtvar.h> | 38 | #include <dev/fdt/fdtvar.h> | |
39 | 39 | |||
40 | #include <dev/ic/amdccpvar.h> | 40 | #include <dev/ic/amdccpvar.h> | |
41 | 41 | |||
42 | struct amdccp_fdt_softc { | 42 | struct amdccp_fdt_softc { | |
43 | struct amdccp_softc sc_sc; | 43 | struct amdccp_softc sc_sc; | |
44 | }; | 44 | }; | |
45 | 45 | |||
46 | static int amdccp_fdt_match(device_t, cfdata_t, void *); | 46 | static int amdccp_fdt_match(device_t, cfdata_t, void *); | |
47 | static void amdccp_fdt_attach(device_t, device_t, void *); | 47 | static void amdccp_fdt_attach(device_t, device_t, void *); | |
48 | 48 | |||
49 | CFATTACH_DECL_NEW(amdccp_fdt, sizeof(struct amdccp_fdt_softc), | 49 | CFATTACH_DECL_NEW(amdccp_fdt, sizeof(struct amdccp_fdt_softc), | |
50 | amdccp_fdt_match, amdccp_fdt_attach, NULL, NULL); | 50 | amdccp_fdt_match, amdccp_fdt_attach, NULL, NULL); | |
51 | 51 | |||
52 | static const struct device_compatible_entry compat_data[] = { | 52 | static const struct device_compatible_entry compat_data[] = { | |
53 | { .compat = "amd,ccp-seattle-v1a" }, | 53 | { .compat = "amd,ccp-seattle-v1a" }, | |
54 | 54 | { } | ||
55 | { 0 } | |||
56 | }; | 55 | }; | |
57 | 56 | |||
58 | static int | 57 | static int | |
59 | amdccp_fdt_match(device_t parent, cfdata_t cf, void *aux) | 58 | amdccp_fdt_match(device_t parent, cfdata_t cf, void *aux) | |
60 | { | 59 | { | |
61 | const struct fdt_attach_args * const faa = aux; | 60 | const struct fdt_attach_args * const faa = aux; | |
62 | 61 | |||
63 | return of_match_compat_data(faa->faa_phandle, compat_data); | 62 | return of_match_compat_data(faa->faa_phandle, compat_data); | |
64 | } | 63 | } | |
65 | 64 | |||
66 | static void | 65 | static void | |
67 | amdccp_fdt_attach(device_t parent, device_t self, void *aux) | 66 | amdccp_fdt_attach(device_t parent, device_t self, void *aux) | |
68 | { | 67 | { | |
69 | struct amdccp_fdt_softc * const fsc = device_private(self); | 68 | struct amdccp_fdt_softc * const fsc = device_private(self); | |
70 | struct amdccp_softc * const sc = &fsc->sc_sc; | 69 | struct amdccp_softc * const sc = &fsc->sc_sc; | |
71 | const struct fdt_attach_args * const faa = aux; | 70 | const struct fdt_attach_args * const faa = aux; | |
72 | const int phandle = faa->faa_phandle; | 71 | const int phandle = faa->faa_phandle; | |
73 | bus_addr_t addr; | 72 | bus_addr_t addr; | |
74 | bus_size_t size; | 73 | bus_size_t size; | |
75 | 74 | |||
76 | fsc->sc_sc.sc_dev = self; | 75 | fsc->sc_sc.sc_dev = self; | |
77 | 76 | |||
78 | if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { | 77 | if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { | |
79 | aprint_error(": couldn't get registers\n"); | 78 | aprint_error(": couldn't get registers\n"); | |
80 | return; | 79 | return; | |
81 | } | 80 | } | |
82 | 81 | |||
83 | sc->sc_bst = faa->faa_bst; | 82 | sc->sc_bst = faa->faa_bst; | |
84 | if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) { | 83 | if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) { | |
85 | aprint_error(": couldn't map registers\n"); | 84 | aprint_error(": couldn't map registers\n"); | |
86 | return; | 85 | return; | |
87 | } | 86 | } | |
88 | 87 | |||
89 | aprint_naive("\n"); | 88 | aprint_naive("\n"); | |
90 | aprint_normal(": AMD CCP\n"); | 89 | aprint_normal(": AMD CCP\n"); | |
91 | 90 | |||
92 | amdccp_common_attach(sc); | 91 | amdccp_common_attach(sc); | |
93 | } | 92 | } |
--- src/sys/dev/fdt/panel_fdt.c 2021/01/18 02:35:49 1.3
+++ src/sys/dev/fdt/panel_fdt.c 2021/01/25 14:25:09 1.4
@@ -1,193 +1,192 @@ | @@ -1,193 +1,192 @@ | |||
1 | /* $NetBSD: panel_fdt.c,v 1.3 2021/01/18 02:35:49 thorpej Exp $ */ | 1 | /* $NetBSD: panel_fdt.c,v 1.4 2021/01/25 14:25:09 thorpej Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2018 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2018 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 Manuel Bouyer. | 8 | * by Manuel Bouyer. | |
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. | |
15 | * 2. Redistributions in binary form must reproduce the above copyright | 15 | * 2. Redistributions in binary form must reproduce the above copyright | |
16 | * notice, this list of conditions and the following disclaimer in the | 16 | * notice, this list of conditions and the following disclaimer in the | |
17 | * documentation and/or other materials provided with the distribution. | 17 | * documentation and/or other materials provided with the distribution. | |
18 | * | 18 | * | |
19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | 19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | |
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
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 | /* | 32 | /* | |
33 | * lvds panel driver. | 33 | * lvds panel driver. | |
34 | * specified in linux/Documentation/devicetree/bindings/display/panel/ | 34 | * specified in linux/Documentation/devicetree/bindings/display/panel/ | |
35 | * Simple RGB panels could be added as well | 35 | * Simple RGB panels could be added as well | |
36 | * registers an endpoint for use by graphic controller drivers | 36 | * registers an endpoint for use by graphic controller drivers | |
37 | * | 37 | * | |
38 | */ | 38 | */ | |
39 | 39 | |||
40 | #include <sys/cdefs.h> | 40 | #include <sys/cdefs.h> | |
41 | 41 | |||
42 | __KERNEL_RCSID(1, "$NetBSD: panel_fdt.c,v 1.3 2021/01/18 02:35:49 thorpej Exp $"); | 42 | __KERNEL_RCSID(1, "$NetBSD: panel_fdt.c,v 1.4 2021/01/25 14:25:09 thorpej Exp $"); | |
43 | 43 | |||
44 | #include <sys/param.h> | 44 | #include <sys/param.h> | |
45 | #include <sys/systm.h> | 45 | #include <sys/systm.h> | |
46 | #include <sys/device.h> | 46 | #include <sys/device.h> | |
47 | #include <sys/bus.h> | 47 | #include <sys/bus.h> | |
48 | #include <sys/gpio.h> | 48 | #include <sys/gpio.h> | |
49 | 49 | |||
50 | #include <dev/fdt/fdtvar.h> | 50 | #include <dev/fdt/fdtvar.h> | |
51 | #include <dev/fdt/panel_fdt.h> | 51 | #include <dev/fdt/panel_fdt.h> | |
52 | 52 | |||
53 | static int fdt_panel_match(device_t, cfdata_t, void *); | 53 | static int fdt_panel_match(device_t, cfdata_t, void *); | |
54 | static void fdt_panel_attach(device_t, device_t, void *); | 54 | static void fdt_panel_attach(device_t, device_t, void *); | |
55 | static void *fdt_panel_get_data(device_t, struct fdt_endpoint *); | 55 | static void *fdt_panel_get_data(device_t, struct fdt_endpoint *); | |
56 | static int fdt_panel_enable(device_t, struct fdt_endpoint *, bool); | 56 | static int fdt_panel_enable(device_t, struct fdt_endpoint *, bool); | |
57 | 57 | |||
58 | struct fdt_panel_softc { | 58 | struct fdt_panel_softc { | |
59 | device_t sc_dev; | 59 | device_t sc_dev; | |
60 | int sc_phandle; | 60 | int sc_phandle; | |
61 | struct fdt_panel sc_panel; | 61 | struct fdt_panel sc_panel; | |
62 | struct fdt_device_ports sc_ports; | 62 | struct fdt_device_ports sc_ports; | |
63 | #define MAX_GPIO_ENABLES 8 | 63 | #define MAX_GPIO_ENABLES 8 | |
64 | struct fdtbus_gpio_pin *sc_gpios_enable[MAX_GPIO_ENABLES]; | 64 | struct fdtbus_gpio_pin *sc_gpios_enable[MAX_GPIO_ENABLES]; | |
65 | }; | 65 | }; | |
66 | 66 | |||
67 | 67 | |||
68 | CFATTACH_DECL_NEW(fdt_panel, sizeof(struct fdt_panel_softc), | 68 | CFATTACH_DECL_NEW(fdt_panel, sizeof(struct fdt_panel_softc), | |
69 | fdt_panel_match, fdt_panel_attach, NULL, NULL); | 69 | fdt_panel_match, fdt_panel_attach, NULL, NULL); | |
70 | 70 | |||
71 | static const struct device_compatible_entry compat_data[] = { | 71 | static const struct device_compatible_entry compat_data[] = { | |
72 | { .compat = "panel-lvds", .value = PANEL_LVDS}, | 72 | { .compat = "panel-lvds", .value = PANEL_LVDS}, | |
73 | { .compat = "panel-dual-lvds", .value = PANEL_DUAL_LVDS}, | 73 | { .compat = "panel-dual-lvds", .value = PANEL_DUAL_LVDS}, | |
74 | 74 | { } | ||
75 | { 0 } | |||
76 | }; | 75 | }; | |
77 | 76 | |||
78 | static int | 77 | static int | |
79 | fdt_panel_match(device_t parent, cfdata_t cf, void *aux) | 78 | fdt_panel_match(device_t parent, cfdata_t cf, void *aux) | |
80 | { | 79 | { | |
81 | const struct fdt_attach_args *faa = aux; | 80 | const struct fdt_attach_args *faa = aux; | |
82 | 81 | |||
83 | return of_match_compat_data(faa->faa_phandle, compat_data); | 82 | return of_match_compat_data(faa->faa_phandle, compat_data); | |
84 | } | 83 | } | |
85 | 84 | |||
86 | static void | 85 | static void | |
87 | fdt_panel_attach(device_t parent, device_t self, void *aux) | 86 | fdt_panel_attach(device_t parent, device_t self, void *aux) | |
88 | { | 87 | { | |
89 | struct fdt_panel_softc *sc = device_private(self); | 88 | struct fdt_panel_softc *sc = device_private(self); | |
90 | const struct fdt_attach_args * const faa = aux; | 89 | const struct fdt_attach_args * const faa = aux; | |
91 | const int phandle = faa->faa_phandle; | 90 | const int phandle = faa->faa_phandle; | |
92 | const struct display_timing * const timing = | 91 | const struct display_timing * const timing = | |
93 | &sc->sc_panel.panel_timing; | 92 | &sc->sc_panel.panel_timing; | |
94 | int child; | 93 | int child; | |
95 | char buf[16]; | 94 | char buf[16]; | |
96 | const char *val; | 95 | const char *val; | |
97 | int i; | 96 | int i; | |
98 | 97 | |||
99 | sc->sc_dev = self; | 98 | sc->sc_dev = self; | |
100 | sc->sc_phandle = phandle; | 99 | sc->sc_phandle = phandle; | |
101 | sc->sc_panel.panel_type = | 100 | sc->sc_panel.panel_type = | |
102 | of_search_compatible(phandle, compat_data)->value; | 101 | of_search_compatible(phandle, compat_data)->value; | |
103 | 102 | |||
104 | if (of_getprop_uint32(phandle, "width-mm", &sc->sc_panel.panel_width) || | 103 | if (of_getprop_uint32(phandle, "width-mm", &sc->sc_panel.panel_width) || | |
105 | of_getprop_uint32(phandle, "height-mm", &sc->sc_panel.panel_height)){ | 104 | of_getprop_uint32(phandle, "height-mm", &sc->sc_panel.panel_height)){ | |
106 | aprint_error(": missing width-mm or height-mm properties\n"); | 105 | aprint_error(": missing width-mm or height-mm properties\n"); | |
107 | return; | 106 | return; | |
108 | } | 107 | } | |
109 | for (child = OF_child(phandle); child; child = OF_peer(child)) { | 108 | for (child = OF_child(phandle); child; child = OF_peer(child)) { | |
110 | if (OF_getprop(child, "name", buf, sizeof(buf)) <= 0) | 109 | if (OF_getprop(child, "name", buf, sizeof(buf)) <= 0) | |
111 | continue; | 110 | continue; | |
112 | if (strcmp(buf, "panel-timing") != 0) | 111 | if (strcmp(buf, "panel-timing") != 0) | |
113 | continue; | 112 | continue; | |
114 | 113 | |||
115 | if (display_timing_parse(child, | 114 | if (display_timing_parse(child, | |
116 | &sc->sc_panel.panel_timing) != 0) { | 115 | &sc->sc_panel.panel_timing) != 0) { | |
117 | aprint_error(": failed to parse panel-timing\n"); | 116 | aprint_error(": failed to parse panel-timing\n"); | |
118 | return; | 117 | return; | |
119 | } | 118 | } | |
120 | } | 119 | } | |
121 | if (sc->sc_panel.panel_timing.clock_freq == 0) { | 120 | if (sc->sc_panel.panel_timing.clock_freq == 0) { | |
122 | aprint_error(": missing panel-timing\n"); | 121 | aprint_error(": missing panel-timing\n"); | |
123 | return; | 122 | return; | |
124 | } | 123 | } | |
125 | switch(sc->sc_panel.panel_type) { | 124 | switch(sc->sc_panel.panel_type) { | |
126 | case PANEL_LVDS: | 125 | case PANEL_LVDS: | |
127 | case PANEL_DUAL_LVDS: | 126 | case PANEL_DUAL_LVDS: | |
128 | val = fdtbus_get_string(phandle, "data-mapping"); | 127 | val = fdtbus_get_string(phandle, "data-mapping"); | |
129 | if (val == NULL) { | 128 | if (val == NULL) { | |
130 | aprint_error(": missing data-mapping\n"); | 129 | aprint_error(": missing data-mapping\n"); | |
131 | return; | 130 | return; | |
132 | } | 131 | } | |
133 | if (strcmp(val, "jeida-18") == 0) | 132 | if (strcmp(val, "jeida-18") == 0) | |
134 | sc->sc_panel.panel_lvds_format = LVDS_JEIDA_18; | 133 | sc->sc_panel.panel_lvds_format = LVDS_JEIDA_18; | |
135 | else if (strcmp(val, "jeida-24") == 0) | 134 | else if (strcmp(val, "jeida-24") == 0) | |
136 | sc->sc_panel.panel_lvds_format = LVDS_JEIDA_24; | 135 | sc->sc_panel.panel_lvds_format = LVDS_JEIDA_24; | |
137 | else if (strcmp(val, "vesa-24") == 0) | 136 | else if (strcmp(val, "vesa-24") == 0) | |
138 | sc->sc_panel.panel_lvds_format = LVDS_VESA_24; | 137 | sc->sc_panel.panel_lvds_format = LVDS_VESA_24; | |
139 | else { | 138 | else { | |
140 | aprint_error(": unknown data-mapping \"%s\"\n", val); | 139 | aprint_error(": unknown data-mapping \"%s\"\n", val); | |
141 | return; | 140 | return; | |
142 | } | 141 | } | |
143 | break; | 142 | break; | |
144 | default: | 143 | default: | |
145 | panic("unknown panel type %d", sc->sc_panel.panel_type); | 144 | panic("unknown panel type %d", sc->sc_panel.panel_type); | |
146 | } | 145 | } | |
147 | 146 | |||
148 | aprint_naive("\n"); | 147 | aprint_naive("\n"); | |
149 | aprint_normal(": %dx%d", timing->hactive, timing->vactive); | 148 | aprint_normal(": %dx%d", timing->hactive, timing->vactive); | |
150 | switch(sc->sc_panel.panel_type) { | 149 | switch(sc->sc_panel.panel_type) { | |
151 | case PANEL_LVDS: | 150 | case PANEL_LVDS: | |
152 | aprint_normal(" LVDS"); | 151 | aprint_normal(" LVDS"); | |
153 | break; | 152 | break; | |
154 | case PANEL_DUAL_LVDS: | 153 | case PANEL_DUAL_LVDS: | |
155 | aprint_normal(" dual-link LVDS"); | 154 | aprint_normal(" dual-link LVDS"); | |
156 | break; | 155 | break; | |
157 | default: | 156 | default: | |
158 | panic(" unknown panel type %d", sc->sc_panel.panel_type); | 157 | panic(" unknown panel type %d", sc->sc_panel.panel_type); | |
159 | } | 158 | } | |
160 | aprint_normal(" panel\n"); | 159 | aprint_normal(" panel\n"); | |
161 | 160 | |||
162 | for (i = 0; i < MAX_GPIO_ENABLES ; i++) { | 161 | for (i = 0; i < MAX_GPIO_ENABLES ; i++) { | |
163 | sc->sc_gpios_enable[i] = fdtbus_gpio_acquire_index(phandle, | 162 | sc->sc_gpios_enable[i] = fdtbus_gpio_acquire_index(phandle, | |
164 | "enable-gpios", i, GPIO_PIN_OUTPUT); | 163 | "enable-gpios", i, GPIO_PIN_OUTPUT); | |
165 | if (sc->sc_gpios_enable[i] == NULL) | 164 | if (sc->sc_gpios_enable[i] == NULL) | |
166 | break; | 165 | break; | |
167 | } | 166 | } | |
168 | 167 | |||
169 | aprint_verbose_dev(self, "%d enable GPIO%c\n", i, i > 1 ? 's' : ' '); | 168 | aprint_verbose_dev(self, "%d enable GPIO%c\n", i, i > 1 ? 's' : ' '); | |
170 | 169 | |||
171 | sc->sc_ports.dp_ep_get_data = fdt_panel_get_data; | 170 | sc->sc_ports.dp_ep_get_data = fdt_panel_get_data; | |
172 | sc->sc_ports.dp_ep_enable = fdt_panel_enable; | 171 | sc->sc_ports.dp_ep_enable = fdt_panel_enable; | |
173 | fdt_ports_register(&sc->sc_ports, self, phandle, EP_PANEL); | 172 | fdt_ports_register(&sc->sc_ports, self, phandle, EP_PANEL); | |
174 | } | 173 | } | |
175 | 174 | |||
176 | static void * | 175 | static void * | |
177 | fdt_panel_get_data(device_t dev, struct fdt_endpoint *ep) | 176 | fdt_panel_get_data(device_t dev, struct fdt_endpoint *ep) | |
178 | { | 177 | { | |
179 | struct fdt_panel_softc *sc = device_private(dev); | 178 | struct fdt_panel_softc *sc = device_private(dev); | |
180 | return &sc->sc_panel; | 179 | return &sc->sc_panel; | |
181 | } | 180 | } | |
182 | 181 | |||
183 | static int | 182 | static int | |
184 | fdt_panel_enable(device_t dev, struct fdt_endpoint *ep, bool enable) | 183 | fdt_panel_enable(device_t dev, struct fdt_endpoint *ep, bool enable) | |
185 | { | 184 | { | |
186 | struct fdt_panel_softc *sc = device_private(dev); | 185 | struct fdt_panel_softc *sc = device_private(dev); | |
187 | for (int i = 0; i < MAX_GPIO_ENABLES ; i++) { | 186 | for (int i = 0; i < MAX_GPIO_ENABLES ; i++) { | |
188 | if (sc->sc_gpios_enable[i] == NULL) | 187 | if (sc->sc_gpios_enable[i] == NULL) | |
189 | break; | 188 | break; | |
190 | fdtbus_gpio_write(sc->sc_gpios_enable[i], enable); | 189 | fdtbus_gpio_write(sc->sc_gpios_enable[i], enable); | |
191 | } | 190 | } | |
192 | return 0; | 191 | return 0; | |
193 | } | 192 | } |
--- src/sys/dev/fdt/connector_fdt.c 2021/01/18 02:35:49 1.2
+++ src/sys/dev/fdt/connector_fdt.c 2021/01/25 14:25:09 1.3
@@ -1,130 +1,129 @@ | @@ -1,130 +1,129 @@ | |||
1 | /* $NetBSD: connector_fdt.c,v 1.2 2021/01/18 02:35:49 thorpej Exp $ */ | 1 | /* $NetBSD: connector_fdt.c,v 1.3 2021/01/25 14:25:09 thorpej Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2018 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2018 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 Manuel Bouyer. | 8 | * by Manuel Bouyer. | |
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. | |
15 | * 2. Redistributions in binary form must reproduce the above copyright | 15 | * 2. Redistributions in binary form must reproduce the above copyright | |
16 | * notice, this list of conditions and the following disclaimer in the | 16 | * notice, this list of conditions and the following disclaimer in the | |
17 | * documentation and/or other materials provided with the distribution. | 17 | * documentation and/or other materials provided with the distribution. | |
18 | * | 18 | * | |
19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | 19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | |
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
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 | /* | 32 | /* | |
33 | * connector driver. | 33 | * connector driver. | |
34 | * specified in linux/Documentation/devicetree/bindings/display/connector/ | 34 | * specified in linux/Documentation/devicetree/bindings/display/connector/ | |
35 | * basically it only register its endpoint. | 35 | * basically it only register its endpoint. | |
36 | */ | 36 | */ | |
37 | 37 | |||
38 | #include <sys/cdefs.h> | 38 | #include <sys/cdefs.h> | |
39 | 39 | |||
40 | __KERNEL_RCSID(1, "$NetBSD: connector_fdt.c,v 1.2 2021/01/18 02:35:49 thorpej Exp $"); | 40 | __KERNEL_RCSID(1, "$NetBSD: connector_fdt.c,v 1.3 2021/01/25 14:25:09 thorpej Exp $"); | |
41 | 41 | |||
42 | #include <sys/param.h> | 42 | #include <sys/param.h> | |
43 | #include <sys/systm.h> | 43 | #include <sys/systm.h> | |
44 | #include <sys/device.h> | 44 | #include <sys/device.h> | |
45 | #include <sys/bus.h> | 45 | #include <sys/bus.h> | |
46 | #include <sys/kmem.h> | 46 | #include <sys/kmem.h> | |
47 | 47 | |||
48 | #include <dev/fdt/fdtvar.h> | 48 | #include <dev/fdt/fdtvar.h> | |
49 | #include <dev/fdt/fdt_port.h> | 49 | #include <dev/fdt/fdt_port.h> | |
50 | #include <dev/fdt/connector_fdt.h> | 50 | #include <dev/fdt/connector_fdt.h> | |
51 | 51 | |||
52 | static int fdt_connector_match(device_t, cfdata_t, void *); | 52 | static int fdt_connector_match(device_t, cfdata_t, void *); | |
53 | static void fdt_connector_attach(device_t, device_t, void *); | 53 | static void fdt_connector_attach(device_t, device_t, void *); | |
54 | static void *fdt_connector_get_data(device_t, struct fdt_endpoint *); | 54 | static void *fdt_connector_get_data(device_t, struct fdt_endpoint *); | |
55 | 55 | |||
56 | SLIST_HEAD(, fdt_connector_softc) fdt_connectors = | 56 | SLIST_HEAD(, fdt_connector_softc) fdt_connectors = | |
57 | SLIST_HEAD_INITIALIZER(&fdt_connectors); | 57 | SLIST_HEAD_INITIALIZER(&fdt_connectors); | |
58 | 58 | |||
59 | struct fdt_connector_softc { | 59 | struct fdt_connector_softc { | |
60 | device_t sc_dev; | 60 | device_t sc_dev; | |
61 | int sc_phandle; | 61 | int sc_phandle; | |
62 | struct fdt_connector sc_con; | 62 | struct fdt_connector sc_con; | |
63 | SLIST_ENTRY(fdt_connector_softc) sc_list; | 63 | SLIST_ENTRY(fdt_connector_softc) sc_list; | |
64 | struct fdt_device_ports sc_ports; | 64 | struct fdt_device_ports sc_ports; | |
65 | }; | 65 | }; | |
66 | 66 | |||
67 | #define sc_type sc_con.con_type | 67 | #define sc_type sc_con.con_type | |
68 | 68 | |||
69 | CFATTACH_DECL_NEW(fdt_connector, sizeof(struct fdt_connector_softc), | 69 | CFATTACH_DECL_NEW(fdt_connector, sizeof(struct fdt_connector_softc), | |
70 | fdt_connector_match, fdt_connector_attach, NULL, NULL); | 70 | fdt_connector_match, fdt_connector_attach, NULL, NULL); | |
71 | 71 | |||
72 | static const struct device_compatible_entry compat_data[] = { | 72 | static const struct device_compatible_entry compat_data[] = { | |
73 | { .compat = "composite-video-connector", .value = CON_TV}, | 73 | { .compat = "composite-video-connector", .value = CON_TV}, | |
74 | { .compat = "dvi-connector", .value = CON_DVI}, | 74 | { .compat = "dvi-connector", .value = CON_DVI}, | |
75 | { .compat = "hdmi-connector", .value = CON_HDMI}, | 75 | { .compat = "hdmi-connector", .value = CON_HDMI}, | |
76 | { .compat = "vga-connector", .value = CON_VGA}, | 76 | { .compat = "vga-connector", .value = CON_VGA}, | |
77 | 77 | { } | ||
78 | { 0 } | |||
79 | }; | 78 | }; | |
80 | 79 | |||
81 | static int | 80 | static int | |
82 | fdt_connector_match(device_t parent, cfdata_t cf, void *aux) | 81 | fdt_connector_match(device_t parent, cfdata_t cf, void *aux) | |
83 | { | 82 | { | |
84 | const struct fdt_attach_args *faa = aux; | 83 | const struct fdt_attach_args *faa = aux; | |
85 | 84 | |||
86 | return of_match_compat_data(faa->faa_phandle, compat_data); | 85 | return of_match_compat_data(faa->faa_phandle, compat_data); | |
87 | } | 86 | } | |
88 | 87 | |||
89 | static void | 88 | static void | |
90 | fdt_connector_attach(device_t parent, device_t self, void *aux) | 89 | fdt_connector_attach(device_t parent, device_t self, void *aux) | |
91 | { | 90 | { | |
92 | struct fdt_connector_softc *sc = device_private(self); | 91 | struct fdt_connector_softc *sc = device_private(self); | |
93 | const struct fdt_attach_args * const faa = aux; | 92 | const struct fdt_attach_args * const faa = aux; | |
94 | const int phandle = faa->faa_phandle; | 93 | const int phandle = faa->faa_phandle; | |
95 | 94 | |||
96 | sc->sc_dev = self; | 95 | sc->sc_dev = self; | |
97 | sc->sc_phandle = phandle; | 96 | sc->sc_phandle = phandle; | |
98 | sc->sc_type = of_search_compatible(phandle, compat_data)->value; | 97 | sc->sc_type = of_search_compatible(phandle, compat_data)->value; | |
99 | 98 | |||
100 | SLIST_INSERT_HEAD(&fdt_connectors, sc, sc_list); | 99 | SLIST_INSERT_HEAD(&fdt_connectors, sc, sc_list); | |
101 | 100 | |||
102 | aprint_naive("\n"); | 101 | aprint_naive("\n"); | |
103 | switch(sc->sc_type) { | 102 | switch(sc->sc_type) { | |
104 | case CON_VGA: | 103 | case CON_VGA: | |
105 | aprint_normal(": VGA"); | 104 | aprint_normal(": VGA"); | |
106 | break; | 105 | break; | |
107 | case CON_DVI: | 106 | case CON_DVI: | |
108 | aprint_normal(": DVI"); | 107 | aprint_normal(": DVI"); | |
109 | break; | 108 | break; | |
110 | case CON_HDMI: | 109 | case CON_HDMI: | |
111 | aprint_normal(": HDMI"); | 110 | aprint_normal(": HDMI"); | |
112 | break; | 111 | break; | |
113 | case CON_TV: | 112 | case CON_TV: | |
114 | aprint_normal(": composite"); | 113 | aprint_normal(": composite"); | |
115 | break; | 114 | break; | |
116 | default: | 115 | default: | |
117 | panic("unknown connector type %d\n", sc->sc_type); | 116 | panic("unknown connector type %d\n", sc->sc_type); | |
118 | } | 117 | } | |
119 | aprint_normal(" connector\n"); | 118 | aprint_normal(" connector\n"); | |
120 | sc->sc_ports.dp_ep_get_data = fdt_connector_get_data; | 119 | sc->sc_ports.dp_ep_get_data = fdt_connector_get_data; | |
121 | fdt_ports_register(&sc->sc_ports, self, phandle, EP_CONNECTOR); | 120 | fdt_ports_register(&sc->sc_ports, self, phandle, EP_CONNECTOR); | |
122 | } | 121 | } | |
123 | 122 | |||
124 | static void * | 123 | static void * | |
125 | fdt_connector_get_data(device_t dev, struct fdt_endpoint *ep) | 124 | fdt_connector_get_data(device_t dev, struct fdt_endpoint *ep) | |
126 | { | 125 | { | |
127 | struct fdt_connector_softc *sc = device_private(dev); | 126 | struct fdt_connector_softc *sc = device_private(dev); | |
128 | 127 | |||
129 | return &sc->sc_con; | 128 | return &sc->sc_con; | |
130 | } | 129 | } |
--- src/sys/dev/fdt/pinctrl_single.c 2021/01/18 02:35:49 1.2
+++ src/sys/dev/fdt/pinctrl_single.c 2021/01/25 14:25:09 1.3
@@ -1,205 +1,204 @@ | @@ -1,205 +1,204 @@ | |||
1 | /* $NetBSD: pinctrl_single.c,v 1.2 2021/01/18 02:35:49 thorpej Exp $ */ | 1 | /* $NetBSD: pinctrl_single.c,v 1.3 2021/01/25 14:25:09 thorpej Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2019 Jared McNeill <jmcneill@invisible.ca> | 4 | * Copyright (c) 2019 Jared 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. | |
15 | * | 15 | * | |
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 <sys/cdefs.h> | 29 | #include <sys/cdefs.h> | |
30 | __KERNEL_RCSID(0, "$NetBSD: pinctrl_single.c,v 1.2 2021/01/18 02:35:49 thorpej Exp $"); | 30 | __KERNEL_RCSID(0, "$NetBSD: pinctrl_single.c,v 1.3 2021/01/25 14:25:09 thorpej 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/systm.h> | 35 | #include <sys/systm.h> | |
36 | #include <sys/gpio.h> | 36 | #include <sys/gpio.h> | |
37 | 37 | |||
38 | #include <dev/fdt/fdtvar.h> | 38 | #include <dev/fdt/fdtvar.h> | |
39 | 39 | |||
40 | #define PINCTRL_FLAG_PINCONF __BIT(0) /* supports generic pinconf */ | 40 | #define PINCTRL_FLAG_PINCONF __BIT(0) /* supports generic pinconf */ | |
41 | 41 | |||
42 | struct pinctrl_single_config { | 42 | struct pinctrl_single_config { | |
43 | uint32_t flags; | 43 | uint32_t flags; | |
44 | }; | 44 | }; | |
45 | 45 | |||
46 | static const struct pinctrl_single_config pinctrl_config = { | 46 | static const struct pinctrl_single_config pinctrl_config = { | |
47 | }; | 47 | }; | |
48 | 48 | |||
49 | static const struct pinctrl_single_config pinconf_config = { | 49 | static const struct pinctrl_single_config pinconf_config = { | |
50 | .flags = PINCTRL_FLAG_PINCONF | 50 | .flags = PINCTRL_FLAG_PINCONF | |
51 | }; | 51 | }; | |
52 | 52 | |||
53 | static const struct device_compatible_entry compat_data[] = { | 53 | static const struct device_compatible_entry compat_data[] = { | |
54 | { .compat = "pinctrl-single", .data = &pinctrl_config }, | 54 | { .compat = "pinctrl-single", .data = &pinctrl_config }, | |
55 | { .compat = "pinconf-single", .data = &pinconf_config }, | 55 | { .compat = "pinconf-single", .data = &pinconf_config }, | |
56 | 56 | { } | ||
57 | { 0 } | |||
58 | }; | 57 | }; | |
59 | 58 | |||
60 | struct pinctrl_single_softc { | 59 | struct pinctrl_single_softc { | |
61 | device_t sc_dev; | 60 | device_t sc_dev; | |
62 | int sc_phandle; | 61 | int sc_phandle; | |
63 | bus_space_tag_t sc_bst; | 62 | bus_space_tag_t sc_bst; | |
64 | bus_space_handle_t sc_bsh; | 63 | bus_space_handle_t sc_bsh; | |
65 | uint32_t sc_flags; | 64 | uint32_t sc_flags; | |
66 | u_int sc_regwidth; | 65 | u_int sc_regwidth; | |
67 | u_int sc_funcmask; | 66 | u_int sc_funcmask; | |
68 | }; | 67 | }; | |
69 | 68 | |||
70 | static void | 69 | static void | |
71 | pinctrl_single_pins_write(struct pinctrl_single_softc *sc, u_int off, u_int val) | 70 | pinctrl_single_pins_write(struct pinctrl_single_softc *sc, u_int off, u_int val) | |
72 | { | 71 | { | |
73 | union { | 72 | union { | |
74 | uint32_t reg32; | 73 | uint32_t reg32; | |
75 | uint16_t reg16; | 74 | uint16_t reg16; | |
76 | uint8_t reg8; | 75 | uint8_t reg8; | |
77 | } u; | 76 | } u; | |
78 | 77 | |||
79 | aprint_debug_dev(sc->sc_dev, "writing %#x with %#x\n", off, val); | 78 | aprint_debug_dev(sc->sc_dev, "writing %#x with %#x\n", off, val); | |
80 | 79 | |||
81 | switch (sc->sc_regwidth) { | 80 | switch (sc->sc_regwidth) { | |
82 | case 8: | 81 | case 8: | |
83 | u.reg8 = bus_space_read_1(sc->sc_bst, sc->sc_bsh, off); | 82 | u.reg8 = bus_space_read_1(sc->sc_bst, sc->sc_bsh, off); | |
84 | u.reg8 &= ~sc->sc_funcmask; | 83 | u.reg8 &= ~sc->sc_funcmask; | |
85 | u.reg8 |= val; | 84 | u.reg8 |= val; | |
86 | bus_space_write_1(sc->sc_bst, sc->sc_bsh, off, u.reg8); | 85 | bus_space_write_1(sc->sc_bst, sc->sc_bsh, off, u.reg8); | |
87 | break; | 86 | break; | |
88 | case 16: | 87 | case 16: | |
89 | u.reg16 = bus_space_read_2(sc->sc_bst, sc->sc_bsh, off); | 88 | u.reg16 = bus_space_read_2(sc->sc_bst, sc->sc_bsh, off); | |
90 | u.reg16 &= ~sc->sc_funcmask; | 89 | u.reg16 &= ~sc->sc_funcmask; | |
91 | u.reg16 |= val; | 90 | u.reg16 |= val; | |
92 | bus_space_write_2(sc->sc_bst, sc->sc_bsh, off, u.reg16); | 91 | bus_space_write_2(sc->sc_bst, sc->sc_bsh, off, u.reg16); | |
93 | break; | 92 | break; | |
94 | case 32: | 93 | case 32: | |
95 | u.reg32 = bus_space_read_4(sc->sc_bst, sc->sc_bsh, off); | 94 | u.reg32 = bus_space_read_4(sc->sc_bst, sc->sc_bsh, off); | |
96 | u.reg32 &= ~sc->sc_funcmask; | 95 | u.reg32 &= ~sc->sc_funcmask; | |
97 | u.reg32 |= val; | 96 | u.reg32 |= val; | |
98 | bus_space_write_4(sc->sc_bst, sc->sc_bsh, off, u.reg32); | 97 | bus_space_write_4(sc->sc_bst, sc->sc_bsh, off, u.reg32); | |
99 | break; | 98 | break; | |
100 | default: | 99 | default: | |
101 | device_printf(sc->sc_dev, "%s: unsupported reg width %d\n", | 100 | device_printf(sc->sc_dev, "%s: unsupported reg width %d\n", | |
102 | __func__, sc->sc_regwidth); | 101 | __func__, sc->sc_regwidth); | |
103 | break; | 102 | break; | |
104 | } | 103 | } | |
105 | } | 104 | } | |
106 | 105 | |||
107 | static int | 106 | static int | |
108 | pinctrl_single_pins_set_config(device_t dev, const void *data, size_t len) | 107 | pinctrl_single_pins_set_config(device_t dev, const void *data, size_t len) | |
109 | { | 108 | { | |
110 | struct pinctrl_single_softc * const sc = device_private(dev); | 109 | struct pinctrl_single_softc * const sc = device_private(dev); | |
111 | const u_int *pins; | 110 | const u_int *pins; | |
112 | int pinslen; | 111 | int pinslen; | |
113 | 112 | |||
114 | if (len != 4) | 113 | if (len != 4) | |
115 | return -1; | 114 | return -1; | |
116 | 115 | |||
117 | const int phandle = fdtbus_get_phandle_from_native(be32dec(data)); | 116 | const int phandle = fdtbus_get_phandle_from_native(be32dec(data)); | |
118 | 117 | |||
119 | pins = fdtbus_get_prop(phandle, "pinctrl-single,pins", &pinslen); | 118 | pins = fdtbus_get_prop(phandle, "pinctrl-single,pins", &pinslen); | |
120 | if (pins == NULL) | 119 | if (pins == NULL) | |
121 | return -1; | 120 | return -1; | |
122 | 121 | |||
123 | while (pinslen >= 8) { | 122 | while (pinslen >= 8) { | |
124 | const int off = be32toh(pins[0]); | 123 | const int off = be32toh(pins[0]); | |
125 | const int val = be32toh(pins[1]); | 124 | const int val = be32toh(pins[1]); | |
126 | 125 | |||
127 | pinctrl_single_pins_write(sc, off, val); | 126 | pinctrl_single_pins_write(sc, off, val); | |
128 | pins += 2; | 127 | pins += 2; | |
129 | pinslen -= 8; | 128 | pinslen -= 8; | |
130 | } | 129 | } | |
131 | 130 | |||
132 | return 0; | 131 | return 0; | |
133 | } | 132 | } | |
134 | 133 | |||
135 | static struct fdtbus_pinctrl_controller_func pinctrl_single_pins_funcs = { | 134 | static struct fdtbus_pinctrl_controller_func pinctrl_single_pins_funcs = { | |
136 | .set_config = pinctrl_single_pins_set_config, | 135 | .set_config = pinctrl_single_pins_set_config, | |
137 | }; | 136 | }; | |
138 | 137 | |||
139 | static int | 138 | static int | |
140 | pinctrl_single_match(device_t parent, cfdata_t cf, void *aux) | 139 | pinctrl_single_match(device_t parent, cfdata_t cf, void *aux) | |
141 | { | 140 | { | |
142 | struct fdt_attach_args * const faa = aux; | 141 | struct fdt_attach_args * const faa = aux; | |
143 | 142 | |||
144 | return of_match_compat_data(faa->faa_phandle, compat_data); | 143 | return of_match_compat_data(faa->faa_phandle, compat_data); | |
145 | } | 144 | } | |
146 | 145 | |||
147 | static void | 146 | static void | |
148 | pinctrl_single_attach(device_t parent, device_t self, void *aux) | 147 | pinctrl_single_attach(device_t parent, device_t self, void *aux) | |
149 | { | 148 | { | |
150 | struct pinctrl_single_softc * const sc = device_private(self); | 149 | struct pinctrl_single_softc * const sc = device_private(self); | |
151 | struct fdt_attach_args * const faa = aux; | 150 | struct fdt_attach_args * const faa = aux; | |
152 | const int phandle = faa->faa_phandle; | 151 | const int phandle = faa->faa_phandle; | |
153 | const struct pinctrl_single_config *conf; | 152 | const struct pinctrl_single_config *conf; | |
154 | bus_addr_t addr; | 153 | bus_addr_t addr; | |
155 | bus_size_t size; | 154 | bus_size_t size; | |
156 | int child; | 155 | int child; | |
157 | 156 | |||
158 | if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { | 157 | if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { | |
159 | aprint_error(": couldn't get registers\n"); | 158 | aprint_error(": couldn't get registers\n"); | |
160 | return; | 159 | return; | |
161 | } | 160 | } | |
162 | 161 | |||
163 | conf = of_search_compatible(phandle, compat_data)->data; | 162 | conf = of_search_compatible(phandle, compat_data)->data; | |
164 | 163 | |||
165 | sc->sc_dev = self; | 164 | sc->sc_dev = self; | |
166 | sc->sc_phandle = phandle; | 165 | sc->sc_phandle = phandle; | |
167 | sc->sc_bst = faa->faa_bst; | 166 | sc->sc_bst = faa->faa_bst; | |
168 | if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) { | 167 | if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) { | |
169 | aprint_error(": couldn't map registers\n"); | 168 | aprint_error(": couldn't map registers\n"); | |
170 | return; | 169 | return; | |
171 | } | 170 | } | |
172 | sc->sc_flags = conf->flags; | 171 | sc->sc_flags = conf->flags; | |
173 | 172 | |||
174 | if (of_getprop_uint32(phandle, "pinctrl-single,register-width", &sc->sc_regwidth) != 0) { | 173 | if (of_getprop_uint32(phandle, "pinctrl-single,register-width", &sc->sc_regwidth) != 0) { | |
175 | aprint_error(": missing 'pinctrl-single,register-width' property\n"); | 174 | aprint_error(": missing 'pinctrl-single,register-width' property\n"); | |
176 | return; | 175 | return; | |
177 | } | 176 | } | |
178 | if (of_getprop_uint32(phandle, "pinctrl-single,function-mask", &sc->sc_funcmask) != 0) { | 177 | if (of_getprop_uint32(phandle, "pinctrl-single,function-mask", &sc->sc_funcmask) != 0) { | |
179 | aprint_error(": missing 'pinctrl-single,function-mask' property\n"); | 178 | aprint_error(": missing 'pinctrl-single,function-mask' property\n"); | |
180 | return; | 179 | return; | |
181 | } | 180 | } | |
182 | 181 | |||
183 | switch (sc->sc_regwidth) { | 182 | switch (sc->sc_regwidth) { | |
184 | case 8: | 183 | case 8: | |
185 | case 16: | 184 | case 16: | |
186 | case 32: | 185 | case 32: | |
187 | break; | 186 | break; | |
188 | default: | 187 | default: | |
189 | aprint_error(": register width %d not supported\n", sc->sc_regwidth); | 188 | aprint_error(": register width %d not supported\n", sc->sc_regwidth); | |
190 | return; | 189 | return; | |
191 | } | 190 | } | |
192 | 191 | |||
193 | aprint_naive("\n"); | 192 | aprint_naive("\n"); | |
194 | aprint_normal("\n"); | 193 | aprint_normal("\n"); | |
195 | 194 | |||
196 | for (child = OF_child(phandle); child; child = OF_peer(child)) { | 195 | for (child = OF_child(phandle); child; child = OF_peer(child)) { | |
197 | if (of_hasprop(child, "pinctrl-single,pins")) | 196 | if (of_hasprop(child, "pinctrl-single,pins")) | |
198 | fdtbus_register_pinctrl_config(self, child, &pinctrl_single_pins_funcs); | 197 | fdtbus_register_pinctrl_config(self, child, &pinctrl_single_pins_funcs); | |
199 | } | 198 | } | |
200 | 199 | |||
201 | fdtbus_pinctrl_set_config(phandle, "default"); | 200 | fdtbus_pinctrl_set_config(phandle, "default"); | |
202 | } | 201 | } | |
203 | 202 | |||
204 | CFATTACH_DECL_NEW(pinctrl_single, sizeof(struct pinctrl_single_softc), | 203 | CFATTACH_DECL_NEW(pinctrl_single, sizeof(struct pinctrl_single_softc), | |
205 | pinctrl_single_match, pinctrl_single_attach, NULL, NULL); | 204 | pinctrl_single_match, pinctrl_single_attach, NULL, NULL); |
--- src/sys/dev/fdt/vmt_fdt.c 2021/01/18 02:35:49 1.2
+++ src/sys/dev/fdt/vmt_fdt.c 2021/01/25 14:25:09 1.3
@@ -1,72 +1,71 @@ | @@ -1,72 +1,71 @@ | |||
1 | /* $NetBSD: vmt_fdt.c,v 1.2 2021/01/18 02:35:49 thorpej Exp $ */ | 1 | /* $NetBSD: vmt_fdt.c,v 1.3 2021/01/25 14:25:09 thorpej Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2020 Ryo Shimizu <ryo@nerv.org> | 4 | * Copyright (c) 2020 Ryo Shimizu <ryo@nerv.org> | |
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. | |
15 | * | 15 | * | |
16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS | 16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS | |
17 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, | 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, | |
20 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
22 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 22 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
23 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | 23 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
24 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | 24 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
25 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 25 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
26 | * POSSIBILITY OF SUCH DAMAGE. | 26 | * POSSIBILITY OF SUCH DAMAGE. | |
27 | */ | 27 | */ | |
28 | 28 | |||
29 | #include <sys/cdefs.h> | 29 | #include <sys/cdefs.h> | |
30 | __KERNEL_RCSID(0, "$NetBSD: vmt_fdt.c,v 1.2 2021/01/18 02:35:49 thorpej Exp $"); | 30 | __KERNEL_RCSID(0, "$NetBSD: vmt_fdt.c,v 1.3 2021/01/25 14:25:09 thorpej Exp $"); | |
31 | 31 | |||
32 | #include <sys/param.h> | 32 | #include <sys/param.h> | |
33 | #include <sys/systm.h> | 33 | #include <sys/systm.h> | |
34 | #include <sys/device.h> | 34 | #include <sys/device.h> | |
35 | 35 | |||
36 | #include <dev/fdt/fdtvar.h> | 36 | #include <dev/fdt/fdtvar.h> | |
37 | #include <dev/vmt/vmtreg.h> | 37 | #include <dev/vmt/vmtreg.h> | |
38 | #include <dev/vmt/vmtvar.h> | 38 | #include <dev/vmt/vmtvar.h> | |
39 | 39 | |||
40 | static int vmt_fdt_match(device_t, cfdata_t, void *); | 40 | static int vmt_fdt_match(device_t, cfdata_t, void *); | |
41 | static void vmt_fdt_attach(device_t, device_t, void *); | 41 | static void vmt_fdt_attach(device_t, device_t, void *); | |
42 | 42 | |||
43 | CFATTACH_DECL_NEW(vmt_fdt, sizeof(struct vmt_softc), | 43 | CFATTACH_DECL_NEW(vmt_fdt, sizeof(struct vmt_softc), | |
44 | vmt_fdt_match, vmt_fdt_attach, NULL, NULL); | 44 | vmt_fdt_match, vmt_fdt_attach, NULL, NULL); | |
45 | 45 | |||
46 | static const struct device_compatible_entry compat_data[] = { | 46 | static const struct device_compatible_entry compat_data[] = { | |
47 | { .compat = "vmware" }, | 47 | { .compat = "vmware" }, | |
48 | 48 | { } | ||
49 | { 0 } | |||
50 | }; | 49 | }; | |
51 | 50 | |||
52 | static int | 51 | static int | |
53 | vmt_fdt_match(device_t parent, cfdata_t cf, void *aux) | 52 | vmt_fdt_match(device_t parent, cfdata_t cf, void *aux) | |
54 | { | 53 | { | |
55 | const struct fdt_attach_args * const faa = aux; | 54 | const struct fdt_attach_args * const faa = aux; | |
56 | 55 | |||
57 | if (OF_finddevice("/hypervisor") != faa->faa_phandle) | 56 | if (OF_finddevice("/hypervisor") != faa->faa_phandle) | |
58 | return 0; | 57 | return 0; | |
59 | return of_match_compat_data(faa->faa_phandle, compat_data); | 58 | return of_match_compat_data(faa->faa_phandle, compat_data); | |
60 | } | 59 | } | |
61 | 60 | |||
62 | static void | 61 | static void | |
63 | vmt_fdt_attach(device_t parent, device_t self, void *aux) | 62 | vmt_fdt_attach(device_t parent, device_t self, void *aux) | |
64 | { | 63 | { | |
65 | struct vmt_softc * const sc = device_private(self); | 64 | struct vmt_softc * const sc = device_private(self); | |
66 | 65 | |||
67 | aprint_naive("\n"); | 66 | aprint_naive("\n"); | |
68 | aprint_normal(": VMware Tools driver\n"); | 67 | aprint_normal(": VMware Tools driver\n"); | |
69 | 68 | |||
70 | sc->sc_dev = self; | 69 | sc->sc_dev = self; | |
71 | vmt_common_attach(sc); | 70 | vmt_common_attach(sc); | |
72 | } | 71 | } |
--- src/sys/dev/fdt/dwc2_fdt.c 2021/01/18 02:35:49 1.7
+++ src/sys/dev/fdt/dwc2_fdt.c 2021/01/25 14:25:09 1.8
@@ -1,241 +1,241 @@ | @@ -1,241 +1,241 @@ | |||
1 | /* $NetBSD: dwc2_fdt.c,v 1.7 2021/01/18 02:35:49 thorpej Exp $ */ | 1 | /* $NetBSD: dwc2_fdt.c,v 1.8 2021/01/25 14:25:09 thorpej 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 Nick Hudson | 8 | * by Nick Hudson | |
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. | |
15 | * 2. Redistributions in binary form must reproduce the above copyright | 15 | * 2. Redistributions in binary form must reproduce the above copyright | |
16 | * notice, this list of conditions and the following disclaimer in the | 16 | * notice, this list of conditions and the following disclaimer in the | |
17 | * documentation and/or other materials provided with the distribution. | 17 | * documentation and/or other materials provided with the distribution. | |
18 | * | 18 | * | |
19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | 19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | |
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
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 | __KERNEL_RCSID(0, "$NetBSD: dwc2_fdt.c,v 1.7 2021/01/18 02:35:49 thorpej Exp $"); | 33 | __KERNEL_RCSID(0, "$NetBSD: dwc2_fdt.c,v 1.8 2021/01/25 14:25:09 thorpej Exp $"); | |
34 | 34 | |||
35 | #include <sys/param.h> | 35 | #include <sys/param.h> | |
36 | #include <sys/systm.h> | 36 | #include <sys/systm.h> | |
37 | #include <sys/device.h> | 37 | #include <sys/device.h> | |
38 | #include <sys/mutex.h> | 38 | #include <sys/mutex.h> | |
39 | #include <sys/bus.h> | 39 | #include <sys/bus.h> | |
40 | #include <sys/workqueue.h> | 40 | #include <sys/workqueue.h> | |
41 | 41 | |||
42 | #include <dev/fdt/fdtvar.h> | 42 | #include <dev/fdt/fdtvar.h> | |
43 | 43 | |||
44 | #include <dev/usb/usb.h> | 44 | #include <dev/usb/usb.h> | |
45 | #include <dev/usb/usbdi.h> | 45 | #include <dev/usb/usbdi.h> | |
46 | #include <dev/usb/usbdivar.h> | 46 | #include <dev/usb/usbdivar.h> | |
47 | #include <dev/usb/usb_mem.h> | 47 | #include <dev/usb/usb_mem.h> | |
48 | 48 | |||
49 | #include <dwc2/dwc2var.h> | 49 | #include <dwc2/dwc2var.h> | |
50 | 50 | |||
51 | #include <dwc2/dwc2.h> | 51 | #include <dwc2/dwc2.h> | |
52 | #include "dwc2_core.h" | 52 | #include "dwc2_core.h" | |
53 | 53 | |||
54 | struct dwc2_fdt_softc { | 54 | struct dwc2_fdt_softc { | |
55 | struct dwc2_softc sc_dwc2; | 55 | struct dwc2_softc sc_dwc2; | |
56 | 56 | |||
57 | struct dwc2_core_params sc_params; | 57 | struct dwc2_core_params sc_params; | |
58 | 58 | |||
59 | void *sc_ih; | 59 | void *sc_ih; | |
60 | int sc_phandle; | 60 | int sc_phandle; | |
61 | }; | 61 | }; | |
62 | 62 | |||
63 | static int dwc2_fdt_match(device_t, struct cfdata *, void *); | 63 | static int dwc2_fdt_match(device_t, struct cfdata *, void *); | |
64 | static void dwc2_fdt_attach(device_t, device_t, void *); | 64 | static void dwc2_fdt_attach(device_t, device_t, void *); | |
65 | static void dwc2_fdt_deferred(device_t); | 65 | static void dwc2_fdt_deferred(device_t); | |
66 | 66 | |||
67 | static void dwc2_fdt_amlogic_params(struct dwc2_fdt_softc *, struct dwc2_core_params *); | 67 | static void dwc2_fdt_amlogic_params(struct dwc2_fdt_softc *, struct dwc2_core_params *); | |
68 | static void dwc2_fdt_rockchip_params(struct dwc2_fdt_softc *, struct dwc2_core_params *); | 68 | static void dwc2_fdt_rockchip_params(struct dwc2_fdt_softc *, struct dwc2_core_params *); | |
69 | 69 | |||
70 | struct dwc2_fdt_config { | 70 | struct dwc2_fdt_config { | |
71 | void (*params)(struct dwc2_fdt_softc *, struct dwc2_core_params *); | 71 | void (*params)(struct dwc2_fdt_softc *, struct dwc2_core_params *); | |
72 | }; | 72 | }; | |
73 | 73 | |||
74 | static const struct dwc2_fdt_config dwc2_fdt_rk3066_config = { | 74 | static const struct dwc2_fdt_config dwc2_fdt_rk3066_config = { | |
75 | .params = dwc2_fdt_rockchip_params, | 75 | .params = dwc2_fdt_rockchip_params, | |
76 | }; | 76 | }; | |
77 | 77 | |||
78 | static const struct dwc2_fdt_config dwc2_fdt_meson8b_config = { | 78 | static const struct dwc2_fdt_config dwc2_fdt_meson8b_config = { | |
79 | .params = dwc2_fdt_amlogic_params, | 79 | .params = dwc2_fdt_amlogic_params, | |
80 | }; | 80 | }; | |
81 | 81 | |||
82 | static const struct dwc2_fdt_config dwc2_fdt_generic_config = { | 82 | static const struct dwc2_fdt_config dwc2_fdt_generic_config = { | |
83 | }; | 83 | }; | |
84 | 84 | |||
85 | static const struct device_compatible_entry compat_data[] = { | 85 | static const struct device_compatible_entry compat_data[] = { | |
86 | { .compat = "amlogic,meson8b-usb", | 86 | { .compat = "amlogic,meson8b-usb", | |
87 | .data = &dwc2_fdt_meson8b_config }, | 87 | .data = &dwc2_fdt_meson8b_config }, | |
88 | { .compat = "amlogic,meson-gxbb-usb", | 88 | { .compat = "amlogic,meson-gxbb-usb", | |
89 | .data = &dwc2_fdt_meson8b_config }, | 89 | .data = &dwc2_fdt_meson8b_config }, | |
90 | { .compat = "rockchip,rk3066-usb", | 90 | { .compat = "rockchip,rk3066-usb", | |
91 | .data = &dwc2_fdt_rk3066_config }, | 91 | .data = &dwc2_fdt_rk3066_config }, | |
92 | { .compat = "snps,dwc2", | 92 | { .compat = "snps,dwc2", | |
93 | .data = &dwc2_fdt_generic_config }, | 93 | .data = &dwc2_fdt_generic_config }, | |
94 | 94 | |||
95 | { 0 } | 95 | { } | |
96 | }; | 96 | }; | |
97 | 97 | |||
98 | CFATTACH_DECL_NEW(dwc2_fdt, sizeof(struct dwc2_fdt_softc), | 98 | CFATTACH_DECL_NEW(dwc2_fdt, sizeof(struct dwc2_fdt_softc), | |
99 | dwc2_fdt_match, dwc2_fdt_attach, NULL, NULL); | 99 | dwc2_fdt_match, dwc2_fdt_attach, NULL, NULL); | |
100 | 100 | |||
101 | /* ARGSUSED */ | 101 | /* ARGSUSED */ | |
102 | static int | 102 | static int | |
103 | dwc2_fdt_match(device_t parent, struct cfdata *match, void *aux) | 103 | dwc2_fdt_match(device_t parent, struct cfdata *match, void *aux) | |
104 | { | 104 | { | |
105 | struct fdt_attach_args * const faa = aux; | 105 | struct fdt_attach_args * const faa = aux; | |
106 | 106 | |||
107 | return of_match_compat_data(faa->faa_phandle, compat_data); | 107 | return of_match_compat_data(faa->faa_phandle, compat_data); | |
108 | } | 108 | } | |
109 | 109 | |||
110 | /* ARGSUSED */ | 110 | /* ARGSUSED */ | |
111 | static void | 111 | static void | |
112 | dwc2_fdt_attach(device_t parent, device_t self, void *aux) | 112 | dwc2_fdt_attach(device_t parent, device_t self, void *aux) | |
113 | { | 113 | { | |
114 | struct dwc2_fdt_softc *sc = device_private(self); | 114 | struct dwc2_fdt_softc *sc = device_private(self); | |
115 | struct fdt_attach_args * const faa = aux; | 115 | struct fdt_attach_args * const faa = aux; | |
116 | const int phandle = faa->faa_phandle; | 116 | const int phandle = faa->faa_phandle; | |
117 | const struct dwc2_fdt_config *conf = | 117 | const struct dwc2_fdt_config *conf = | |
118 | of_search_compatible(phandle, compat_data)->data; | 118 | of_search_compatible(phandle, compat_data)->data; | |
119 | char intrstr[128]; | 119 | char intrstr[128]; | |
120 | struct fdtbus_phy *phy; | 120 | struct fdtbus_phy *phy; | |
121 | struct clk *clk; | 121 | struct clk *clk; | |
122 | bus_addr_t addr; | 122 | bus_addr_t addr; | |
123 | bus_size_t size; | 123 | bus_size_t size; | |
124 | int error; | 124 | int error; | |
125 | 125 | |||
126 | const char *dr_mode = fdtbus_get_string(phandle, "dr_mode"); | 126 | const char *dr_mode = fdtbus_get_string(phandle, "dr_mode"); | |
127 | if (dr_mode == NULL || strcmp(dr_mode, "host") != 0) { | 127 | if (dr_mode == NULL || strcmp(dr_mode, "host") != 0) { | |
128 | aprint_error(": mode '%s' not supported\n", dr_mode); | 128 | aprint_error(": mode '%s' not supported\n", dr_mode); | |
129 | return; | 129 | return; | |
130 | } | 130 | } | |
131 | 131 | |||
132 | if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { | 132 | if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { | |
133 | aprint_error(": couldn't get registers\n"); | 133 | aprint_error(": couldn't get registers\n"); | |
134 | return; | 134 | return; | |
135 | } | 135 | } | |
136 | 136 | |||
137 | clk = fdtbus_clock_get(phandle, "otg"); | 137 | clk = fdtbus_clock_get(phandle, "otg"); | |
138 | if (clk == NULL || clk_enable(clk) != 0) { | 138 | if (clk == NULL || clk_enable(clk) != 0) { | |
139 | aprint_error(": couldn't enable otg clock\n"); | 139 | aprint_error(": couldn't enable otg clock\n"); | |
140 | return; | 140 | return; | |
141 | } | 141 | } | |
142 | 142 | |||
143 | /* Enable optional phy */ | 143 | /* Enable optional phy */ | |
144 | phy = fdtbus_phy_get(phandle, "usb2-phy"); | 144 | phy = fdtbus_phy_get(phandle, "usb2-phy"); | |
145 | if (phy && fdtbus_phy_enable(phy, true) != 0) { | 145 | if (phy && fdtbus_phy_enable(phy, true) != 0) { | |
146 | aprint_error(": couldn't enable phy\n"); | 146 | aprint_error(": couldn't enable phy\n"); | |
147 | return; | 147 | return; | |
148 | } | 148 | } | |
149 | 149 | |||
150 | sc->sc_phandle = phandle; | 150 | sc->sc_phandle = phandle; | |
151 | sc->sc_dwc2.sc_dev = self; | 151 | sc->sc_dwc2.sc_dev = self; | |
152 | sc->sc_dwc2.sc_iot = faa->faa_bst; | 152 | sc->sc_dwc2.sc_iot = faa->faa_bst; | |
153 | sc->sc_dwc2.sc_bus.ub_dmatag = faa->faa_dmat; | 153 | sc->sc_dwc2.sc_bus.ub_dmatag = faa->faa_dmat; | |
154 | 154 | |||
155 | error = bus_space_map(faa->faa_bst, addr, size, 0, &sc->sc_dwc2.sc_ioh); | 155 | error = bus_space_map(faa->faa_bst, addr, size, 0, &sc->sc_dwc2.sc_ioh); | |
156 | if (error) { | 156 | if (error) { | |
157 | aprint_error(": couldn't map device\n"); | 157 | aprint_error(": couldn't map device\n"); | |
158 | return; | 158 | return; | |
159 | } | 159 | } | |
160 | 160 | |||
161 | if (conf->params) { | 161 | if (conf->params) { | |
162 | conf->params(sc, &sc->sc_params); | 162 | conf->params(sc, &sc->sc_params); | |
163 | sc->sc_dwc2.sc_params = &sc->sc_params; | 163 | sc->sc_dwc2.sc_params = &sc->sc_params; | |
164 | } | 164 | } | |
165 | 165 | |||
166 | if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { | 166 | if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { | |
167 | aprint_error(": failed to decode interrupt\n"); | 167 | aprint_error(": failed to decode interrupt\n"); | |
168 | return; | 168 | return; | |
169 | } | 169 | } | |
170 | 170 | |||
171 | aprint_naive("\n"); | 171 | aprint_naive("\n"); | |
172 | aprint_normal(": DesignWare USB2 OTG\n"); | 172 | aprint_normal(": DesignWare USB2 OTG\n"); | |
173 | 173 | |||
174 | sc->sc_ih = fdtbus_intr_establish_xname(phandle, 0, IPL_VM, | 174 | sc->sc_ih = fdtbus_intr_establish_xname(phandle, 0, IPL_VM, | |
175 | FDT_INTR_MPSAFE, dwc2_intr, &sc->sc_dwc2, device_xname(self)); | 175 | FDT_INTR_MPSAFE, dwc2_intr, &sc->sc_dwc2, device_xname(self)); | |
176 | if (sc->sc_ih == NULL) { | 176 | if (sc->sc_ih == NULL) { | |
177 | aprint_error_dev(self, "failed to establish interrupt %s\n", | 177 | aprint_error_dev(self, "failed to establish interrupt %s\n", | |
178 | intrstr); | 178 | intrstr); | |
179 | goto fail; | 179 | goto fail; | |
180 | } | 180 | } | |
181 | aprint_normal_dev(self, "interrupting on %s\n", intrstr); | 181 | aprint_normal_dev(self, "interrupting on %s\n", intrstr); | |
182 | config_interrupts(self, dwc2_fdt_deferred); | 182 | config_interrupts(self, dwc2_fdt_deferred); | |
183 | 183 | |||
184 | return; | 184 | return; | |
185 | 185 | |||
186 | fail: | 186 | fail: | |
187 | if (sc->sc_ih) { | 187 | if (sc->sc_ih) { | |
188 | fdtbus_intr_disestablish(sc->sc_phandle, sc->sc_ih); | 188 | fdtbus_intr_disestablish(sc->sc_phandle, sc->sc_ih); | |
189 | sc->sc_ih = NULL; | 189 | sc->sc_ih = NULL; | |
190 | } | 190 | } | |
191 | bus_space_unmap(sc->sc_dwc2.sc_iot, sc->sc_dwc2.sc_ioh, size); | 191 | bus_space_unmap(sc->sc_dwc2.sc_iot, sc->sc_dwc2.sc_ioh, size); | |
192 | } | 192 | } | |
193 | 193 | |||
194 | static void | 194 | static void | |
195 | dwc2_fdt_deferred(device_t self) | 195 | dwc2_fdt_deferred(device_t self) | |
196 | { | 196 | { | |
197 | struct dwc2_fdt_softc *sc = device_private(self); | 197 | struct dwc2_fdt_softc *sc = device_private(self); | |
198 | int error; | 198 | int error; | |
199 | 199 | |||
200 | error = dwc2_init(&sc->sc_dwc2); | 200 | error = dwc2_init(&sc->sc_dwc2); | |
201 | if (error != 0) { | 201 | if (error != 0) { | |
202 | aprint_error_dev(self, "couldn't initialize host, error=%d\n", | 202 | aprint_error_dev(self, "couldn't initialize host, error=%d\n", | |
203 | error); | 203 | error); | |
204 | return; | 204 | return; | |
205 | } | 205 | } | |
206 | sc->sc_dwc2.sc_child = config_found(sc->sc_dwc2.sc_dev, | 206 | sc->sc_dwc2.sc_child = config_found(sc->sc_dwc2.sc_dev, | |
207 | &sc->sc_dwc2.sc_bus, usbctlprint); | 207 | &sc->sc_dwc2.sc_bus, usbctlprint); | |
208 | } | 208 | } | |
209 | 209 | |||
210 | static void | 210 | static void | |
211 | dwc2_fdt_amlogic_params(struct dwc2_fdt_softc *sc, struct dwc2_core_params *params) | 211 | dwc2_fdt_amlogic_params(struct dwc2_fdt_softc *sc, struct dwc2_core_params *params) | |
212 | { | 212 | { | |
213 | dwc2_set_all_params(params, -1); | 213 | dwc2_set_all_params(params, -1); | |
214 | 214 | |||
215 | params->otg_cap = DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE; | 215 | params->otg_cap = DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE; | |
216 | params->speed = DWC2_SPEED_PARAM_HIGH; | 216 | params->speed = DWC2_SPEED_PARAM_HIGH; | |
217 | params->dma_enable = 1; | 217 | params->dma_enable = 1; | |
218 | params->enable_dynamic_fifo = 1, | 218 | params->enable_dynamic_fifo = 1, | |
219 | params->host_rx_fifo_size = 512; | 219 | params->host_rx_fifo_size = 512; | |
220 | params->host_nperio_tx_fifo_size = 500; | 220 | params->host_nperio_tx_fifo_size = 500; | |
221 | params->host_perio_tx_fifo_size = 500; | 221 | params->host_perio_tx_fifo_size = 500; | |
222 | params->host_channels = 16; | 222 | params->host_channels = 16; | |
223 | params->phy_type = DWC2_PHY_TYPE_PARAM_UTMI; | 223 | params->phy_type = DWC2_PHY_TYPE_PARAM_UTMI; | |
224 | params->reload_ctl = 1, | 224 | params->reload_ctl = 1, | |
225 | params->ahbcfg = GAHBCFG_HBSTLEN_INCR8 << GAHBCFG_HBSTLEN_SHIFT; | 225 | params->ahbcfg = GAHBCFG_HBSTLEN_INCR8 << GAHBCFG_HBSTLEN_SHIFT; | |
226 | #ifdef DWC2_POWER_DOWN_PARAM_NONE | 226 | #ifdef DWC2_POWER_DOWN_PARAM_NONE | |
227 | params->power_down = DWC2_POWER_DOWN_PARAM_NONE; | 227 | params->power_down = DWC2_POWER_DOWN_PARAM_NONE; | |
228 | #endif | 228 | #endif | |
229 | } | 229 | } | |
230 | 230 | |||
231 | static void | 231 | static void | |
232 | dwc2_fdt_rockchip_params(struct dwc2_fdt_softc *sc, struct dwc2_core_params *params) | 232 | dwc2_fdt_rockchip_params(struct dwc2_fdt_softc *sc, struct dwc2_core_params *params) | |
233 | { | 233 | { | |
234 | dwc2_set_all_params(params, -1); | 234 | dwc2_set_all_params(params, -1); | |
235 | 235 | |||
236 | params->otg_cap = DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE; | 236 | params->otg_cap = DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE; | |
237 | params->host_rx_fifo_size = 525; | 237 | params->host_rx_fifo_size = 525; | |
238 | params->host_nperio_tx_fifo_size = 128; | 238 | params->host_nperio_tx_fifo_size = 128; | |
239 | params->host_perio_tx_fifo_size = 256; | 239 | params->host_perio_tx_fifo_size = 256; | |
240 | params->ahbcfg = GAHBCFG_HBSTLEN_INCR16 << GAHBCFG_HBSTLEN_SHIFT; | 240 | params->ahbcfg = GAHBCFG_HBSTLEN_INCR16 << GAHBCFG_HBSTLEN_SHIFT; | |
241 | } | 241 | } |
--- src/sys/dev/fdt/i2cmux_fdt.c 2021/01/25 12:18:18 1.7
+++ src/sys/dev/fdt/i2cmux_fdt.c 2021/01/25 14:25:09 1.8
@@ -1,280 +1,280 @@ | @@ -1,280 +1,280 @@ | |||
1 | /* $NetBSD: i2cmux_fdt.c,v 1.7 2021/01/25 12:18:18 jmcneill Exp $ */ | 1 | /* $NetBSD: i2cmux_fdt.c,v 1.8 2021/01/25 14:25:09 thorpej Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2020 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2020 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 Jason R. Thorpe. | 8 | * by Jason R. Thorpe. | |
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. | |
15 | * 2. Redistributions in binary form must reproduce the above copyright | 15 | * 2. Redistributions in binary form must reproduce the above copyright | |
16 | * notice, this list of conditions and the following disclaimer in the | 16 | * notice, this list of conditions and the following disclaimer in the | |
17 | * documentation and/or other materials provided with the distribution. | 17 | * documentation and/or other materials provided with the distribution. | |
18 | * | 18 | * | |
19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | 19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | |
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
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 | __KERNEL_RCSID(0, "$NetBSD: i2cmux_fdt.c,v 1.7 2021/01/25 12:18:18 jmcneill Exp $"); | 33 | __KERNEL_RCSID(0, "$NetBSD: i2cmux_fdt.c,v 1.8 2021/01/25 14:25:09 thorpej Exp $"); | |
34 | 34 | |||
35 | #include <sys/types.h> | 35 | #include <sys/types.h> | |
36 | #include <sys/device.h> | 36 | #include <sys/device.h> | |
37 | #include <sys/kernel.h> | 37 | #include <sys/kernel.h> | |
38 | #include <sys/kmem.h> | 38 | #include <sys/kmem.h> | |
39 | #include <sys/bus.h> | 39 | #include <sys/bus.h> | |
40 | #include <sys/gpio.h> | 40 | #include <sys/gpio.h> | |
41 | 41 | |||
42 | #include <dev/fdt/fdtvar.h> | 42 | #include <dev/fdt/fdtvar.h> | |
43 | #include <dev/i2c/i2cmuxvar.h> | 43 | #include <dev/i2c/i2cmuxvar.h> | |
44 | 44 | |||
45 | /*****************************************************************************/ | 45 | /*****************************************************************************/ | |
46 | 46 | |||
47 | struct mux_info_gpio { | 47 | struct mux_info_gpio { | |
48 | struct fdtbus_gpio_pin **pins; | 48 | struct fdtbus_gpio_pin **pins; | |
49 | int npins; | 49 | int npins; | |
50 | uint32_t idle_value; | 50 | uint32_t idle_value; | |
51 | bool has_idle_value; | 51 | bool has_idle_value; | |
52 | }; | 52 | }; | |
53 | 53 | |||
54 | struct bus_info_gpio { | 54 | struct bus_info_gpio { | |
55 | bus_addr_t value; | 55 | bus_addr_t value; | |
56 | }; | 56 | }; | |
57 | 57 | |||
58 | static void * | 58 | static void * | |
59 | iicmux_gpio_get_mux_info(struct iicmux_softc * const sc) | 59 | iicmux_gpio_get_mux_info(struct iicmux_softc * const sc) | |
60 | { | 60 | { | |
61 | struct mux_info_gpio *mux_data; | 61 | struct mux_info_gpio *mux_data; | |
62 | int i; | 62 | int i; | |
63 | 63 | |||
64 | mux_data = kmem_zalloc(sizeof(*mux_data), KM_SLEEP); | 64 | mux_data = kmem_zalloc(sizeof(*mux_data), KM_SLEEP); | |
65 | 65 | |||
66 | mux_data->npins = fdtbus_gpio_count(sc->sc_handle, "mux-gpios"); | 66 | mux_data->npins = fdtbus_gpio_count(sc->sc_handle, "mux-gpios"); | |
67 | if (mux_data->npins == 0) { | 67 | if (mux_data->npins == 0) { | |
68 | aprint_error_dev(sc->sc_dev, | 68 | aprint_error_dev(sc->sc_dev, | |
69 | "unable to get mux-gpios property\n"); | 69 | "unable to get mux-gpios property\n"); | |
70 | goto bad; | 70 | goto bad; | |
71 | } | 71 | } | |
72 | 72 | |||
73 | mux_data->pins = | 73 | mux_data->pins = | |
74 | kmem_zalloc(sizeof(*mux_data->pins) * mux_data->npins, KM_SLEEP); | 74 | kmem_zalloc(sizeof(*mux_data->pins) * mux_data->npins, KM_SLEEP); | |
75 | for (i = 0; i < mux_data->npins; i++) { | 75 | for (i = 0; i < mux_data->npins; i++) { | |
76 | mux_data->pins[i] = fdtbus_gpio_acquire_index(sc->sc_handle, | 76 | mux_data->pins[i] = fdtbus_gpio_acquire_index(sc->sc_handle, | |
77 | "mux-gpios", i, GPIO_PIN_OUTPUT); | 77 | "mux-gpios", i, GPIO_PIN_OUTPUT); | |
78 | if (mux_data->pins[i] == NULL) { | 78 | if (mux_data->pins[i] == NULL) { | |
79 | aprint_error_dev(sc->sc_dev, | 79 | aprint_error_dev(sc->sc_dev, | |
80 | "unable to acquire gpio #%d\n", i); | 80 | "unable to acquire gpio #%d\n", i); | |
81 | goto bad; | 81 | goto bad; | |
82 | } | 82 | } | |
83 | } | 83 | } | |
84 | 84 | |||
85 | mux_data->has_idle_value = | 85 | mux_data->has_idle_value = | |
86 | of_getprop_uint32(sc->sc_handle, "idle-state", | 86 | of_getprop_uint32(sc->sc_handle, "idle-state", | |
87 | &mux_data->idle_value) == 0; | 87 | &mux_data->idle_value) == 0; | |
88 | 88 | |||
89 | return mux_data; | 89 | return mux_data; | |
90 | 90 | |||
91 | bad: | 91 | bad: | |
92 | for (i = 0; i < mux_data->npins; i++) { | 92 | for (i = 0; i < mux_data->npins; i++) { | |
93 | if (mux_data->pins[i] != NULL) { | 93 | if (mux_data->pins[i] != NULL) { | |
94 | fdtbus_gpio_release(mux_data->pins[i]); | 94 | fdtbus_gpio_release(mux_data->pins[i]); | |
95 | } | 95 | } | |
96 | } | 96 | } | |
97 | kmem_free(mux_data, sizeof(*mux_data)); | 97 | kmem_free(mux_data, sizeof(*mux_data)); | |
98 | return NULL; | 98 | return NULL; | |
99 | } | 99 | } | |
100 | 100 | |||
101 | static void * | 101 | static void * | |
102 | iicmux_gpio_get_bus_info(struct iicmux_bus * const bus) | 102 | iicmux_gpio_get_bus_info(struct iicmux_bus * const bus) | |
103 | { | 103 | { | |
104 | struct iicmux_softc * const sc = bus->mux; | 104 | struct iicmux_softc * const sc = bus->mux; | |
105 | struct bus_info_gpio *bus_info; | 105 | struct bus_info_gpio *bus_info; | |
106 | int error; | 106 | int error; | |
107 | 107 | |||
108 | bus_info = kmem_zalloc(sizeof(*bus_info), KM_SLEEP); | 108 | bus_info = kmem_zalloc(sizeof(*bus_info), KM_SLEEP); | |
109 | 109 | |||
110 | error = fdtbus_get_reg(bus->handle, 0, &bus_info->value, NULL); | 110 | error = fdtbus_get_reg(bus->handle, 0, &bus_info->value, NULL); | |
111 | if (error) { | 111 | if (error) { | |
112 | aprint_error_dev(sc->sc_dev, | 112 | aprint_error_dev(sc->sc_dev, | |
113 | "unable to get reg property for bus %d\n", bus->busidx); | 113 | "unable to get reg property for bus %d\n", bus->busidx); | |
114 | kmem_free(bus_info, sizeof(*bus_info)); | 114 | kmem_free(bus_info, sizeof(*bus_info)); | |
115 | return NULL; | 115 | return NULL; | |
116 | } | 116 | } | |
117 | 117 | |||
118 | return bus_info; | 118 | return bus_info; | |
119 | } | 119 | } | |
120 | 120 | |||
121 | static void | 121 | static void | |
122 | iicmux_gpio_set_value(struct iicmux_softc * const sc, bus_addr_t value) | 122 | iicmux_gpio_set_value(struct iicmux_softc * const sc, bus_addr_t value) | |
123 | { | 123 | { | |
124 | struct mux_info_gpio * const mux_info = sc->sc_mux_data; | 124 | struct mux_info_gpio * const mux_info = sc->sc_mux_data; | |
125 | int i; | 125 | int i; | |
126 | 126 | |||
127 | for (i = 0; i < mux_info->npins; i++, value >>= 1) { | 127 | for (i = 0; i < mux_info->npins; i++, value >>= 1) { | |
128 | fdtbus_gpio_write(mux_info->pins[i], value & 1); | 128 | fdtbus_gpio_write(mux_info->pins[i], value & 1); | |
129 | } | 129 | } | |
130 | } | 130 | } | |
131 | 131 | |||
132 | static int | 132 | static int | |
133 | iicmux_gpio_acquire_bus(struct iicmux_bus * const bus, int const flags __unused) | 133 | iicmux_gpio_acquire_bus(struct iicmux_bus * const bus, int const flags __unused) | |
134 | { | 134 | { | |
135 | struct bus_info_gpio * const bus_info = bus->bus_data; | 135 | struct bus_info_gpio * const bus_info = bus->bus_data; | |
136 | 136 | |||
137 | iicmux_gpio_set_value(bus->mux, bus_info->value); | 137 | iicmux_gpio_set_value(bus->mux, bus_info->value); | |
138 | 138 | |||
139 | return 0; | 139 | return 0; | |
140 | } | 140 | } | |
141 | 141 | |||
142 | static void | 142 | static void | |
143 | iicmux_gpio_release_bus(struct iicmux_bus * const bus, int const flags __unused) | 143 | iicmux_gpio_release_bus(struct iicmux_bus * const bus, int const flags __unused) | |
144 | { | 144 | { | |
145 | struct iicmux_softc * const sc = bus->mux; | 145 | struct iicmux_softc * const sc = bus->mux; | |
146 | struct mux_info_gpio * const mux_info = sc->sc_mux_data; | 146 | struct mux_info_gpio * const mux_info = sc->sc_mux_data; | |
147 | 147 | |||
148 | if (mux_info->has_idle_value) { | 148 | if (mux_info->has_idle_value) { | |
149 | iicmux_gpio_set_value(sc, mux_info->idle_value); | 149 | iicmux_gpio_set_value(sc, mux_info->idle_value); | |
150 | } | 150 | } | |
151 | } | 151 | } | |
152 | 152 | |||
153 | static const struct iicmux_config iicmux_gpio_config = { | 153 | static const struct iicmux_config iicmux_gpio_config = { | |
154 | .desc = "GPIO", | 154 | .desc = "GPIO", | |
155 | .get_mux_info = iicmux_gpio_get_mux_info, | 155 | .get_mux_info = iicmux_gpio_get_mux_info, | |
156 | .get_bus_info = iicmux_gpio_get_bus_info, | 156 | .get_bus_info = iicmux_gpio_get_bus_info, | |
157 | .acquire_bus = iicmux_gpio_acquire_bus, | 157 | .acquire_bus = iicmux_gpio_acquire_bus, | |
158 | .release_bus = iicmux_gpio_release_bus, | 158 | .release_bus = iicmux_gpio_release_bus, | |
159 | }; | 159 | }; | |
160 | 160 | |||
161 | /*****************************************************************************/ | 161 | /*****************************************************************************/ | |
162 | 162 | |||
163 | struct mux_info_pinctrl { | 163 | struct mux_info_pinctrl { | |
164 | u_int idle_idx; | 164 | u_int idle_idx; | |
165 | bool has_idle_idx; | 165 | bool has_idle_idx; | |
166 | } sc_pinctrl; | 166 | } sc_pinctrl; | |
167 | 167 | |||
168 | struct bus_info_pinctrl { | 168 | struct bus_info_pinctrl { | |
169 | bus_addr_t idx; | 169 | bus_addr_t idx; | |
170 | }; | 170 | }; | |
171 | 171 | |||
172 | static void * | 172 | static void * | |
173 | iicmux_pinctrl_get_mux_info(struct iicmux_softc * const sc) | 173 | iicmux_pinctrl_get_mux_info(struct iicmux_softc * const sc) | |
174 | { | 174 | { | |
175 | struct mux_info_pinctrl *mux_info; | 175 | struct mux_info_pinctrl *mux_info; | |
176 | 176 | |||
177 | mux_info = kmem_alloc(sizeof(*mux_info), KM_SLEEP); | 177 | mux_info = kmem_alloc(sizeof(*mux_info), KM_SLEEP); | |
178 | 178 | |||
179 | mux_info->has_idle_idx = | 179 | mux_info->has_idle_idx = | |
180 | fdtbus_get_index(sc->sc_handle, "pinctrl-names", "idle", | 180 | fdtbus_get_index(sc->sc_handle, "pinctrl-names", "idle", | |
181 | &mux_info->idle_idx) == 0; | 181 | &mux_info->idle_idx) == 0; | |
182 | 182 | |||
183 | return mux_info; | 183 | return mux_info; | |
184 | } | 184 | } | |
185 | 185 | |||
186 | static void * | 186 | static void * | |
187 | iicmux_pinctrl_get_bus_info(struct iicmux_bus * const bus) | 187 | iicmux_pinctrl_get_bus_info(struct iicmux_bus * const bus) | |
188 | { | 188 | { | |
189 | struct iicmux_softc * const sc = bus->mux; | 189 | struct iicmux_softc * const sc = bus->mux; | |
190 | struct bus_info_pinctrl *bus_info; | 190 | struct bus_info_pinctrl *bus_info; | |
191 | int error; | 191 | int error; | |
192 | 192 | |||
193 | bus_info = kmem_alloc(sizeof(*bus_info), KM_SLEEP); | 193 | bus_info = kmem_alloc(sizeof(*bus_info), KM_SLEEP); | |
194 | 194 | |||
195 | error = fdtbus_get_reg(bus->handle, 0, &bus_info->idx, NULL); | 195 | error = fdtbus_get_reg(bus->handle, 0, &bus_info->idx, NULL); | |
196 | if (error) { | 196 | if (error) { | |
197 | aprint_error_dev(sc->sc_dev, | 197 | aprint_error_dev(sc->sc_dev, | |
198 | "unable to get reg property for bus %d\n", bus->busidx); | 198 | "unable to get reg property for bus %d\n", bus->busidx); | |
199 | kmem_free(bus_info, sizeof(*bus_info)); | 199 | kmem_free(bus_info, sizeof(*bus_info)); | |
200 | return NULL; | 200 | return NULL; | |
201 | } | 201 | } | |
202 | 202 | |||
203 | return bus_info; | 203 | return bus_info; | |
204 | } | 204 | } | |
205 | 205 | |||
206 | static int | 206 | static int | |
207 | iicmux_pinctrl_acquire_bus(struct iicmux_bus * const bus, | 207 | iicmux_pinctrl_acquire_bus(struct iicmux_bus * const bus, | |
208 | int const flags __unused) | 208 | int const flags __unused) | |
209 | { | 209 | { | |
210 | struct iicmux_softc * const sc = bus->mux; | 210 | struct iicmux_softc * const sc = bus->mux; | |
211 | struct bus_info_pinctrl * const bus_info = bus->bus_data; | 211 | struct bus_info_pinctrl * const bus_info = bus->bus_data; | |
212 | 212 | |||
213 | return fdtbus_pinctrl_set_config_index(sc->sc_handle, bus_info->idx); | 213 | return fdtbus_pinctrl_set_config_index(sc->sc_handle, bus_info->idx); | |
214 | } | 214 | } | |
215 | 215 | |||
216 | static void | 216 | static void | |
217 | iicmux_pinctrl_release_bus(struct iicmux_bus * const bus, | 217 | iicmux_pinctrl_release_bus(struct iicmux_bus * const bus, | |
218 | int const flags __unused) | 218 | int const flags __unused) | |
219 | { | 219 | { | |
220 | struct iicmux_softc * const sc = bus->mux; | 220 | struct iicmux_softc * const sc = bus->mux; | |
221 | struct mux_info_pinctrl * const mux_info = sc->sc_mux_data; | 221 | struct mux_info_pinctrl * const mux_info = sc->sc_mux_data; | |
222 | 222 | |||
223 | if (mux_info->has_idle_idx) { | 223 | if (mux_info->has_idle_idx) { | |
224 | (void) fdtbus_pinctrl_set_config_index(sc->sc_handle, | 224 | (void) fdtbus_pinctrl_set_config_index(sc->sc_handle, | |
225 | mux_info->idle_idx); | 225 | mux_info->idle_idx); | |
226 | } | 226 | } | |
227 | } | 227 | } | |
228 | 228 | |||
229 | static const struct iicmux_config iicmux_pinctrl_config = { | 229 | static const struct iicmux_config iicmux_pinctrl_config = { | |
230 | .desc = "PinMux", | 230 | .desc = "PinMux", | |
231 | .get_mux_info = iicmux_pinctrl_get_mux_info, | 231 | .get_mux_info = iicmux_pinctrl_get_mux_info, | |
232 | .get_bus_info = iicmux_pinctrl_get_bus_info, | 232 | .get_bus_info = iicmux_pinctrl_get_bus_info, | |
233 | .acquire_bus = iicmux_pinctrl_acquire_bus, | 233 | .acquire_bus = iicmux_pinctrl_acquire_bus, | |
234 | .release_bus = iicmux_pinctrl_release_bus, | 234 | .release_bus = iicmux_pinctrl_release_bus, | |
235 | }; | 235 | }; | |
236 | 236 | |||
237 | /*****************************************************************************/ | 237 | /*****************************************************************************/ | |
238 | 238 | |||
239 | static const struct device_compatible_entry compat_data[] = { | 239 | static const struct device_compatible_entry compat_data[] = { | |
240 | { .compat = "i2c-mux-gpio", | 240 | { .compat = "i2c-mux-gpio", | |
241 | .data = &iicmux_gpio_config }, | 241 | .data = &iicmux_gpio_config }, | |
242 | 242 | |||
243 | { .compat = "i2c-mux-pinctrl", | 243 | { .compat = "i2c-mux-pinctrl", | |
244 | .data = &iicmux_pinctrl_config }, | 244 | .data = &iicmux_pinctrl_config }, | |
245 | 245 | |||
246 | { NULL } | 246 | { } | |
247 | }; | 247 | }; | |
248 | 248 | |||
249 | static int | 249 | static int | |
250 | iicmux_fdt_match(device_t const parent, cfdata_t const match, void * const aux) | 250 | iicmux_fdt_match(device_t const parent, cfdata_t const match, void * const aux) | |
251 | { | 251 | { | |
252 | struct fdt_attach_args * const faa = aux; | 252 | struct fdt_attach_args * const faa = aux; | |
253 | 253 | |||
254 | return of_match_compat_data(faa->faa_phandle, compat_data); | 254 | return of_match_compat_data(faa->faa_phandle, compat_data); | |
255 | } | 255 | } | |
256 | 256 | |||
257 | static void | 257 | static void | |
258 | iicmux_fdt_attach(device_t const parent, device_t const self, void * const aux) | 258 | iicmux_fdt_attach(device_t const parent, device_t const self, void * const aux) | |
259 | { | 259 | { | |
260 | struct iicmux_softc * const sc = device_private(self); | 260 | struct iicmux_softc * const sc = device_private(self); | |
261 | struct fdt_attach_args * const faa = aux; | 261 | struct fdt_attach_args * const faa = aux; | |
262 | 262 | |||
263 | sc->sc_dev = self; | 263 | sc->sc_dev = self; | |
264 | sc->sc_handle = faa->faa_phandle; | 264 | sc->sc_handle = faa->faa_phandle; | |
265 | sc->sc_config = of_search_compatible(sc->sc_handle, compat_data)->data; | 265 | sc->sc_config = of_search_compatible(sc->sc_handle, compat_data)->data; | |
266 | 266 | |||
267 | aprint_naive("\n"); | 267 | aprint_naive("\n"); | |
268 | aprint_normal(": %s I2C mux\n", sc->sc_config->desc); | 268 | aprint_normal(": %s I2C mux\n", sc->sc_config->desc); | |
269 | 269 | |||
270 | sc->sc_i2c_parent = fdtbus_i2c_acquire(sc->sc_handle, "i2c-parent"); | 270 | sc->sc_i2c_parent = fdtbus_i2c_acquire(sc->sc_handle, "i2c-parent"); | |
271 | if (sc->sc_i2c_parent == NULL) { | 271 | if (sc->sc_i2c_parent == NULL) { | |
272 | aprint_error_dev(sc->sc_dev, "unable to acquire i2c-parent\n"); | 272 | aprint_error_dev(sc->sc_dev, "unable to acquire i2c-parent\n"); | |
273 | return; | 273 | return; | |
274 | } | 274 | } | |
275 | 275 | |||
276 | iicmux_attach(sc); | 276 | iicmux_attach(sc); | |
277 | } | 277 | } | |
278 | 278 | |||
279 | CFATTACH_DECL_NEW(iicmux_fdt, sizeof(struct iicmux_softc), | 279 | CFATTACH_DECL_NEW(iicmux_fdt, sizeof(struct iicmux_softc), | |
280 | iicmux_fdt_match, iicmux_fdt_attach, NULL, NULL); | 280 | iicmux_fdt_match, iicmux_fdt_attach, NULL, NULL); |
--- src/sys/dev/fdt/dwcmmc_fdt.c 2021/01/18 02:35:49 1.13
+++ src/sys/dev/fdt/dwcmmc_fdt.c 2021/01/25 14:25:09 1.14
@@ -1,276 +1,275 @@ | @@ -1,276 +1,275 @@ | |||
1 | /* $NetBSD: dwcmmc_fdt.c,v 1.13 2021/01/18 02:35:49 thorpej Exp $ */ | 1 | /* $NetBSD: dwcmmc_fdt.c,v 1.14 2021/01/25 14:25:09 thorpej Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2015-2018 Jared McNeill <jmcneill@invisible.ca> | 4 | * Copyright (c) 2015-2018 Jared 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. | |
15 | * | 15 | * | |
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 <sys/cdefs.h> | 29 | #include <sys/cdefs.h> | |
30 | __KERNEL_RCSID(0, "$NetBSD: dwcmmc_fdt.c,v 1.13 2021/01/18 02:35:49 thorpej Exp $"); | 30 | __KERNEL_RCSID(0, "$NetBSD: dwcmmc_fdt.c,v 1.14 2021/01/25 14:25:09 thorpej 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/gpio.h> | 40 | #include <sys/gpio.h> | |
41 | 41 | |||
42 | #include <dev/ic/dwc_mmc_var.h> | 42 | #include <dev/ic/dwc_mmc_var.h> | |
43 | #include <dev/sdmmc/sdmmcchip.h> | 43 | #include <dev/sdmmc/sdmmcchip.h> | |
44 | #include <dev/fdt/fdtvar.h> | 44 | #include <dev/fdt/fdtvar.h> | |
45 | 45 | |||
46 | static int dwcmmc_fdt_match(device_t, cfdata_t, void *); | 46 | static int dwcmmc_fdt_match(device_t, cfdata_t, void *); | |
47 | static void dwcmmc_fdt_attach(device_t, device_t, void *); | 47 | static void dwcmmc_fdt_attach(device_t, device_t, void *); | |
48 | 48 | |||
49 | static void dwcmmc_fdt_pre_power_on(struct dwc_mmc_softc *); | 49 | static void dwcmmc_fdt_pre_power_on(struct dwc_mmc_softc *); | |
50 | static void dwcmmc_fdt_post_power_on(struct dwc_mmc_softc *); | 50 | static void dwcmmc_fdt_post_power_on(struct dwc_mmc_softc *); | |
51 | 51 | |||
52 | static int dwcmmc_fdt_card_detect(struct dwc_mmc_softc *); | 52 | static int dwcmmc_fdt_card_detect(struct dwc_mmc_softc *); | |
53 | static int dwcmmc_fdt_bus_clock(struct dwc_mmc_softc *, int); | 53 | static int dwcmmc_fdt_bus_clock(struct dwc_mmc_softc *, int); | |
54 | static int dwcmmc_fdt_signal_voltage(struct dwc_mmc_softc *, int); | 54 | static int dwcmmc_fdt_signal_voltage(struct dwc_mmc_softc *, int); | |
55 | 55 | |||
56 | struct dwcmmc_fdt_config { | 56 | struct dwcmmc_fdt_config { | |
57 | u_int ciu_div; | 57 | u_int ciu_div; | |
58 | u_int flags; | 58 | u_int flags; | |
59 | uint32_t intr_cardmask; | 59 | uint32_t intr_cardmask; | |
60 | }; | 60 | }; | |
61 | 61 | |||
62 | static const struct dwcmmc_fdt_config dwcmmc_rk3288_config = { | 62 | static const struct dwcmmc_fdt_config dwcmmc_rk3288_config = { | |
63 | .ciu_div = 2, | 63 | .ciu_div = 2, | |
64 | .flags = DWC_MMC_F_USE_HOLD_REG | | 64 | .flags = DWC_MMC_F_USE_HOLD_REG | | |
65 | DWC_MMC_F_DMA, | 65 | DWC_MMC_F_DMA, | |
66 | .intr_cardmask = __BIT(24), | 66 | .intr_cardmask = __BIT(24), | |
67 | }; | 67 | }; | |
68 | 68 | |||
69 | static const struct device_compatible_entry compat_data[] = { | 69 | static const struct device_compatible_entry compat_data[] = { | |
70 | { .compat = "rockchip,rk3288-dw-mshc", .data = &dwcmmc_rk3288_config }, | 70 | { .compat = "rockchip,rk3288-dw-mshc", .data = &dwcmmc_rk3288_config }, | |
71 | 71 | { } | ||
72 | { 0 } | |||
73 | }; | 72 | }; | |
74 | 73 | |||
75 | struct dwcmmc_fdt_softc { | 74 | struct dwcmmc_fdt_softc { | |
76 | struct dwc_mmc_softc sc; | 75 | struct dwc_mmc_softc sc; | |
77 | struct clk *sc_clk_biu; | 76 | struct clk *sc_clk_biu; | |
78 | struct clk *sc_clk_ciu; | 77 | struct clk *sc_clk_ciu; | |
79 | struct fdtbus_gpio_pin *sc_pin_cd; | 78 | struct fdtbus_gpio_pin *sc_pin_cd; | |
80 | const struct dwcmmc_fdt_config *sc_conf; | 79 | const struct dwcmmc_fdt_config *sc_conf; | |
81 | u_int sc_ciu_div; | 80 | u_int sc_ciu_div; | |
82 | struct fdtbus_regulator *sc_vqmmc; | 81 | struct fdtbus_regulator *sc_vqmmc; | |
83 | struct fdtbus_mmc_pwrseq *sc_pwrseq; | 82 | struct fdtbus_mmc_pwrseq *sc_pwrseq; | |
84 | }; | 83 | }; | |
85 | 84 | |||
86 | CFATTACH_DECL_NEW(dwcmmc_fdt, sizeof(struct dwcmmc_fdt_softc), | 85 | CFATTACH_DECL_NEW(dwcmmc_fdt, sizeof(struct dwcmmc_fdt_softc), | |
87 | dwcmmc_fdt_match, dwcmmc_fdt_attach, NULL, NULL); | 86 | dwcmmc_fdt_match, dwcmmc_fdt_attach, NULL, NULL); | |
88 | 87 | |||
89 | static int | 88 | static int | |
90 | dwcmmc_fdt_match(device_t parent, cfdata_t cf, void *aux) | 89 | dwcmmc_fdt_match(device_t parent, cfdata_t cf, void *aux) | |
91 | { | 90 | { | |
92 | struct fdt_attach_args * const faa = aux; | 91 | struct fdt_attach_args * const faa = aux; | |
93 | 92 | |||
94 | return of_match_compat_data(faa->faa_phandle, compat_data); | 93 | return of_match_compat_data(faa->faa_phandle, compat_data); | |
95 | } | 94 | } | |
96 | 95 | |||
97 | static void | 96 | static void | |
98 | dwcmmc_fdt_attach(device_t parent, device_t self, void *aux) | 97 | dwcmmc_fdt_attach(device_t parent, device_t self, void *aux) | |
99 | { | 98 | { | |
100 | struct dwcmmc_fdt_softc *esc = device_private(self); | 99 | struct dwcmmc_fdt_softc *esc = device_private(self); | |
101 | struct dwc_mmc_softc *sc = &esc->sc; | 100 | struct dwc_mmc_softc *sc = &esc->sc; | |
102 | struct fdt_attach_args * const faa = aux; | 101 | struct fdt_attach_args * const faa = aux; | |
103 | const int phandle = faa->faa_phandle; | 102 | const int phandle = faa->faa_phandle; | |
104 | char intrstr[128]; | 103 | char intrstr[128]; | |
105 | u_int fifo_depth; | 104 | u_int fifo_depth; | |
106 | bus_addr_t addr; | 105 | bus_addr_t addr; | |
107 | bus_size_t size; | 106 | bus_size_t size; | |
108 | int error; | 107 | int error; | |
109 | 108 | |||
110 | if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { | 109 | if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { | |
111 | aprint_error(": couldn't get registers\n"); | 110 | aprint_error(": couldn't get registers\n"); | |
112 | return; | 111 | return; | |
113 | } | 112 | } | |
114 | 113 | |||
115 | if (of_getprop_uint32(phandle, "fifo-depth", &fifo_depth)) | 114 | if (of_getprop_uint32(phandle, "fifo-depth", &fifo_depth)) | |
116 | fifo_depth = 0; | 115 | fifo_depth = 0; | |
117 | 116 | |||
118 | fdtbus_clock_assign(phandle); | 117 | fdtbus_clock_assign(phandle); | |
119 | 118 | |||
120 | esc->sc_clk_biu = fdtbus_clock_get(phandle, "biu"); | 119 | esc->sc_clk_biu = fdtbus_clock_get(phandle, "biu"); | |
121 | if (esc->sc_clk_biu == NULL) { | 120 | if (esc->sc_clk_biu == NULL) { | |
122 | aprint_error(": couldn't get clock biu\n"); | 121 | aprint_error(": couldn't get clock biu\n"); | |
123 | return; | 122 | return; | |
124 | } | 123 | } | |
125 | esc->sc_clk_ciu = fdtbus_clock_get(phandle, "ciu"); | 124 | esc->sc_clk_ciu = fdtbus_clock_get(phandle, "ciu"); | |
126 | if (esc->sc_clk_ciu == NULL) { | 125 | if (esc->sc_clk_ciu == NULL) { | |
127 | aprint_error(": couldn't get clock ciu\n"); | 126 | aprint_error(": couldn't get clock ciu\n"); | |
128 | return; | 127 | return; | |
129 | } | 128 | } | |
130 | 129 | |||
131 | error = clk_enable(esc->sc_clk_biu); | 130 | error = clk_enable(esc->sc_clk_biu); | |
132 | if (error) { | 131 | if (error) { | |
133 | aprint_error(": couldn't enable clock biu: %d\n", error); | 132 | aprint_error(": couldn't enable clock biu: %d\n", error); | |
134 | return; | 133 | return; | |
135 | } | 134 | } | |
136 | error = clk_enable(esc->sc_clk_ciu); | 135 | error = clk_enable(esc->sc_clk_ciu); | |
137 | if (error) { | 136 | if (error) { | |
138 | aprint_error(": couldn't enable clock ciu: %d\n", error); | 137 | aprint_error(": couldn't enable clock ciu: %d\n", error); | |
139 | return; | 138 | return; | |
140 | } | 139 | } | |
141 | 140 | |||
142 | esc->sc_vqmmc = fdtbus_regulator_acquire(phandle, "vqmmc-supply"); | 141 | esc->sc_vqmmc = fdtbus_regulator_acquire(phandle, "vqmmc-supply"); | |
143 | esc->sc_pwrseq = fdtbus_mmc_pwrseq_get(phandle); | 142 | esc->sc_pwrseq = fdtbus_mmc_pwrseq_get(phandle); | |
144 | 143 | |||
145 | sc->sc_dev = self; | 144 | sc->sc_dev = self; | |
146 | sc->sc_bst = faa->faa_bst; | 145 | sc->sc_bst = faa->faa_bst; | |
147 | sc->sc_dmat = faa->faa_dmat; | 146 | sc->sc_dmat = faa->faa_dmat; | |
148 | error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh); | 147 | error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh); | |
149 | if (error) { | 148 | if (error) { | |
150 | aprint_error(": couldn't map %#" PRIx64 ": %d\n", | 149 | aprint_error(": couldn't map %#" PRIx64 ": %d\n", | |
151 | (uint64_t)addr, error); | 150 | (uint64_t)addr, error); | |
152 | return; | 151 | return; | |
153 | } | 152 | } | |
154 | esc->sc_conf = of_search_compatible(phandle, compat_data)->data; | 153 | esc->sc_conf = of_search_compatible(phandle, compat_data)->data; | |
155 | 154 | |||
156 | if (of_getprop_uint32(phandle, "max-frequency", &sc->sc_clock_freq) != 0) | 155 | if (of_getprop_uint32(phandle, "max-frequency", &sc->sc_clock_freq) != 0) | |
157 | sc->sc_clock_freq = UINT_MAX; | 156 | sc->sc_clock_freq = UINT_MAX; | |
158 | if (of_getprop_uint32(phandle, "bus-width", &sc->sc_bus_width) != 0) | 157 | if (of_getprop_uint32(phandle, "bus-width", &sc->sc_bus_width) != 0) | |
159 | sc->sc_bus_width = 4; | 158 | sc->sc_bus_width = 4; | |
160 | 159 | |||
161 | sc->sc_fifo_depth = fifo_depth; | 160 | sc->sc_fifo_depth = fifo_depth; | |
162 | sc->sc_intr_cardmask = esc->sc_conf->intr_cardmask; | 161 | sc->sc_intr_cardmask = esc->sc_conf->intr_cardmask; | |
163 | sc->sc_ciu_div = esc->sc_conf->ciu_div; | 162 | sc->sc_ciu_div = esc->sc_conf->ciu_div; | |
164 | sc->sc_flags = esc->sc_conf->flags; | 163 | sc->sc_flags = esc->sc_conf->flags; | |
165 | sc->sc_pre_power_on = dwcmmc_fdt_pre_power_on; | 164 | sc->sc_pre_power_on = dwcmmc_fdt_pre_power_on; | |
166 | sc->sc_post_power_on = dwcmmc_fdt_post_power_on; | 165 | sc->sc_post_power_on = dwcmmc_fdt_post_power_on; | |
167 | sc->sc_bus_clock = dwcmmc_fdt_bus_clock; | 166 | sc->sc_bus_clock = dwcmmc_fdt_bus_clock; | |
168 | sc->sc_signal_voltage = dwcmmc_fdt_signal_voltage; | 167 | sc->sc_signal_voltage = dwcmmc_fdt_signal_voltage; | |
169 | 168 | |||
170 | esc->sc_pin_cd = fdtbus_gpio_acquire(phandle, "cd-gpios", | 169 | esc->sc_pin_cd = fdtbus_gpio_acquire(phandle, "cd-gpios", | |
171 | GPIO_PIN_INPUT); | 170 | GPIO_PIN_INPUT); | |
172 | if (esc->sc_pin_cd) | 171 | if (esc->sc_pin_cd) | |
173 | sc->sc_card_detect = dwcmmc_fdt_card_detect; | 172 | sc->sc_card_detect = dwcmmc_fdt_card_detect; | |
174 | 173 | |||
175 | aprint_naive("\n"); | 174 | aprint_naive("\n"); | |
176 | aprint_normal(": DesignWare SD/MMC\n"); | 175 | aprint_normal(": DesignWare SD/MMC\n"); | |
177 | 176 | |||
178 | if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { | 177 | if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { | |
179 | aprint_error_dev(self, "failed to decode interrupt\n"); | 178 | aprint_error_dev(self, "failed to decode interrupt\n"); | |
180 | return; | 179 | return; | |
181 | } | 180 | } | |
182 | 181 | |||
183 | if (dwc_mmc_init(sc) != 0) | 182 | if (dwc_mmc_init(sc) != 0) | |
184 | return; | 183 | return; | |
185 | 184 | |||
186 | sc->sc_ih = fdtbus_intr_establish_xname(phandle, 0, IPL_BIO, 0, | 185 | sc->sc_ih = fdtbus_intr_establish_xname(phandle, 0, IPL_BIO, 0, | |
187 | dwc_mmc_intr, sc, device_xname(self)); | 186 | dwc_mmc_intr, sc, device_xname(self)); | |
188 | if (sc->sc_ih == NULL) { | 187 | if (sc->sc_ih == NULL) { | |
189 | aprint_error_dev(self, "couldn't establish interrupt on %s\n", | 188 | aprint_error_dev(self, "couldn't establish interrupt on %s\n", | |
190 | intrstr); | 189 | intrstr); | |
191 | return; | 190 | return; | |
192 | } | 191 | } | |
193 | aprint_normal_dev(self, "interrupting on %s\n", intrstr); | 192 | aprint_normal_dev(self, "interrupting on %s\n", intrstr); | |
194 | } | 193 | } | |
195 | 194 | |||
196 | static void | 195 | static void | |
197 | dwcmmc_fdt_pre_power_on(struct dwc_mmc_softc *sc) | 196 | dwcmmc_fdt_pre_power_on(struct dwc_mmc_softc *sc) | |
198 | { | 197 | { | |
199 | struct dwcmmc_fdt_softc *esc = device_private(sc->sc_dev); | 198 | struct dwcmmc_fdt_softc *esc = device_private(sc->sc_dev); | |
200 | 199 | |||
201 | if (esc->sc_pwrseq != NULL) | 200 | if (esc->sc_pwrseq != NULL) | |
202 | fdtbus_mmc_pwrseq_pre_power_on(esc->sc_pwrseq); | 201 | fdtbus_mmc_pwrseq_pre_power_on(esc->sc_pwrseq); | |
203 | } | 202 | } | |
204 | 203 | |||
205 | static void | 204 | static void | |
206 | dwcmmc_fdt_post_power_on(struct dwc_mmc_softc *sc) | 205 | dwcmmc_fdt_post_power_on(struct dwc_mmc_softc *sc) | |
207 | { | 206 | { | |
208 | struct dwcmmc_fdt_softc *esc = device_private(sc->sc_dev); | 207 | struct dwcmmc_fdt_softc *esc = device_private(sc->sc_dev); | |
209 | 208 | |||
210 | if (esc->sc_pwrseq != NULL) | 209 | if (esc->sc_pwrseq != NULL) | |
211 | fdtbus_mmc_pwrseq_post_power_on(esc->sc_pwrseq); | 210 | fdtbus_mmc_pwrseq_post_power_on(esc->sc_pwrseq); | |
212 | } | 211 | } | |
213 | 212 | |||
214 | static int | 213 | static int | |
215 | dwcmmc_fdt_card_detect(struct dwc_mmc_softc *sc) | 214 | dwcmmc_fdt_card_detect(struct dwc_mmc_softc *sc) | |
216 | { | 215 | { | |
217 | struct dwcmmc_fdt_softc *esc = device_private(sc->sc_dev); | 216 | struct dwcmmc_fdt_softc *esc = device_private(sc->sc_dev); | |
218 | 217 | |||
219 | KASSERT(esc->sc_pin_cd != NULL); | 218 | KASSERT(esc->sc_pin_cd != NULL); | |
220 | 219 | |||
221 | return fdtbus_gpio_read(esc->sc_pin_cd); | 220 | return fdtbus_gpio_read(esc->sc_pin_cd); | |
222 | } | 221 | } | |
223 | 222 | |||
224 | static int | 223 | static int | |
225 | dwcmmc_fdt_bus_clock(struct dwc_mmc_softc *sc, int rate) | 224 | dwcmmc_fdt_bus_clock(struct dwc_mmc_softc *sc, int rate) | |
226 | { | 225 | { | |
227 | struct dwcmmc_fdt_softc *esc = device_private(sc->sc_dev); | 226 | struct dwcmmc_fdt_softc *esc = device_private(sc->sc_dev); | |
228 | const u_int ciu_div = sc->sc_ciu_div > 0 ? sc->sc_ciu_div : 1; | 227 | const u_int ciu_div = sc->sc_ciu_div > 0 ? sc->sc_ciu_div : 1; | |
229 | int error; | 228 | int error; | |
230 | 229 | |||
231 | error = clk_set_rate(esc->sc_clk_ciu, 1000 * rate * ciu_div); | 230 | error = clk_set_rate(esc->sc_clk_ciu, 1000 * rate * ciu_div); | |
232 | if (error != 0) { | 231 | if (error != 0) { | |
233 | aprint_error_dev(sc->sc_dev, "failed to set rate to %u kHz: %d\n", | 232 | aprint_error_dev(sc->sc_dev, "failed to set rate to %u kHz: %d\n", | |
234 | rate * ciu_div, error); | 233 | rate * ciu_div, error); | |
235 | return error; | 234 | return error; | |
236 | } | 235 | } | |
237 | 236 | |||
238 | sc->sc_clock_freq = clk_get_rate(esc->sc_clk_ciu); | 237 | sc->sc_clock_freq = clk_get_rate(esc->sc_clk_ciu); | |
239 | 238 | |||
240 | aprint_debug_dev(sc->sc_dev, "set clock rate to %u kHz (target %u kHz)\n", | 239 | aprint_debug_dev(sc->sc_dev, "set clock rate to %u kHz (target %u kHz)\n", | |
241 | sc->sc_clock_freq, rate); | 240 | sc->sc_clock_freq, rate); | |
242 | 241 | |||
243 | return 0; | 242 | return 0; | |
244 | } | 243 | } | |
245 | 244 | |||
246 | static int | 245 | static int | |
247 | dwcmmc_fdt_signal_voltage(struct dwc_mmc_softc *sc, int signal_voltage) | 246 | dwcmmc_fdt_signal_voltage(struct dwc_mmc_softc *sc, int signal_voltage) | |
248 | { | 247 | { | |
249 | struct dwcmmc_fdt_softc *esc = device_private(sc->sc_dev); | 248 | struct dwcmmc_fdt_softc *esc = device_private(sc->sc_dev); | |
250 | u_int uvol; | 249 | u_int uvol; | |
251 | int error; | 250 | int error; | |
252 | 251 | |||
253 | if (esc->sc_vqmmc == NULL) | 252 | if (esc->sc_vqmmc == NULL) | |
254 | return 0; | 253 | return 0; | |
255 | 254 | |||
256 | switch (signal_voltage) { | 255 | switch (signal_voltage) { | |
257 | case SDMMC_SIGNAL_VOLTAGE_180: | 256 | case SDMMC_SIGNAL_VOLTAGE_180: | |
258 | uvol = 1800000; | 257 | uvol = 1800000; | |
259 | break; | 258 | break; | |
260 | case SDMMC_SIGNAL_VOLTAGE_330: | 259 | case SDMMC_SIGNAL_VOLTAGE_330: | |
261 | uvol = 3300000; | 260 | uvol = 3300000; | |
262 | break; | 261 | break; | |
263 | default: | 262 | default: | |
264 | return EINVAL; | 263 | return EINVAL; | |
265 | } | 264 | } | |
266 | 265 | |||
267 | error = fdtbus_regulator_supports_voltage(esc->sc_vqmmc, uvol, uvol); | 266 | error = fdtbus_regulator_supports_voltage(esc->sc_vqmmc, uvol, uvol); | |
268 | if (error != 0) | 267 | if (error != 0) | |
269 | return 0; | 268 | return 0; | |
270 | 269 | |||
271 | error = fdtbus_regulator_set_voltage(esc->sc_vqmmc, uvol, uvol); | 270 | error = fdtbus_regulator_set_voltage(esc->sc_vqmmc, uvol, uvol); | |
272 | if (error != 0) | 271 | if (error != 0) | |
273 | return error; | 272 | return error; | |
274 | 273 | |||
275 | return fdtbus_regulator_enable(esc->sc_vqmmc); | 274 | return fdtbus_regulator_enable(esc->sc_vqmmc); | |
276 | } | 275 | } |
--- src/sys/dev/fdt/ns8250_uart.c 2021/01/18 02:35:49 1.4
+++ src/sys/dev/fdt/ns8250_uart.c 2021/01/25 14:25:09 1.5
@@ -1,225 +1,224 @@ | @@ -1,225 +1,224 @@ | |||
1 | /* $NetBSD: ns8250_uart.c,v 1.4 2021/01/18 02:35:49 thorpej Exp $ */ | 1 | /* $NetBSD: ns8250_uart.c,v 1.5 2021/01/25 14:25:09 thorpej Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2017-2020 Jared McNeill <jmcneill@invisible.ca> | 4 | * Copyright (c) 2017-2020 Jared 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. | |
15 | * | 15 | * | |
16 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | 16 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | |
17 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 17 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | 19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
26 | * POSSIBILITY OF SUCH DAMAGE. | 26 | * POSSIBILITY OF SUCH DAMAGE. | |
27 | */ | 27 | */ | |
28 | 28 | |||
29 | #include <sys/cdefs.h> | 29 | #include <sys/cdefs.h> | |
30 | 30 | |||
31 | __KERNEL_RCSID(1, "$NetBSD: ns8250_uart.c,v 1.4 2021/01/18 02:35:49 thorpej Exp $"); | 31 | __KERNEL_RCSID(1, "$NetBSD: ns8250_uart.c,v 1.5 2021/01/25 14:25:09 thorpej Exp $"); | |
32 | 32 | |||
33 | #include <sys/param.h> | 33 | #include <sys/param.h> | |
34 | #include <sys/bus.h> | 34 | #include <sys/bus.h> | |
35 | #include <sys/device.h> | 35 | #include <sys/device.h> | |
36 | #include <sys/intr.h> | 36 | #include <sys/intr.h> | |
37 | #include <sys/systm.h> | 37 | #include <sys/systm.h> | |
38 | #include <sys/time.h> | 38 | #include <sys/time.h> | |
39 | #include <sys/termios.h> | 39 | #include <sys/termios.h> | |
40 | 40 | |||
41 | #include <dev/ic/comvar.h> | 41 | #include <dev/ic/comvar.h> | |
42 | 42 | |||
43 | #include <dev/fdt/fdtvar.h> | 43 | #include <dev/fdt/fdtvar.h> | |
44 | 44 | |||
45 | static int ns8250_uart_match(device_t, cfdata_t, void *); | 45 | static int ns8250_uart_match(device_t, cfdata_t, void *); | |
46 | static void ns8250_uart_attach(device_t, device_t, void *); | 46 | static void ns8250_uart_attach(device_t, device_t, void *); | |
47 | 47 | |||
48 | struct ns8250_config { | 48 | struct ns8250_config { | |
49 | int type; | 49 | int type; | |
50 | int (*enable)(struct com_softc *); | 50 | int (*enable)(struct com_softc *); | |
51 | void (*disable)(struct com_softc *); | 51 | void (*disable)(struct com_softc *); | |
52 | }; | 52 | }; | |
53 | 53 | |||
54 | static const struct ns8250_config ns8250_config = { | 54 | static const struct ns8250_config ns8250_config = { | |
55 | .type = COM_TYPE_NORMAL, | 55 | .type = COM_TYPE_NORMAL, | |
56 | }; | 56 | }; | |
57 | 57 | |||
58 | static const struct ns8250_config ns16750_config = { | 58 | static const struct ns8250_config ns16750_config = { | |
59 | .type = COM_TYPE_16750, | 59 | .type = COM_TYPE_16750, | |
60 | }; | 60 | }; | |
61 | 61 | |||
62 | #define NS8250_OCTEON_USR_REG 0x0138 | 62 | #define NS8250_OCTEON_USR_REG 0x0138 | |
63 | 63 | |||
64 | static int | 64 | static int | |
65 | ns8250_octeon_enable(struct com_softc *sc) | 65 | ns8250_octeon_enable(struct com_softc *sc) | |
66 | { | 66 | { | |
67 | struct com_regs *regsp = &sc->sc_regs; | 67 | struct com_regs *regsp = &sc->sc_regs; | |
68 | 68 | |||
69 | /* XXX Clear old busy detect interrupts */ | 69 | /* XXX Clear old busy detect interrupts */ | |
70 | bus_space_read_1(regsp->cr_iot, regsp->cr_ioh, NS8250_OCTEON_USR_REG); | 70 | bus_space_read_1(regsp->cr_iot, regsp->cr_ioh, NS8250_OCTEON_USR_REG); | |
71 | 71 | |||
72 | return 0; | 72 | return 0; | |
73 | } | 73 | } | |
74 | 74 | |||
75 | static const struct ns8250_config octeon_config = { | 75 | static const struct ns8250_config octeon_config = { | |
76 | .type = COM_TYPE_16550_NOERS, | 76 | .type = COM_TYPE_16550_NOERS, | |
77 | .enable = ns8250_octeon_enable, | 77 | .enable = ns8250_octeon_enable, | |
78 | }; | 78 | }; | |
79 | 79 | |||
80 | static const struct device_compatible_entry compat_data[] = { | 80 | static const struct device_compatible_entry compat_data[] = { | |
81 | { .compat = "cavium,octeon-3860-uart", .data = &octeon_config }, | 81 | { .compat = "cavium,octeon-3860-uart", .data = &octeon_config }, | |
82 | { .compat = "ns8250", .data = &ns8250_config }, | 82 | { .compat = "ns8250", .data = &ns8250_config }, | |
83 | { .compat = "ns16450", .data = &ns8250_config }, | 83 | { .compat = "ns16450", .data = &ns8250_config }, | |
84 | { .compat = "ns16550a", .data = &ns8250_config }, | 84 | { .compat = "ns16550a", .data = &ns8250_config }, | |
85 | { .compat = "ns16550", .data = &ns8250_config }, | 85 | { .compat = "ns16550", .data = &ns8250_config }, | |
86 | { .compat = "ns16750", .data = &ns16750_config }, | 86 | { .compat = "ns16750", .data = &ns16750_config }, | |
87 | 87 | { } | ||
88 | { 0 } | |||
89 | }; | 88 | }; | |
90 | 89 | |||
91 | CFATTACH_DECL_NEW(ns8250_uart, sizeof(struct com_softc), | 90 | CFATTACH_DECL_NEW(ns8250_uart, sizeof(struct com_softc), | |
92 | ns8250_uart_match, ns8250_uart_attach, NULL, NULL); | 91 | ns8250_uart_match, ns8250_uart_attach, NULL, NULL); | |
93 | 92 | |||
94 | static int | 93 | static int | |
95 | ns8250_uart_match(device_t parent, cfdata_t cf, void *aux) | 94 | ns8250_uart_match(device_t parent, cfdata_t cf, void *aux) | |
96 | { | 95 | { | |
97 | struct fdt_attach_args * const faa = aux; | 96 | struct fdt_attach_args * const faa = aux; | |
98 | 97 | |||
99 | return of_match_compat_data(faa->faa_phandle, compat_data); | 98 | return of_match_compat_data(faa->faa_phandle, compat_data); | |
100 | } | 99 | } | |
101 | 100 | |||
102 | static void | 101 | static void | |
103 | ns8250_uart_attach(device_t parent, device_t self, void *aux) | 102 | ns8250_uart_attach(device_t parent, device_t self, void *aux) | |
104 | { | 103 | { | |
105 | struct com_softc * const sc = device_private(self); | 104 | struct com_softc * const sc = device_private(self); | |
106 | struct fdt_attach_args * const faa = aux; | 105 | struct fdt_attach_args * const faa = aux; | |
107 | const int phandle = faa->faa_phandle; | 106 | const int phandle = faa->faa_phandle; | |
108 | bus_space_tag_t bst = faa->faa_bst; | 107 | bus_space_tag_t bst = faa->faa_bst; | |
109 | bus_space_handle_t bsh; | 108 | bus_space_handle_t bsh; | |
110 | char intrstr[128]; | 109 | char intrstr[128]; | |
111 | struct clk *clk; | 110 | struct clk *clk; | |
112 | bus_addr_t addr; | 111 | bus_addr_t addr; | |
113 | bus_size_t size; | 112 | bus_size_t size; | |
114 | u_int reg_shift; | 113 | u_int reg_shift; | |
115 | int error; | 114 | int error; | |
116 | void *ih; | 115 | void *ih; | |
117 | 116 | |||
118 | const struct ns8250_config *config = | 117 | const struct ns8250_config *config = | |
119 | of_search_compatible(phandle, compat_data)->data; | 118 | of_search_compatible(phandle, compat_data)->data; | |
120 | 119 | |||
121 | if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { | 120 | if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { | |
122 | aprint_error(": couldn't get registers\n"); | 121 | aprint_error(": couldn't get registers\n"); | |
123 | return; | 122 | return; | |
124 | } | 123 | } | |
125 | 124 | |||
126 | if (of_getprop_uint32(phandle, "reg-shift", ®_shift)) { | 125 | if (of_getprop_uint32(phandle, "reg-shift", ®_shift)) { | |
127 | /* missing or bad reg-shift property, assume 0 */ | 126 | /* missing or bad reg-shift property, assume 0 */ | |
128 | reg_shift = 0; | 127 | reg_shift = 0; | |
129 | } | 128 | } | |
130 | 129 | |||
131 | sc->sc_dev = self; | 130 | sc->sc_dev = self; | |
132 | if (of_getprop_uint32(phandle, "clock-frequency", &sc->sc_frequency)) { | 131 | if (of_getprop_uint32(phandle, "clock-frequency", &sc->sc_frequency)) { | |
133 | clk = fdtbus_clock_get_index(phandle, 0); | 132 | clk = fdtbus_clock_get_index(phandle, 0); | |
134 | if (clk != NULL) | 133 | if (clk != NULL) | |
135 | sc->sc_frequency = clk_get_rate(clk); | 134 | sc->sc_frequency = clk_get_rate(clk); | |
136 | } | 135 | } | |
137 | if (sc->sc_frequency == 0) { | 136 | if (sc->sc_frequency == 0) { | |
138 | aprint_error(": couldn't get frequency\n"); | 137 | aprint_error(": couldn't get frequency\n"); | |
139 | return; | 138 | return; | |
140 | } | 139 | } | |
141 | 140 | |||
142 | sc->sc_type = config->type; | 141 | sc->sc_type = config->type; | |
143 | sc->enable = config->enable; | 142 | sc->enable = config->enable; | |
144 | sc->disable = config->disable; | 143 | sc->disable = config->disable; | |
145 | 144 | |||
146 | error = bus_space_map(bst, addr, size, 0, &bsh); | 145 | error = bus_space_map(bst, addr, size, 0, &bsh); | |
147 | if (error) { | 146 | if (error) { | |
148 | aprint_error(": couldn't map %#" PRIx64 ": %d", | 147 | aprint_error(": couldn't map %#" PRIx64 ": %d", | |
149 | (uint64_t)addr, error); | 148 | (uint64_t)addr, error); | |
150 | return; | 149 | return; | |
151 | } | 150 | } | |
152 | 151 | |||
153 | com_init_regs_stride(&sc->sc_regs, bst, bsh, addr, reg_shift); | 152 | com_init_regs_stride(&sc->sc_regs, bst, bsh, addr, reg_shift); | |
154 | 153 | |||
155 | if (config->enable != NULL) { | 154 | if (config->enable != NULL) { | |
156 | sc->enable(sc); | 155 | sc->enable(sc); | |
157 | sc->enabled = 1; | 156 | sc->enabled = 1; | |
158 | } | 157 | } | |
159 | 158 | |||
160 | com_attach_subr(sc); | 159 | com_attach_subr(sc); | |
161 | 160 | |||
162 | if (!fdtbus_intr_str(faa->faa_phandle, 0, intrstr, sizeof(intrstr))) { | 161 | if (!fdtbus_intr_str(faa->faa_phandle, 0, intrstr, sizeof(intrstr))) { | |
163 | aprint_error_dev(self, "failed to decode interrupt\n"); | 162 | aprint_error_dev(self, "failed to decode interrupt\n"); | |
164 | return; | 163 | return; | |
165 | } | 164 | } | |
166 | 165 | |||
167 | ih = fdtbus_intr_establish_xname(faa->faa_phandle, 0, IPL_SERIAL, | 166 | ih = fdtbus_intr_establish_xname(faa->faa_phandle, 0, IPL_SERIAL, | |
168 | FDT_INTR_MPSAFE, comintr, sc, device_xname(self)); | 167 | FDT_INTR_MPSAFE, comintr, sc, device_xname(self)); | |
169 | if (ih == NULL) { | 168 | if (ih == NULL) { | |
170 | aprint_error_dev(self, "failed to establish interrupt on %s\n", | 169 | aprint_error_dev(self, "failed to establish interrupt on %s\n", | |
171 | intrstr); | 170 | intrstr); | |
172 | return; | 171 | return; | |
173 | } | 172 | } | |
174 | aprint_normal_dev(self, "interrupting on %s\n", intrstr); | 173 | aprint_normal_dev(self, "interrupting on %s\n", intrstr); | |
175 | } | 174 | } | |
176 | 175 | |||
177 | /* | 176 | /* | |
178 | * Console support | 177 | * Console support | |
179 | */ | 178 | */ | |
180 | 179 | |||
181 | static int | 180 | static int | |
182 | ns8250_uart_console_match(int phandle) | 181 | ns8250_uart_console_match(int phandle) | |
183 | { | 182 | { | |
184 | return of_match_compat_data(phandle, compat_data); | 183 | return of_match_compat_data(phandle, compat_data); | |
185 | } | 184 | } | |
186 | 185 | |||
187 | static void | 186 | static void | |
188 | ns8250_uart_console_consinit(struct fdt_attach_args *faa, u_int uart_freq) | 187 | ns8250_uart_console_consinit(struct fdt_attach_args *faa, u_int uart_freq) | |
189 | { | 188 | { | |
190 | const int phandle = faa->faa_phandle; | 189 | const int phandle = faa->faa_phandle; | |
191 | bus_space_tag_t bst = faa->faa_bst; | 190 | bus_space_tag_t bst = faa->faa_bst; | |
192 | bus_space_handle_t dummy_bsh; | 191 | bus_space_handle_t dummy_bsh; | |
193 | struct com_regs regs; | 192 | struct com_regs regs; | |
194 | bus_addr_t addr; | 193 | bus_addr_t addr; | |
195 | tcflag_t flags; | 194 | tcflag_t flags; | |
196 | u_int reg_shift; | 195 | u_int reg_shift; | |
197 | int speed; | 196 | int speed; | |
198 | 197 | |||
199 | const struct ns8250_config *config = | 198 | const struct ns8250_config *config = | |
200 | of_search_compatible(phandle, compat_data)->data; | 199 | of_search_compatible(phandle, compat_data)->data; | |
201 | 200 | |||
202 | fdtbus_get_reg(phandle, 0, &addr, NULL); | 201 | fdtbus_get_reg(phandle, 0, &addr, NULL); | |
203 | speed = fdtbus_get_stdout_speed(); | 202 | speed = fdtbus_get_stdout_speed(); | |
204 | if (speed < 0) | 203 | if (speed < 0) | |
205 | speed = 115200; /* default */ | 204 | speed = 115200; /* default */ | |
206 | flags = fdtbus_get_stdout_flags(); | 205 | flags = fdtbus_get_stdout_flags(); | |
207 | 206 | |||
208 | if (of_getprop_uint32(phandle, "reg-shift", ®_shift)) { | 207 | if (of_getprop_uint32(phandle, "reg-shift", ®_shift)) { | |
209 | /* missing or bad reg-shift property, assume 0 */ | 208 | /* missing or bad reg-shift property, assume 0 */ | |
210 | reg_shift = 0; | 209 | reg_shift = 0; | |
211 | } | 210 | } | |
212 | 211 | |||
213 | memset(&dummy_bsh, 0, sizeof(dummy_bsh)); | 212 | memset(&dummy_bsh, 0, sizeof(dummy_bsh)); | |
214 | com_init_regs_stride(®s, bst, dummy_bsh, addr, reg_shift); | 213 | com_init_regs_stride(®s, bst, dummy_bsh, addr, reg_shift); | |
215 | 214 | |||
216 | if (comcnattach1(®s, speed, uart_freq, config->type, flags)) | 215 | if (comcnattach1(®s, speed, uart_freq, config->type, flags)) | |
217 | panic("Cannot initialize ns8250 console"); | 216 | panic("Cannot initialize ns8250 console"); | |
218 | } | 217 | } | |
219 | 218 | |||
220 | static const struct fdt_console ns8250_uart_console = { | 219 | static const struct fdt_console ns8250_uart_console = { | |
221 | .match = ns8250_uart_console_match, | 220 | .match = ns8250_uart_console_match, | |
222 | .consinit = ns8250_uart_console_consinit, | 221 | .consinit = ns8250_uart_console_consinit, | |
223 | }; | 222 | }; | |
224 | 223 | |||
225 | FDT_CONSOLE(ns8250_uart, &ns8250_uart_console); | 224 | FDT_CONSOLE(ns8250_uart, &ns8250_uart_console); |