tegra124_xusbpadctl.c (332010) | tegra124_xusbpadctl.c (332025) |
---|---|
1/*- 2 * Copyright (c) 2016 Michal Meloun <mmel@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 8 unchanged lines hidden (view full) --- 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. | 1/*- 2 * Copyright (c) 2016 Michal Meloun <mmel@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 8 unchanged lines hidden (view full) --- 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. |
25 * 26 * $FreeBSD: stable/11/sys/arm/nvidia/tegra124/tegra124_xusbpadctl.c 332010 2018-04-04 11:30:20Z mmel $ | |
27 */ 28 | 25 */ 26 |
27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD: stable/11/sys/arm/nvidia/tegra124/tegra124_xusbpadctl.c 332025 2018-04-04 13:23:06Z mmel $"); 29 |
|
29#include <sys/param.h> 30#include <sys/systm.h> 31#include <sys/bus.h> 32#include <sys/kernel.h> 33#include <sys/module.h> 34#include <sys/malloc.h> 35#include <sys/rman.h> 36 --- 8 unchanged lines hidden (view full) --- 45#include <dev/ofw/openfirm.h> 46#include <dev/ofw/ofw_bus.h> 47#include <dev/ofw/ofw_bus_subr.h> 48 49#include <arm/nvidia/tegra_efuse.h> 50 51#include <gnu/dts/include/dt-bindings/pinctrl/pinctrl-tegra-xusb.h> 52 | 30#include <sys/param.h> 31#include <sys/systm.h> 32#include <sys/bus.h> 33#include <sys/kernel.h> 34#include <sys/module.h> 35#include <sys/malloc.h> 36#include <sys/rman.h> 37 --- 8 unchanged lines hidden (view full) --- 46#include <dev/ofw/openfirm.h> 47#include <dev/ofw/ofw_bus.h> 48#include <dev/ofw/ofw_bus_subr.h> 49 50#include <arm/nvidia/tegra_efuse.h> 51 52#include <gnu/dts/include/dt-bindings/pinctrl/pinctrl-tegra-xusb.h> 53 |
53#include "phy_if.h" | 54#include "phydev_if.h" |
54 55/* FUSE calibration data. */ 56#define FUSE_XUSB_CALIB 0x0F0 57#define FUSE_XUSB_CALIB_HS_CURR_LEVEL_123(x) (((x) >> 15) & 0x3F); 58#define FUSE_XUSB_CALIB_HS_IREF_CAP(x) (((x) >> 13) & 0x03); 59#define FUSE_XUSB_CALIB_HS_SQUELCH_LEVEL(x) (((x) >> 11) & 0x03); 60#define FUSE_XUSB_CALIB_HS_TERM_RANGE_ADJ(x) (((x) >> 7) & 0x0F); 61#define FUSE_XUSB_CALIB_HS_CURR_LEVEL_0(x) (((x) >> 0) & 0x3F); --- 149 unchanged lines hidden (view full) --- 211 enum padctl_port_type type; 212 const char *name; 213 const char *base_name; 214 int idx; 215 int (*init)(struct padctl_softc *sc, 216 struct padctl_port *port); 217 218 /* Runtime data. */ | 55 56/* FUSE calibration data. */ 57#define FUSE_XUSB_CALIB 0x0F0 58#define FUSE_XUSB_CALIB_HS_CURR_LEVEL_123(x) (((x) >> 15) & 0x3F); 59#define FUSE_XUSB_CALIB_HS_IREF_CAP(x) (((x) >> 13) & 0x03); 60#define FUSE_XUSB_CALIB_HS_SQUELCH_LEVEL(x) (((x) >> 11) & 0x03); 61#define FUSE_XUSB_CALIB_HS_TERM_RANGE_ADJ(x) (((x) >> 7) & 0x0F); 62#define FUSE_XUSB_CALIB_HS_CURR_LEVEL_0(x) (((x) >> 0) & 0x3F); --- 149 unchanged lines hidden (view full) --- 212 enum padctl_port_type type; 213 const char *name; 214 const char *base_name; 215 int idx; 216 int (*init)(struct padctl_softc *sc, 217 struct padctl_port *port); 218 219 /* Runtime data. */ |
219 phandle_t xref; | |
220 bool enabled; 221 regulator_t supply_vbus; /* USB2, USB3 */ 222 bool internal; /* ULPI, USB2, USB3 */ 223 uint32_t companion; /* USB3 */ 224 struct padctl_lane *lane; 225}; 226 227static int usb3_port_init(struct padctl_softc *sc, struct padctl_port *port); --- 70 unchanged lines hidden (view full) --- 298 int idx; 299 bus_size_t reg; 300 uint32_t shift; 301 uint32_t mask; 302 char **mux; 303 int nmux; 304 /* Runtime data. */ 305 bool enabled; | 220 bool enabled; 221 regulator_t supply_vbus; /* USB2, USB3 */ 222 bool internal; /* ULPI, USB2, USB3 */ 223 uint32_t companion; /* USB3 */ 224 struct padctl_lane *lane; 225}; 226 227static int usb3_port_init(struct padctl_softc *sc, struct padctl_port *port); --- 70 unchanged lines hidden (view full) --- 298 int idx; 299 bus_size_t reg; 300 uint32_t shift; 301 uint32_t mask; 302 char **mux; 303 int nmux; 304 /* Runtime data. */ 305 bool enabled; |
306 phandle_t xref; | |
307 struct padctl_pad *pad; 308 struct padctl_port *port; 309 int mux_idx; 310 311}; 312 313#define LANE(n, p, r, s, m, mx) { \ 314 .name = n "-" #p, \ --- 33 unchanged lines hidden (view full) --- 348} 349static struct padctl_lane_map lane_map_tbl[] = { 350 LANE_MAP(0, PADCTL_PAD_PCIE, 0), /* port USB3-0 -> lane PCIE-0 */ 351 LANE_MAP(1, PADCTL_PAD_PCIE, 1), /* port USB3-1 -> lane PCIE-1 */ 352 /* -- or -- */ 353 LANE_MAP(1, PADCTL_PAD_SATA, 0), /* port USB3-1 -> lane SATA-0 */ 354}; 355 | 306 struct padctl_pad *pad; 307 struct padctl_port *port; 308 int mux_idx; 309 310}; 311 312#define LANE(n, p, r, s, m, mx) { \ 313 .name = n "-" #p, \ --- 33 unchanged lines hidden (view full) --- 347} 348static struct padctl_lane_map lane_map_tbl[] = { 349 LANE_MAP(0, PADCTL_PAD_PCIE, 0), /* port USB3-0 -> lane PCIE-0 */ 350 LANE_MAP(1, PADCTL_PAD_PCIE, 1), /* port USB3-1 -> lane PCIE-1 */ 351 /* -- or -- */ 352 LANE_MAP(1, PADCTL_PAD_SATA, 0), /* port USB3-1 -> lane SATA-0 */ 353}; 354 |
355 /* Phy class and methods. */ 356static int xusbpadctl_phy_enable(struct phynode *phy, bool enable); 357static phynode_method_t xusbpadctl_phynode_methods[] = { 358 PHYNODEMETHOD(phynode_enable, xusbpadctl_phy_enable), 359 PHYNODEMETHOD_END 360 361}; 362DEFINE_CLASS_1(xusbpadctl_phynode, xusbpadctl_phynode_class, 363 xusbpadctl_phynode_methods, 0, phynode_class); 364 |
|
356static struct padctl_port *search_lane_port(struct padctl_softc *sc, 357 struct padctl_lane *lane); 358/* ------------------------------------------------------------------------- 359 * 360 * PHY functions 361 */ 362static int 363usb3_port_init(struct padctl_softc *sc, struct padctl_port *port) --- 314 unchanged lines hidden (view full) --- 678 reg |= ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN; 679 WR4(sc, XUSB_PADCTL_ELPG_PROGRAM, reg); 680 DELAY(100); 681 682 return (0); 683} 684 685static int | 365static struct padctl_port *search_lane_port(struct padctl_softc *sc, 366 struct padctl_lane *lane); 367/* ------------------------------------------------------------------------- 368 * 369 * PHY functions 370 */ 371static int 372usb3_port_init(struct padctl_softc *sc, struct padctl_port *port) --- 314 unchanged lines hidden (view full) --- 687 reg |= ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN; 688 WR4(sc, XUSB_PADCTL_ELPG_PROGRAM, reg); 689 DELAY(100); 690 691 return (0); 692} 693 694static int |
686xusbpadctl_phy_enable(device_t dev, intptr_t id, bool enable) | 695xusbpadctl_phy_enable(struct phynode *phy, bool enable) |
687{ | 696{ |
697 device_t dev; 698 intptr_t id; |
|
688 struct padctl_softc *sc; 689 struct padctl_lane *lane; 690 struct padctl_pad *pad; 691 int rv; 692 | 699 struct padctl_softc *sc; 700 struct padctl_lane *lane; 701 struct padctl_pad *pad; 702 int rv; 703 |
704 dev = phynode_get_device(phy); 705 id = phynode_get_id(phy); |
|
693 sc = device_get_softc(dev); 694 695 if (id < 0 || id >= nitems(lanes_tbl)) { 696 device_printf(dev, "Unknown phy: %d\n", id); 697 return (ENXIO); 698 } 699 lane = lanes_tbl + id; 700 if (!lane->enabled) { --- 25 unchanged lines hidden (view full) --- 726 return (rv); 727 } 728 sc->phy_ena_cnt--; 729 } 730 731 return (0); 732} 733 | 706 sc = device_get_softc(dev); 707 708 if (id < 0 || id >= nitems(lanes_tbl)) { 709 device_printf(dev, "Unknown phy: %d\n", id); 710 return (ENXIO); 711 } 712 lane = lanes_tbl + id; 713 if (!lane->enabled) { --- 25 unchanged lines hidden (view full) --- 739 return (rv); 740 } 741 sc->phy_ena_cnt--; 742 } 743 744 return (0); 745} 746 |
734static int 735xusbpadctl_phy_map(device_t provider, phandle_t xref, int ncells, 736 pcell_t *cells, intptr_t *id) 737{ 738 int i; 739 740 if (ncells != 0) 741 return (ERANGE); 742 743 for (i = 0; i < nitems(lanes_tbl); i++) { 744 if (lanes_tbl[i].xref == xref) { 745 *id = i; 746 return (0); 747 } 748 } 749 return (ENXIO); 750} 751 | |
752/* ------------------------------------------------------------------------- 753 * 754 * FDT processing 755 */ 756static struct padctl_port * 757search_port(struct padctl_softc *sc, char *port_name) 758{ 759 int i; --- 106 unchanged lines hidden (view full) --- 866 WR4(sc, lane->reg, reg); 867 return (0); 868} 869 870static int 871process_lane(struct padctl_softc *sc, phandle_t node, struct padctl_pad *pad) 872{ 873 struct padctl_lane *lane; | 747/* ------------------------------------------------------------------------- 748 * 749 * FDT processing 750 */ 751static struct padctl_port * 752search_port(struct padctl_softc *sc, char *port_name) 753{ 754 int i; --- 106 unchanged lines hidden (view full) --- 861 WR4(sc, lane->reg, reg); 862 return (0); 863} 864 865static int 866process_lane(struct padctl_softc *sc, phandle_t node, struct padctl_pad *pad) 867{ 868 struct padctl_lane *lane; |
869 struct phynode *phynode; 870 struct phynode_init_def phy_init; |
|
874 char *name; 875 char *function; 876 int rv; 877 878 name = NULL; 879 function = NULL; 880 rv = OF_getprop_alloc(node, "name", 1, (void **)&name); 881 if (rv <= 0) { --- 26 unchanged lines hidden (view full) --- 908 909 rv = config_lane(sc, lane); 910 if (rv != 0) { 911 device_printf(sc->dev, "Cannot configure lane: %s: %d\n", 912 name, rv); 913 rv = ENXIO; 914 goto end; 915 } | 871 char *name; 872 char *function; 873 int rv; 874 875 name = NULL; 876 function = NULL; 877 rv = OF_getprop_alloc(node, "name", 1, (void **)&name); 878 if (rv <= 0) { --- 26 unchanged lines hidden (view full) --- 905 906 rv = config_lane(sc, lane); 907 if (rv != 0) { 908 device_printf(sc->dev, "Cannot configure lane: %s: %d\n", 909 name, rv); 910 rv = ENXIO; 911 goto end; 912 } |
916 lane->xref = OF_xref_from_node(node); | |
917 lane->pad = pad; 918 lane->enabled = true; 919 pad->lanes[pad->nlanes++] = lane; | 913 lane->pad = pad; 914 lane->enabled = true; 915 pad->lanes[pad->nlanes++] = lane; |
916 917 /* Create and register phy. */ 918 bzero(&phy_init, sizeof(phy_init)); 919 phy_init.id = lane - lanes_tbl; 920 phy_init.ofw_node = node; 921 phynode = phynode_create(sc->dev, &xusbpadctl_phynode_class, &phy_init); 922 if (phynode == NULL) { 923 device_printf(sc->dev, "Cannot create phy\n"); 924 rv = ENXIO; 925 goto end; 926 } 927 if (phynode_register(phynode) == NULL) { 928 device_printf(sc->dev, "Cannot create phy\n"); 929 return (ENXIO); 930 } 931 |
|
920 rv = 0; 921 922end: 923 if (name != NULL) 924 OF_prop_free(name); 925 if (function != NULL) 926 OF_prop_free(function); 927 return (rv); 928} 929 930static int 931process_pad(struct padctl_softc *sc, phandle_t node) 932{ | 932 rv = 0; 933 934end: 935 if (name != NULL) 936 OF_prop_free(name); 937 if (function != NULL) 938 OF_prop_free(function); 939 return (rv); 940} 941 942static int 943process_pad(struct padctl_softc *sc, phandle_t node) 944{ |
933 phandle_t xref; | |
934 struct padctl_pad *pad; 935 char *name; 936 int rv; 937 938 name = NULL; 939 rv = OF_getprop_alloc(node, "name", 1, (void **)&name); 940 if (rv <= 0) { 941 device_printf(sc->dev, "Cannot read pad name.\n"); --- 16 unchanged lines hidden (view full) --- 958 959 for (node = OF_child(node); node != 0; node = OF_peer(node)) { 960 if (!fdt_is_enabled(node)) 961 continue; 962 963 rv = process_lane(sc, node, pad); 964 if (rv != 0) 965 goto end; | 945 struct padctl_pad *pad; 946 char *name; 947 int rv; 948 949 name = NULL; 950 rv = OF_getprop_alloc(node, "name", 1, (void **)&name); 951 if (rv <= 0) { 952 device_printf(sc->dev, "Cannot read pad name.\n"); --- 16 unchanged lines hidden (view full) --- 969 970 for (node = OF_child(node); node != 0; node = OF_peer(node)) { 971 if (!fdt_is_enabled(node)) 972 continue; 973 974 rv = process_lane(sc, node, pad); 975 if (rv != 0) 976 goto end; |
966 967 xref = OF_xref_from_node(node); 968 OF_device_register_xref(xref, sc->dev); | |
969 } 970 pad->enabled = true; 971 rv = 0; 972end: 973 if (name != NULL) 974 OF_prop_free(name); 975 return (rv); 976} --- 212 unchanged lines hidden (view full) --- 1189} 1190 1191static device_method_t tegra_xusbpadctl_methods[] = { 1192 /* Device interface */ 1193 DEVMETHOD(device_probe, xusbpadctl_probe), 1194 DEVMETHOD(device_attach, xusbpadctl_attach), 1195 DEVMETHOD(device_detach, xusbpadctl_detach), 1196 | 977 } 978 pad->enabled = true; 979 rv = 0; 980end: 981 if (name != NULL) 982 OF_prop_free(name); 983 return (rv); 984} --- 212 unchanged lines hidden (view full) --- 1197} 1198 1199static device_method_t tegra_xusbpadctl_methods[] = { 1200 /* Device interface */ 1201 DEVMETHOD(device_probe, xusbpadctl_probe), 1202 DEVMETHOD(device_attach, xusbpadctl_attach), 1203 DEVMETHOD(device_detach, xusbpadctl_detach), 1204 |
1197 /* phy interface */ 1198 DEVMETHOD(phy_enable, xusbpadctl_phy_enable), 1199 DEVMETHOD(phy_map, xusbpadctl_phy_map), 1200 | |
1201 DEVMETHOD_END 1202}; 1203 1204static devclass_t tegra_xusbpadctl_devclass; 1205static DEFINE_CLASS_0(xusbpadctl, tegra_xusbpadctl_driver, 1206 tegra_xusbpadctl_methods, sizeof(struct padctl_softc)); 1207EARLY_DRIVER_MODULE(tegra_xusbpadctl, simplebus, tegra_xusbpadctl_driver, 1208 tegra_xusbpadctl_devclass, NULL, NULL, 73); | 1205 DEVMETHOD_END 1206}; 1207 1208static devclass_t tegra_xusbpadctl_devclass; 1209static DEFINE_CLASS_0(xusbpadctl, tegra_xusbpadctl_driver, 1210 tegra_xusbpadctl_methods, sizeof(struct padctl_softc)); 1211EARLY_DRIVER_MODULE(tegra_xusbpadctl, simplebus, tegra_xusbpadctl_driver, 1212 tegra_xusbpadctl_devclass, NULL, NULL, 73); |