^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2011 Marvell International Ltd. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2018 Lubomir Rintel <lkundrak@v3.sk>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <dt-bindings/phy/phy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/phy/phy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) /* phy regs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define UTMI_REVISION 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define UTMI_CTRL 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define UTMI_PLL 0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define UTMI_TX 0xc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define UTMI_RX 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define UTMI_IVREF 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define UTMI_T0 0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define UTMI_T1 0x1c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define UTMI_T2 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define UTMI_T3 0x24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define UTMI_T4 0x28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define UTMI_T5 0x2c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define UTMI_RESERVE 0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define UTMI_USB_INT 0x34
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define UTMI_DBG_CTL 0x38
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define UTMI_OTG_ADDON 0x3c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) /* For UTMICTRL Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define UTMI_CTRL_USB_CLK_EN (1 << 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /* pxa168 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define UTMI_CTRL_SUSPEND_SET1 (1 << 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define UTMI_CTRL_SUSPEND_SET2 (1 << 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define UTMI_CTRL_RXBUF_PDWN (1 << 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define UTMI_CTRL_TXBUF_PDWN (1 << 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define UTMI_CTRL_INPKT_DELAY_SHIFT 30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define UTMI_CTRL_INPKT_DELAY_SOF_SHIFT 28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define UTMI_CTRL_PU_REF_SHIFT 20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define UTMI_CTRL_ARC_PULLDN_SHIFT 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define UTMI_CTRL_PLL_PWR_UP_SHIFT 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define UTMI_CTRL_PWR_UP_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) /* For UTMI_PLL Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define UTMI_PLL_PLLCALI12_SHIFT 29
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define UTMI_PLL_PLLCALI12_MASK (0x3 << 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define UTMI_PLL_PLLVDD18_SHIFT 27
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define UTMI_PLL_PLLVDD18_MASK (0x3 << 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define UTMI_PLL_PLLVDD12_SHIFT 25
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define UTMI_PLL_PLLVDD12_MASK (0x3 << 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define UTMI_PLL_CLK_BLK_EN_SHIFT 24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define CLK_BLK_EN (0x1 << 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define PLL_READY (0x1 << 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define KVCO_EXT (0x1 << 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define VCOCAL_START (0x1 << 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define UTMI_PLL_KVCO_SHIFT 15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define UTMI_PLL_KVCO_MASK (0x7 << 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define UTMI_PLL_ICP_SHIFT 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define UTMI_PLL_ICP_MASK (0x7 << 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define UTMI_PLL_FBDIV_SHIFT 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define UTMI_PLL_FBDIV_MASK (0xFF << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define UTMI_PLL_REFDIV_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define UTMI_PLL_REFDIV_MASK (0xF << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /* For UTMI_TX Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define UTMI_TX_REG_EXT_FS_RCAL_SHIFT 27
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define UTMI_TX_REG_EXT_FS_RCAL_MASK (0xf << 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define UTMI_TX_REG_EXT_FS_RCAL_EN_SHIFT 26
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define UTMI_TX_REG_EXT_FS_RCAL_EN_MASK (0x1 << 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define UTMI_TX_TXVDD12_SHIFT 22
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define UTMI_TX_TXVDD12_MASK (0x3 << 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define UTMI_TX_CK60_PHSEL_SHIFT 17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define UTMI_TX_CK60_PHSEL_MASK (0xf << 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define UTMI_TX_IMPCAL_VTH_SHIFT 14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define UTMI_TX_IMPCAL_VTH_MASK (0x7 << 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define REG_RCAL_START (0x1 << 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define UTMI_TX_LOW_VDD_EN_SHIFT 11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define UTMI_TX_AMP_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define UTMI_TX_AMP_MASK (0x7 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) /* For UTMI_RX Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define UTMI_REG_SQ_LENGTH_SHIFT 15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define UTMI_REG_SQ_LENGTH_MASK (0x3 << 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define UTMI_RX_SQ_THRESH_SHIFT 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define UTMI_RX_SQ_THRESH_MASK (0xf << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define UTMI_OTG_ADDON_OTG_ON (1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) enum pxa_usb_phy_version {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) PXA_USB_PHY_MMP2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) PXA_USB_PHY_PXA910,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) PXA_USB_PHY_PXA168,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct pxa_usb_phy {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct phy *phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) enum pxa_usb_phy_version version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) /*****************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * The registers read/write routines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) *****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static unsigned int u2o_get(void __iomem *base, unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return readl_relaxed(base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) static void u2o_set(void __iomem *base, unsigned int offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) unsigned int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) reg = readl_relaxed(base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) reg |= value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) writel_relaxed(reg, base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) readl_relaxed(base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static void u2o_clear(void __iomem *base, unsigned int offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) unsigned int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) reg = readl_relaxed(base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) reg &= ~value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) writel_relaxed(reg, base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) readl_relaxed(base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) static void u2o_write(void __iomem *base, unsigned int offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) unsigned int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) writel_relaxed(value, base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) readl_relaxed(base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) static int pxa_usb_phy_init(struct phy *phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct pxa_usb_phy *pxa_usb_phy = phy_get_drvdata(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) void __iomem *base = pxa_usb_phy->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) int loops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) dev_info(&phy->dev, "initializing Marvell PXA USB PHY");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /* Initialize the USB PHY power */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (pxa_usb_phy->version == PXA_USB_PHY_PXA910) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) u2o_set(base, UTMI_CTRL, (1<<UTMI_CTRL_INPKT_DELAY_SOF_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) | (1<<UTMI_CTRL_PU_REF_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) u2o_set(base, UTMI_CTRL, 1<<UTMI_CTRL_PLL_PWR_UP_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) u2o_set(base, UTMI_CTRL, 1<<UTMI_CTRL_PWR_UP_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) /* UTMI_PLL settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) u2o_clear(base, UTMI_PLL, UTMI_PLL_PLLVDD18_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) | UTMI_PLL_PLLVDD12_MASK | UTMI_PLL_PLLCALI12_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) | UTMI_PLL_FBDIV_MASK | UTMI_PLL_REFDIV_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) | UTMI_PLL_ICP_MASK | UTMI_PLL_KVCO_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) u2o_set(base, UTMI_PLL, 0xee<<UTMI_PLL_FBDIV_SHIFT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) | 0xb<<UTMI_PLL_REFDIV_SHIFT | 3<<UTMI_PLL_PLLVDD18_SHIFT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) | 3<<UTMI_PLL_PLLVDD12_SHIFT | 3<<UTMI_PLL_PLLCALI12_SHIFT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) | 1<<UTMI_PLL_ICP_SHIFT | 3<<UTMI_PLL_KVCO_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /* UTMI_TX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) u2o_clear(base, UTMI_TX, UTMI_TX_REG_EXT_FS_RCAL_EN_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) | UTMI_TX_TXVDD12_MASK | UTMI_TX_CK60_PHSEL_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) | UTMI_TX_IMPCAL_VTH_MASK | UTMI_TX_REG_EXT_FS_RCAL_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) | UTMI_TX_AMP_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) u2o_set(base, UTMI_TX, 3<<UTMI_TX_TXVDD12_SHIFT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) | 4<<UTMI_TX_CK60_PHSEL_SHIFT | 4<<UTMI_TX_IMPCAL_VTH_SHIFT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) | 8<<UTMI_TX_REG_EXT_FS_RCAL_SHIFT | 3<<UTMI_TX_AMP_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) /* UTMI_RX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) u2o_clear(base, UTMI_RX, UTMI_RX_SQ_THRESH_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) | UTMI_REG_SQ_LENGTH_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) u2o_set(base, UTMI_RX, 7<<UTMI_RX_SQ_THRESH_SHIFT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) | 2<<UTMI_REG_SQ_LENGTH_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) /* UTMI_IVREF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (pxa_usb_phy->version == PXA_USB_PHY_PXA168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * fixing Microsoft Altair board interface with NEC hub issue -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * Set UTMI_IVREF from 0x4a3 to 0x4bf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) u2o_write(base, UTMI_IVREF, 0x4bf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /* toggle VCOCAL_START bit of UTMI_PLL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) udelay(200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) u2o_set(base, UTMI_PLL, VCOCAL_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) udelay(40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) u2o_clear(base, UTMI_PLL, VCOCAL_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /* toggle REG_RCAL_START bit of UTMI_TX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) udelay(400);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) u2o_set(base, UTMI_TX, REG_RCAL_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) udelay(40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) u2o_clear(base, UTMI_TX, REG_RCAL_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) udelay(400);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) /* Make sure PHY PLL is ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) loops = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) while ((u2o_get(base, UTMI_PLL) & PLL_READY) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) mdelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) loops++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if (loops > 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) dev_warn(&phy->dev, "calibrate timeout, UTMI_PLL %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) u2o_get(base, UTMI_PLL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (pxa_usb_phy->version == PXA_USB_PHY_PXA168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) u2o_set(base, UTMI_RESERVE, 1 << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) /* Turn on UTMI PHY OTG extension */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) u2o_write(base, UTMI_OTG_ADDON, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) static int pxa_usb_phy_exit(struct phy *phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) struct pxa_usb_phy *pxa_usb_phy = phy_get_drvdata(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) void __iomem *base = pxa_usb_phy->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) dev_info(&phy->dev, "deinitializing Marvell PXA USB PHY");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if (pxa_usb_phy->version == PXA_USB_PHY_PXA168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) u2o_clear(base, UTMI_OTG_ADDON, UTMI_OTG_ADDON_OTG_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) u2o_clear(base, UTMI_CTRL, UTMI_CTRL_RXBUF_PDWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) u2o_clear(base, UTMI_CTRL, UTMI_CTRL_TXBUF_PDWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) u2o_clear(base, UTMI_CTRL, UTMI_CTRL_USB_CLK_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) u2o_clear(base, UTMI_CTRL, 1<<UTMI_CTRL_PWR_UP_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) u2o_clear(base, UTMI_CTRL, 1<<UTMI_CTRL_PLL_PWR_UP_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static const struct phy_ops pxa_usb_phy_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) .init = pxa_usb_phy_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) .exit = pxa_usb_phy_exit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) static const struct of_device_id pxa_usb_phy_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) .compatible = "marvell,mmp2-usb-phy",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) .data = (void *)PXA_USB_PHY_MMP2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) .compatible = "marvell,pxa910-usb-phy",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) .data = (void *)PXA_USB_PHY_PXA910,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) .compatible = "marvell,pxa168-usb-phy",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) .data = (void *)PXA_USB_PHY_PXA168,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) MODULE_DEVICE_TABLE(of, pxa_usb_phy_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) static int pxa_usb_phy_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) struct resource *resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) struct pxa_usb_phy *pxa_usb_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) struct phy_provider *provider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) const struct of_device_id *of_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) pxa_usb_phy = devm_kzalloc(dev, sizeof(struct pxa_usb_phy), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (!pxa_usb_phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) of_id = of_match_node(pxa_usb_phy_of_match, dev->of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) if (of_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) pxa_usb_phy->version = (enum pxa_usb_phy_version)of_id->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) pxa_usb_phy->version = PXA_USB_PHY_MMP2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) pxa_usb_phy->base = devm_ioremap_resource(dev, resource);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) if (IS_ERR(pxa_usb_phy->base)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) dev_err(dev, "failed to remap PHY regs\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return PTR_ERR(pxa_usb_phy->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) pxa_usb_phy->phy = devm_phy_create(dev, NULL, &pxa_usb_phy_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if (IS_ERR(pxa_usb_phy->phy)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) dev_err(dev, "failed to create PHY\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return PTR_ERR(pxa_usb_phy->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) phy_set_drvdata(pxa_usb_phy->phy, pxa_usb_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) if (IS_ERR(provider)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) dev_err(dev, "failed to register PHY provider\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) return PTR_ERR(provider);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (!dev->of_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) phy_create_lookup(pxa_usb_phy->phy, "usb", "mv-udc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) phy_create_lookup(pxa_usb_phy->phy, "usb", "pxa-u2oehci");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) phy_create_lookup(pxa_usb_phy->phy, "usb", "mv-otg");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) dev_info(dev, "Marvell PXA USB PHY");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) static struct platform_driver pxa_usb_phy_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) .probe = pxa_usb_phy_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) .name = "pxa-usb-phy",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) .of_match_table = pxa_usb_phy_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) module_platform_driver(pxa_usb_phy_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) MODULE_AUTHOR("Lubomir Rintel <lkundrak@v3.sk>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) MODULE_DESCRIPTION("Marvell PXA USB PHY Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) MODULE_LICENSE("GPL v2");