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 <clk.h> 12 #include <dm.h> 13 #include <generic-phy.h> 14 #include <reset.h> 15 #include <asm/io.h> 16 #include <dm/device.h> 17 18 #define USBH_SETUP_PORT1_EN BIT(0) 19 20 struct bcm6348_usbh_priv { 21 void __iomem *regs; 22 }; 23 24 static int bcm6348_usbh_init(struct phy *phy) 25 { 26 struct bcm6348_usbh_priv *priv = dev_get_priv(phy->dev); 27 28 writel_be(USBH_SETUP_PORT1_EN, priv->regs); 29 30 return 0; 31 } 32 33 static struct phy_ops bcm6348_usbh_ops = { 34 .init = bcm6348_usbh_init, 35 }; 36 37 static const struct udevice_id bcm6348_usbh_ids[] = { 38 { .compatible = "brcm,bcm6348-usbh" }, 39 { /* sentinel */ } 40 }; 41 42 static int bcm6348_usbh_probe(struct udevice *dev) 43 { 44 struct bcm6348_usbh_priv *priv = dev_get_priv(dev); 45 struct reset_ctl rst_ctl; 46 struct clk clk; 47 int ret; 48 49 priv->regs = dev_remap_addr(dev); 50 if (!priv->regs) 51 return -EINVAL; 52 53 /* enable usbh clock */ 54 ret = clk_get_by_name(dev, "usbh", &clk); 55 if (ret < 0) 56 return ret; 57 58 ret = clk_enable(&clk); 59 if (ret < 0) 60 return ret; 61 62 ret = clk_free(&clk); 63 if (ret < 0) 64 return ret; 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(bcm6348_usbh) = { 83 .name = "bcm6348-usbh", 84 .id = UCLASS_PHY, 85 .of_match = bcm6348_usbh_ids, 86 .ops = &bcm6348_usbh_ops, 87 .priv_auto_alloc_size = sizeof(struct bcm6348_usbh_priv), 88 .probe = bcm6348_usbh_probe, 89 }; 90