diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-18 20:21:49 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-18 20:21:49 +0300 |
commit | 5695d5d1970f975de059bb6dec76941440f62488 (patch) | |
tree | 6b03381a0b103324c286a83ebb4154719b514feb /drivers/phy/mediatek/phy-mtk-tphy.c | |
parent | 1f7a4c73a739a63b3f108d8eda6f947fdc70dd65 (diff) | |
parent | 29c692c96b3a39cd1911fb79cd2505af8d070f07 (diff) | |
download | linux-5695d5d1970f975de059bb6dec76941440f62488.tar.xz |
Merge tag 'usb-4.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB/PHY updates from Greg KH:
"Here is the big USB and phy driver patch set for 4.19-rc1.
Nothing huge but there was a lot of work that happened this
development cycle:
- lots of type-c work, with drivers graduating out of staging, and
displayport support being added.
- new PHY drivers
- the normal collection of gadget driver updates and fixes
- code churn to work on the urb handling path, using irqsave()
everywhere in anticipation of making this codepath a lot simpler in
the future.
- usbserial driver fixes and reworks
- other misc changes
All of these have been in linux-next with no reported issues for a
while"
* tag 'usb-4.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (159 commits)
USB: serial: pl2303: add a new device id for ATEN
usb: renesas_usbhs: Kconfig: convert to SPDX identifiers
usb: dwc3: gadget: Check MaxPacketSize from descriptor
usb: dwc2: Turn on uframe_sched on "stm32f4x9_fsotg" platforms
usb: dwc2: Turn on uframe_sched on "amlogic" platforms
usb: dwc2: Turn on uframe_sched on "his" platforms
usb: dwc2: Turn on uframe_sched on "bcm" platforms
usb: dwc2: gadget: ISOC's starting flow improvement
usb: dwc2: Make dwc2_readl/writel functions endianness-agnostic.
usb: dwc3: core: Enable AutoRetry feature in the controller
usb: dwc3: Set default mode for dwc_usb31
usb: gadget: udc: renesas_usb3: Add register of usb role switch
usb: dwc2: replace ioread32/iowrite32_rep with dwc2_readl/writel_rep
usb: dwc2: Modify dwc2_readl/writel functions prototype
usb: dwc3: pci: Intel Merrifield can be host
usb: dwc3: pci: Supply device properties via driver data
arm64: dts: dwc3: description of incr burst type
usb: dwc3: Enable undefined length INCR burst type
usb: dwc3: add global soc bus configuration reg0
usb: dwc3: Describe 'wakeup_work' field of struct dwc3_pci
...
Diffstat (limited to 'drivers/phy/mediatek/phy-mtk-tphy.c')
-rw-r--r-- | drivers/phy/mediatek/phy-mtk-tphy.c | 85 |
1 files changed, 76 insertions, 9 deletions
diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c index 38c281b5abbb..3eb8e1bd7b78 100644 --- a/drivers/phy/mediatek/phy-mtk-tphy.c +++ b/drivers/phy/mediatek/phy-mtk-tphy.c @@ -1,16 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2015 MediaTek Inc. * Author: Chunfeng Yun <chunfeng.yun@mediatek.com> * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include <dt-bindings/phy/phy.h> @@ -50,6 +42,12 @@ #define PA0_RG_U2PLL_FORCE_ON BIT(15) #define PA0_RG_USB20_INTR_EN BIT(5) +#define U3P_USBPHYACR1 0x004 +#define PA1_RG_VRT_SEL GENMASK(14, 12) +#define PA1_RG_VRT_SEL_VAL(x) ((0x7 & (x)) << 12) +#define PA1_RG_TERM_SEL GENMASK(10, 8) +#define PA1_RG_TERM_SEL_VAL(x) ((0x7 & (x)) << 8) + #define U3P_USBPHYACR2 0x008 #define PA2_RG_SIF_U2PLL_FORCE_EN BIT(18) @@ -103,6 +101,9 @@ #define P2C_RG_AVALID BIT(2) #define P2C_RG_IDDIG BIT(1) +#define U3P_U2PHYBC12C 0x080 +#define P2C_RG_CHGDT_EN BIT(0) + #define U3P_U3_CHIP_GPIO_CTLD 0x0c #define P3C_REG_IP_SW_RST BIT(31) #define P3C_MCU_BUS_CK_GATE_EN BIT(30) @@ -296,6 +297,10 @@ struct mtk_phy_instance { struct clk *ref_clk; /* reference clock of anolog phy */ u32 index; u8 type; + int eye_src; + int eye_vrt; + int eye_term; + bool bc12_en; }; struct mtk_tphy { @@ -320,6 +325,10 @@ static void hs_slew_rate_calibrate(struct mtk_tphy *tphy, int fm_out; u32 tmp; + /* use force value */ + if (instance->eye_src) + return; + /* enable USB ring oscillator */ tmp = readl(com + U3P_USBPHYACR5); tmp |= PA5_RG_U2_HSTX_SRCAL_EN; @@ -826,6 +835,61 @@ static void phy_v2_banks_init(struct mtk_tphy *tphy, } } +static void phy_parse_property(struct mtk_tphy *tphy, + struct mtk_phy_instance *instance) +{ + struct device *dev = &instance->phy->dev; + + if (instance->type != PHY_TYPE_USB2) + return; + + instance->bc12_en = device_property_read_bool(dev, "mediatek,bc12"); + device_property_read_u32(dev, "mediatek,eye-src", + &instance->eye_src); + device_property_read_u32(dev, "mediatek,eye-vrt", + &instance->eye_vrt); + device_property_read_u32(dev, "mediatek,eye-term", + &instance->eye_term); + dev_dbg(dev, "bc12:%d, src:%d, vrt:%d, term:%d\n", + instance->bc12_en, instance->eye_src, + instance->eye_vrt, instance->eye_term); +} + +static void u2_phy_props_set(struct mtk_tphy *tphy, + struct mtk_phy_instance *instance) +{ + struct u2phy_banks *u2_banks = &instance->u2_banks; + void __iomem *com = u2_banks->com; + u32 tmp; + + if (instance->bc12_en) { + tmp = readl(com + U3P_U2PHYBC12C); + tmp |= P2C_RG_CHGDT_EN; /* BC1.2 path Enable */ + writel(tmp, com + U3P_U2PHYBC12C); + } + + if (instance->eye_src) { + tmp = readl(com + U3P_USBPHYACR5); + tmp &= ~PA5_RG_U2_HSTX_SRCTRL; + tmp |= PA5_RG_U2_HSTX_SRCTRL_VAL(instance->eye_src); + writel(tmp, com + U3P_USBPHYACR5); + } + + if (instance->eye_vrt) { + tmp = readl(com + U3P_USBPHYACR1); + tmp &= ~PA1_RG_VRT_SEL; + tmp |= PA1_RG_VRT_SEL_VAL(instance->eye_vrt); + writel(tmp, com + U3P_USBPHYACR1); + } + + if (instance->eye_term) { + tmp = readl(com + U3P_USBPHYACR1); + tmp &= ~PA1_RG_TERM_SEL; + tmp |= PA1_RG_TERM_SEL_VAL(instance->eye_term); + writel(tmp, com + U3P_USBPHYACR1); + } +} + static int mtk_phy_init(struct phy *phy) { struct mtk_phy_instance *instance = phy_get_drvdata(phy); @@ -847,6 +911,7 @@ static int mtk_phy_init(struct phy *phy) switch (instance->type) { case PHY_TYPE_USB2: u2_phy_instance_init(tphy, instance); + u2_phy_props_set(tphy, instance); break; case PHY_TYPE_USB3: u3_phy_instance_init(tphy, instance); @@ -959,6 +1024,8 @@ static struct phy *mtk_phy_xlate(struct device *dev, return ERR_PTR(-EINVAL); } + phy_parse_property(tphy, instance); + return instance->phy; } |