1*4613293aSryo /* $NetBSD: autoconf.c,v 1.6 2016/10/05 15:54:58 ryo Exp $ */
29c6e0201Smatt /*-
39c6e0201Smatt * Copyright (c) 2011 CradlePoint Technology, Inc.
49c6e0201Smatt * All rights reserved.
59c6e0201Smatt *
69c6e0201Smatt *
79c6e0201Smatt * Redistribution and use in source and binary forms, with or without
89c6e0201Smatt * modification, are permitted provided that the following conditions
99c6e0201Smatt * are met:
109c6e0201Smatt * 1. Redistributions of source code must retain the above copyright
119c6e0201Smatt * notice, this list of conditions and the following disclaimer.
129c6e0201Smatt * 2. Redistributions in binary form must reproduce the above copyright
139c6e0201Smatt * notice, this list of conditions and the following disclaimer in the
149c6e0201Smatt * documentation and/or other materials provided with the distribution.
159c6e0201Smatt *
169c6e0201Smatt * THIS SOFTWARE IS PROVIDED BY CRADLEPOINT TECHNOLOGY, INC. AND CONTRIBUTORS
179c6e0201Smatt * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
189c6e0201Smatt * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
199c6e0201Smatt * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
209c6e0201Smatt * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
219c6e0201Smatt * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
229c6e0201Smatt * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
239c6e0201Smatt * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
249c6e0201Smatt * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
259c6e0201Smatt * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
269c6e0201Smatt * POSSIBILITY OF SUCH DAMAGE.
279c6e0201Smatt */
289c6e0201Smatt
299c6e0201Smatt #include <sys/cdefs.h>
30*4613293aSryo __KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.6 2016/10/05 15:54:58 ryo Exp $");
319c6e0201Smatt
329c6e0201Smatt #include <sys/param.h>
339c6e0201Smatt #include <sys/bus.h>
349c6e0201Smatt #include <sys/conf.h>
359c6e0201Smatt #include <sys/device.h>
369c6e0201Smatt #include <sys/systm.h>
379c6e0201Smatt
381b6521b4Smatt #include <mips/ralink/ralink_reg.h>
391b6521b4Smatt #include <mips/ralink/ralink_var.h>
401b6521b4Smatt
419c6e0201Smatt /*
429c6e0201Smatt * Configure all devices on system
439c6e0201Smatt */
449c6e0201Smatt void
cpu_configure(void)459c6e0201Smatt cpu_configure(void)
469c6e0201Smatt {
479c6e0201Smatt intr_init();
489c6e0201Smatt
499c6e0201Smatt /* Kick off autoconfiguration. */
509c6e0201Smatt if (config_rootfound("mainbus", NULL) == NULL)
519c6e0201Smatt panic("no mainbus found");
529c6e0201Smatt
539c6e0201Smatt /*
549c6e0201Smatt * Hardware interrupts will be enabled in
559c6e0201Smatt * sys/arch/mips/mips/mips3_clockintr.c:mips3_initclocks()
569c6e0201Smatt * to avoid hardclock(9) by CPU INT5 before softclockintr is
579c6e0201Smatt * initialized in initclocks().
589c6e0201Smatt */
599c6e0201Smatt }
609c6e0201Smatt
619c6e0201Smatt void
cpu_rootconf(void)629c6e0201Smatt cpu_rootconf(void)
639c6e0201Smatt {
648ce44338Smlelstv rootconf();
659c6e0201Smatt }
669c6e0201Smatt
671b6521b4Smatt static const struct cfg_info {
681b6521b4Smatt const char *map_name;
691b6521b4Smatt uint32_t map_rst;
701b6521b4Smatt uint32_t map_clkcfg1;
711b6521b4Smatt } map_info[] = {
72*4613293aSryo #if defined(MT7628)
73*4613293aSryo { "rpci", RST_PCIE0_7620, SYSCTL_CLKCFG1_PCIE_CLK_EN_7620 },
74*4613293aSryo { "ohci", RST_UHST0_7620|RST_UHST,
75*4613293aSryo SYSCTL_CLKCFG1_UPHY0_CLK_EN_7620|SYSCTL_CLKCFG1_UPHY0_CLK_EN_7628 },
76*4613293aSryo { "ehci", RST_UHST0_7620|RST_UHST,
77*4613293aSryo SYSCTL_CLKCFG1_UPHY0_CLK_EN_7620|SYSCTL_CLKCFG1_UPHY0_CLK_EN_7628 },
78*4613293aSryo { "sdhc", RST_SDHC_7620, SYSCTL_CLKCFG1_SDHC_CLK_EN },
79*4613293aSryo { "rsw", RST_ESW_7620, SYSCTL_CLKCFG1_ESW_CLK_EN },
80*4613293aSryo #endif
811b6521b4Smatt #if defined(MT7620)
821b6521b4Smatt { "rpci", RST_PCIE0_7620, SYSCTL_CLKCFG1_PCIE_CLK_EN_7620 },
831b6521b4Smatt { "ohci", RST_UHST0_7620|RST_UHST, SYSCTL_CLKCFG1_UPHY0_CLK_EN_7620 },
841b6521b4Smatt { "ehci", RST_UHST0_7620|RST_UHST, SYSCTL_CLKCFG1_UPHY0_CLK_EN_7620 },
851b6521b4Smatt { "sdhc", RST_SDHC_7620, SYSCTL_CLKCFG1_SDHC_CLK_EN },
861b6521b4Smatt { "rsw", RST_ESW_7620, SYSCTL_CLKCFG1_ESW_CLK_EN },
871b6521b4Smatt #endif
881b6521b4Smatt #if defined(RT3883)
891b6521b4Smatt { "rpci", RST_PCI_3883 | RST_PCIPCIE_3883,
901b6521b4Smatt SYSCTL_CLKCFG1_PCI_CLK_EN|SYSCTL_CLKCFG1_PCIE_CLK_EN_3883 },
911b6521b4Smatt { "ohci", RST_UHST, SYSCTL_CLKCFG1_UPHY0_CLK_EN_3883 },
921b6521b4Smatt { "ehci", RST_UHST, SYSCTL_CLKCFG1_UPHY0_CLK_EN_3883 },
931b6521b4Smatt #endif
941b6521b4Smatt };
951b6521b4Smatt
961b6521b4Smatt static void
ra_device_fixup(bus_space_tag_t bst,const struct cfg_info * map)971b6521b4Smatt ra_device_fixup(bus_space_tag_t bst, const struct cfg_info *map)
989c6e0201Smatt {
991b6521b4Smatt const uint32_t clkcfg1 = bus_space_read_4(bst, ra_sysctl_bsh,
1001b6521b4Smatt RA_SYSCTL_CLKCFG1);
1011b6521b4Smatt if ((clkcfg1 & map->map_clkcfg1) != map->map_clkcfg1) {
1021b6521b4Smatt bus_space_write_4(bst, ra_sysctl_bsh, RA_SYSCTL_CLKCFG1,
1031b6521b4Smatt clkcfg1 | map->map_clkcfg1);
1041b6521b4Smatt delay(10000);
1051b6521b4Smatt }
1061b6521b4Smatt
1071b6521b4Smatt const uint32_t rst = bus_space_read_4(bst, ra_sysctl_bsh,
1081b6521b4Smatt RA_SYSCTL_RST);
1091b6521b4Smatt if ((rst & map->map_rst) != 0) {
1101b6521b4Smatt bus_space_write_4(bst, ra_sysctl_bsh, RA_SYSCTL_RST,
1111b6521b4Smatt rst & ~map->map_rst);
1121b6521b4Smatt delay(10000);
1131b6521b4Smatt }
1141b6521b4Smatt }
1151b6521b4Smatt
1161b6521b4Smatt void
device_register(device_t self,void * aux)1171b6521b4Smatt device_register(device_t self, void *aux)
1181b6521b4Smatt {
1191b6521b4Smatt device_t parent = device_parent(self);
1201b6521b4Smatt
1211b6521b4Smatt if (parent != NULL && device_is_a(parent, "mainbus")) {
1221b6521b4Smatt // If we are attaching a mainbus device, see if we know how
1231b6521b4Smatt // to bring it out of reset.
1241b6521b4Smatt struct mainbus_attach_args * const ma = aux;
1251b6521b4Smatt for (const struct cfg_info *map = map_info;
1261b6521b4Smatt map < map_info + __arraycount(map_info);
1271b6521b4Smatt map++) {
1281b6521b4Smatt if (device_is_a(self, map->map_name)) {
1291b6521b4Smatt ra_device_fixup(ma->ma_memt, map);
1301b6521b4Smatt delay(1000);
1311b6521b4Smatt break;
1321b6521b4Smatt }
1331b6521b4Smatt }
1341b6521b4Smatt
1351b6521b4Smatt #if defined(RT3883) || defined(MT7620)
1361b6521b4Smatt if (device_is_a(self, "ohci") || device_is_a(self, "ehci")) {
1371b6521b4Smatt const uint32_t cfg1 = bus_space_read_4(ma->ma_memt,
1381b6521b4Smatt ra_sysctl_bsh, RA_SYSCTL_CFG1);
1391b6521b4Smatt if ((cfg1 & SYSCTL_CFG1_USB0_HOST_MODE) == 0) {
1401b6521b4Smatt bus_space_write_4(ma->ma_memt, ra_sysctl_bsh,
1411b6521b4Smatt RA_SYSCTL_CFG1,
1421b6521b4Smatt cfg1 | SYSCTL_CFG1_USB0_HOST_MODE);
1431b6521b4Smatt delay(10);
1441b6521b4Smatt }
1451b6521b4Smatt }
1461b6521b4Smatt #endif
1471b6521b4Smatt }
1489c6e0201Smatt }
149