Deleted Added
full compact
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);