1ecf8ea9fSMasahiro Yamada /* 2ecf8ea9fSMasahiro Yamada * UniPhier Specific Glue Layer for DWC3 3ecf8ea9fSMasahiro Yamada * 4ecf8ea9fSMasahiro Yamada * Copyright (C) 2016-2017 Socionext Inc. 5ecf8ea9fSMasahiro Yamada * Author: Masahiro Yamada <yamada.masahiro@socionext.com> 6ecf8ea9fSMasahiro Yamada * 7ecf8ea9fSMasahiro Yamada * SPDX-License-Identifier: GPL-2.0+ 8ecf8ea9fSMasahiro Yamada */ 9ecf8ea9fSMasahiro Yamada 10ecf8ea9fSMasahiro Yamada #include <dm.h> 11*1488d4b9SMasahiro Yamada #include <linux/bitops.h> 12ecf8ea9fSMasahiro Yamada #include <linux/errno.h> 13ecf8ea9fSMasahiro Yamada #include <linux/io.h> 14ecf8ea9fSMasahiro Yamada #include <linux/sizes.h> 15ecf8ea9fSMasahiro Yamada 16ecf8ea9fSMasahiro Yamada #define UNIPHIER_PRO4_DWC3_RESET 0x40 17ecf8ea9fSMasahiro Yamada #define UNIPHIER_PRO4_DWC3_RESET_XIOMMU BIT(5) 18ecf8ea9fSMasahiro Yamada #define UNIPHIER_PRO4_DWC3_RESET_XLINK BIT(4) 19ecf8ea9fSMasahiro Yamada #define UNIPHIER_PRO4_DWC3_RESET_PHY_SS BIT(2) 20ecf8ea9fSMasahiro Yamada 21ecf8ea9fSMasahiro Yamada #define UNIPHIER_PRO5_DWC3_RESET 0x00 22ecf8ea9fSMasahiro Yamada #define UNIPHIER_PRO5_DWC3_RESET_PHY_S1 BIT(17) 23ecf8ea9fSMasahiro Yamada #define UNIPHIER_PRO5_DWC3_RESET_PHY_S0 BIT(16) 24ecf8ea9fSMasahiro Yamada #define UNIPHIER_PRO5_DWC3_RESET_XLINK BIT(15) 25ecf8ea9fSMasahiro Yamada #define UNIPHIER_PRO5_DWC3_RESET_XIOMMU BIT(14) 26ecf8ea9fSMasahiro Yamada 27ecf8ea9fSMasahiro Yamada #define UNIPHIER_PXS2_DWC3_RESET 0x00 28ecf8ea9fSMasahiro Yamada #define UNIPHIER_PXS2_DWC3_RESET_XLINK BIT(15) 29ecf8ea9fSMasahiro Yamada 30ecf8ea9fSMasahiro Yamada static int uniphier_pro4_dwc3_init(void __iomem *regs) 31ecf8ea9fSMasahiro Yamada { 32ecf8ea9fSMasahiro Yamada u32 tmp; 33ecf8ea9fSMasahiro Yamada 34ecf8ea9fSMasahiro Yamada tmp = readl(regs + UNIPHIER_PRO4_DWC3_RESET); 35ecf8ea9fSMasahiro Yamada tmp &= ~UNIPHIER_PRO4_DWC3_RESET_PHY_SS; 36ecf8ea9fSMasahiro Yamada tmp |= UNIPHIER_PRO4_DWC3_RESET_XIOMMU | UNIPHIER_PRO4_DWC3_RESET_XLINK; 37ecf8ea9fSMasahiro Yamada writel(tmp, regs + UNIPHIER_PRO4_DWC3_RESET); 38ecf8ea9fSMasahiro Yamada 39ecf8ea9fSMasahiro Yamada return 0; 40ecf8ea9fSMasahiro Yamada } 41ecf8ea9fSMasahiro Yamada 42ecf8ea9fSMasahiro Yamada static int uniphier_pro5_dwc3_init(void __iomem *regs) 43ecf8ea9fSMasahiro Yamada { 44ecf8ea9fSMasahiro Yamada u32 tmp; 45ecf8ea9fSMasahiro Yamada 46ecf8ea9fSMasahiro Yamada tmp = readl(regs + UNIPHIER_PRO5_DWC3_RESET); 47ecf8ea9fSMasahiro Yamada tmp &= ~(UNIPHIER_PRO5_DWC3_RESET_PHY_S1 | 48ecf8ea9fSMasahiro Yamada UNIPHIER_PRO5_DWC3_RESET_PHY_S0); 49ecf8ea9fSMasahiro Yamada tmp |= UNIPHIER_PRO5_DWC3_RESET_XLINK | UNIPHIER_PRO5_DWC3_RESET_XIOMMU; 50ecf8ea9fSMasahiro Yamada writel(tmp, regs + UNIPHIER_PRO5_DWC3_RESET); 51ecf8ea9fSMasahiro Yamada 52ecf8ea9fSMasahiro Yamada return 0; 53ecf8ea9fSMasahiro Yamada } 54ecf8ea9fSMasahiro Yamada 55ecf8ea9fSMasahiro Yamada static int uniphier_pxs2_dwc3_init(void __iomem *regs) 56ecf8ea9fSMasahiro Yamada { 57ecf8ea9fSMasahiro Yamada u32 tmp; 58ecf8ea9fSMasahiro Yamada 59ecf8ea9fSMasahiro Yamada tmp = readl(regs + UNIPHIER_PXS2_DWC3_RESET); 60ecf8ea9fSMasahiro Yamada tmp |= UNIPHIER_PXS2_DWC3_RESET_XLINK; 61ecf8ea9fSMasahiro Yamada writel(tmp, regs + UNIPHIER_PXS2_DWC3_RESET); 62ecf8ea9fSMasahiro Yamada 63ecf8ea9fSMasahiro Yamada return 0; 64ecf8ea9fSMasahiro Yamada } 65ecf8ea9fSMasahiro Yamada 66ecf8ea9fSMasahiro Yamada static int uniphier_dwc3_probe(struct udevice *dev) 67ecf8ea9fSMasahiro Yamada { 68ecf8ea9fSMasahiro Yamada fdt_addr_t base; 69ecf8ea9fSMasahiro Yamada void __iomem *regs; 70ecf8ea9fSMasahiro Yamada int (*init)(void __iomem *regs); 71ecf8ea9fSMasahiro Yamada int ret; 72ecf8ea9fSMasahiro Yamada 73ecf8ea9fSMasahiro Yamada base = devfdt_get_addr(dev); 74ecf8ea9fSMasahiro Yamada if (base == FDT_ADDR_T_NONE) 75ecf8ea9fSMasahiro Yamada return -EINVAL; 76ecf8ea9fSMasahiro Yamada 77ecf8ea9fSMasahiro Yamada regs = ioremap(base, SZ_32K); 78ecf8ea9fSMasahiro Yamada if (!regs) 79ecf8ea9fSMasahiro Yamada return -ENOMEM; 80ecf8ea9fSMasahiro Yamada 81ecf8ea9fSMasahiro Yamada init = (typeof(init))dev_get_driver_data(dev); 82ecf8ea9fSMasahiro Yamada ret = init(regs); 83ecf8ea9fSMasahiro Yamada if (ret) 84ecf8ea9fSMasahiro Yamada dev_err(dev, "failed to init glue layer\n"); 85ecf8ea9fSMasahiro Yamada 86ecf8ea9fSMasahiro Yamada iounmap(regs); 87ecf8ea9fSMasahiro Yamada 88ecf8ea9fSMasahiro Yamada return ret; 89ecf8ea9fSMasahiro Yamada } 90ecf8ea9fSMasahiro Yamada 91ecf8ea9fSMasahiro Yamada static const struct udevice_id uniphier_dwc3_match[] = { 92ecf8ea9fSMasahiro Yamada { 93ecf8ea9fSMasahiro Yamada .compatible = "socionext,uniphier-pro4-dwc3", 94ecf8ea9fSMasahiro Yamada .data = (ulong)uniphier_pro4_dwc3_init, 95ecf8ea9fSMasahiro Yamada }, 96ecf8ea9fSMasahiro Yamada { 97ecf8ea9fSMasahiro Yamada .compatible = "socionext,uniphier-pro5-dwc3", 98ecf8ea9fSMasahiro Yamada .data = (ulong)uniphier_pro5_dwc3_init, 99ecf8ea9fSMasahiro Yamada }, 100ecf8ea9fSMasahiro Yamada { 101ecf8ea9fSMasahiro Yamada .compatible = "socionext,uniphier-pxs2-dwc3", 102ecf8ea9fSMasahiro Yamada .data = (ulong)uniphier_pxs2_dwc3_init, 103ecf8ea9fSMasahiro Yamada }, 104ecf8ea9fSMasahiro Yamada { 105ecf8ea9fSMasahiro Yamada .compatible = "socionext,uniphier-ld20-dwc3", 106ecf8ea9fSMasahiro Yamada .data = (ulong)uniphier_pxs2_dwc3_init, 107ecf8ea9fSMasahiro Yamada }, 108ecf8ea9fSMasahiro Yamada { 109ecf8ea9fSMasahiro Yamada .compatible = "socionext,uniphier-pxs3-dwc3", 110ecf8ea9fSMasahiro Yamada .data = (ulong)uniphier_pxs2_dwc3_init, 111ecf8ea9fSMasahiro Yamada }, 112ecf8ea9fSMasahiro Yamada { /* sentinel */ } 113ecf8ea9fSMasahiro Yamada }; 114ecf8ea9fSMasahiro Yamada 115ecf8ea9fSMasahiro Yamada U_BOOT_DRIVER(usb_xhci) = { 116ecf8ea9fSMasahiro Yamada .name = "uniphier-dwc3", 117ecf8ea9fSMasahiro Yamada .id = UCLASS_SIMPLE_BUS, 118ecf8ea9fSMasahiro Yamada .of_match = uniphier_dwc3_match, 119ecf8ea9fSMasahiro Yamada .probe = uniphier_dwc3_probe, 120ecf8ea9fSMasahiro Yamada }; 121