1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com> 4 * 5 * Derived from linux/arch/mips/bcm63xx/usb-common.c: 6 * Copyright 2008 Maxime Bizon <mbizon@freebox.fr> 7 * Copyright 2013 Florian Fainelli <florian@openwrt.org> 8 */ 9 10 #include <common.h> 11 #include <dm.h> 12 #include <generic-phy.h> 13 #include <reset.h> 14 #include <asm/io.h> 15 #include <dm/device.h> 16 17 /* USBH Swap Control register */ 18 #define USBH_SWAP_REG 0x00 19 #define USBH_SWAP_OHCI_DATA BIT(0) 20 #define USBH_SWAP_OHCI_ENDIAN BIT(1) 21 #define USBH_SWAP_EHCI_DATA BIT(3) 22 #define USBH_SWAP_EHCI_ENDIAN BIT(4) 23 24 /* USBH Test register */ 25 #define USBH_TEST_REG 0x24 26 #define USBH_TEST_PORT_CTL 0x1c0020 27 28 struct bcm6358_usbh_priv { 29 void __iomem *regs; 30 }; 31 32 static int bcm6358_usbh_init(struct phy *phy) 33 { 34 struct bcm6358_usbh_priv *priv = dev_get_priv(phy->dev); 35 36 /* configure to work in native cpu endian */ 37 clrsetbits_be32(priv->regs + USBH_SWAP_REG, 38 USBH_SWAP_EHCI_ENDIAN | USBH_SWAP_OHCI_ENDIAN, 39 USBH_SWAP_EHCI_DATA | USBH_SWAP_OHCI_DATA); 40 41 /* test port control */ 42 writel_be(USBH_TEST_PORT_CTL, priv->regs + USBH_TEST_REG); 43 44 return 0; 45 } 46 47 static struct phy_ops bcm6358_usbh_ops = { 48 .init = bcm6358_usbh_init, 49 }; 50 51 static const struct udevice_id bcm6358_usbh_ids[] = { 52 { .compatible = "brcm,bcm6358-usbh" }, 53 { /* sentinel */ } 54 }; 55 56 static int bcm6358_usbh_probe(struct udevice *dev) 57 { 58 struct bcm6358_usbh_priv *priv = dev_get_priv(dev); 59 struct reset_ctl rst_ctl; 60 int ret; 61 62 priv->regs = dev_remap_addr(dev); 63 if (!priv->regs) 64 return -EINVAL; 65 66 /* perform reset */ 67 ret = reset_get_by_index(dev, 0, &rst_ctl); 68 if (ret < 0) 69 return ret; 70 71 ret = reset_deassert(&rst_ctl); 72 if (ret < 0) 73 return ret; 74 75 ret = reset_free(&rst_ctl); 76 if (ret < 0) 77 return ret; 78 79 return 0; 80 } 81 82 U_BOOT_DRIVER(bcm6358_usbh) = { 83 .name = "bcm6358-usbh", 84 .id = UCLASS_PHY, 85 .of_match = bcm6358_usbh_ids, 86 .ops = &bcm6358_usbh_ops, 87 .priv_auto_alloc_size = sizeof(struct bcm6358_usbh_priv), 88 .probe = bcm6358_usbh_probe, 89 }; 90