* [PATCH 1/2] phy: introduce phy mode PHY_MODE_UART and phy_get_mode_ext()
@ 2021-07-27 10:50 ` Macpaul Lin
0 siblings, 0 replies; 22+ messages in thread
From: Macpaul Lin @ 2021-07-27 10:50 UTC (permalink / raw)
To: linux-phy, Chunfeng Yun, Kishon Vijay Abraham I, Vinod Koul,
Matthias Brugger
Cc: Ainge Hsu, Eddie Hung, Kuohong Wang, Mediatek WSD Upstream,
Macpaul Lin, Macpaul Lin, linux-kernel, linux-arm-kernel,
linux-usb, linux-mediatek
Some embedded platform shared PINs between USB and UART.
For example, some phone will use special cable detection in boot loader
to switch USB port function into UART mode. Hence Kernel need to query
the hardware state from PHY registers to confirm the initialzation flow
for PHY and USB driver.
To support this kind of PIN switch, new PHY MODE and query API is
required. Here we introduce a new PHY mode: PHY_MODE_UART.
API phy_get_mode_ext() can be used to query the MODE from hardware
instead of reading it from phy attributes.
Signed-off-by: Macpaul Lin <macpaul.lin@mediatek.com>
---
drivers/phy/phy-core.c | 17 +++++++++++++++++
include/linux/phy/phy.h | 3 +++
2 files changed, 20 insertions(+)
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
index ccb575b..b8f6539 100644
--- a/drivers/phy/phy-core.c
+++ b/drivers/phy/phy-core.c
@@ -373,6 +373,23 @@ int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode)
}
EXPORT_SYMBOL_GPL(phy_set_mode_ext);
+int phy_get_mode_ext(struct phy *phy)
+{
+ int ret;
+
+ if (!phy || !phy->ops->get_mode_ext)
+ return 0;
+
+ mutex_lock(&phy->mutex);
+ ret = phy->ops->get_mode_ext(phy);
+ if (!ret)
+ ret = phy->attrs.mode;
+ mutex_unlock(&phy->mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(phy_get_mode_ext);
+
int phy_set_media(struct phy *phy, enum phy_media media)
{
int ret;
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index 0ed434d..7d32c6b 100644
--- a/include/linux/phy/phy.h
+++ b/include/linux/phy/phy.h
@@ -34,6 +34,7 @@ enum phy_mode {
PHY_MODE_USB_DEVICE_HS,
PHY_MODE_USB_DEVICE_SS,
PHY_MODE_USB_OTG,
+ PHY_MODE_UART,
PHY_MODE_UFS_HS_A,
PHY_MODE_UFS_HS_B,
PHY_MODE_PCIE,
@@ -70,6 +71,7 @@ enum phy_media {
* @power_on: powering on the phy
* @power_off: powering off the phy
* @set_mode: set the mode of the phy
+ * @get_mode_ext: get the extented mode of the phy
* @set_media: set the media type of the phy (optional)
* @set_speed: set the speed of the phy (optional)
* @reset: resetting the phy
@@ -83,6 +85,7 @@ struct phy_ops {
int (*power_on)(struct phy *phy);
int (*power_off)(struct phy *phy);
int (*set_mode)(struct phy *phy, enum phy_mode mode, int submode);
+ int (*get_mode_ext)(struct phy *phy);
int (*set_media)(struct phy *phy, enum phy_media media);
int (*set_speed)(struct phy *phy, int speed);
--
1.7.9.5
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 1/2] phy: introduce phy mode PHY_MODE_UART and phy_get_mode_ext()
@ 2021-07-27 10:50 ` Macpaul Lin
0 siblings, 0 replies; 22+ messages in thread
From: Macpaul Lin @ 2021-07-27 10:50 UTC (permalink / raw)
To: linux-phy, Chunfeng Yun, Kishon Vijay Abraham I, Vinod Koul,
Matthias Brugger
Cc: Ainge Hsu, Eddie Hung, Kuohong Wang, Mediatek WSD Upstream,
Macpaul Lin, Macpaul Lin, linux-kernel, linux-arm-kernel,
linux-usb, linux-mediatek
Some embedded platform shared PINs between USB and UART.
For example, some phone will use special cable detection in boot loader
to switch USB port function into UART mode. Hence Kernel need to query
the hardware state from PHY registers to confirm the initialzation flow
for PHY and USB driver.
To support this kind of PIN switch, new PHY MODE and query API is
required. Here we introduce a new PHY mode: PHY_MODE_UART.
API phy_get_mode_ext() can be used to query the MODE from hardware
instead of reading it from phy attributes.
Signed-off-by: Macpaul Lin <macpaul.lin@mediatek.com>
---
drivers/phy/phy-core.c | 17 +++++++++++++++++
include/linux/phy/phy.h | 3 +++
2 files changed, 20 insertions(+)
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
index ccb575b..b8f6539 100644
--- a/drivers/phy/phy-core.c
+++ b/drivers/phy/phy-core.c
@@ -373,6 +373,23 @@ int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode)
}
EXPORT_SYMBOL_GPL(phy_set_mode_ext);
+int phy_get_mode_ext(struct phy *phy)
+{
+ int ret;
+
+ if (!phy || !phy->ops->get_mode_ext)
+ return 0;
+
+ mutex_lock(&phy->mutex);
+ ret = phy->ops->get_mode_ext(phy);
+ if (!ret)
+ ret = phy->attrs.mode;
+ mutex_unlock(&phy->mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(phy_get_mode_ext);
+
int phy_set_media(struct phy *phy, enum phy_media media)
{
int ret;
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index 0ed434d..7d32c6b 100644
--- a/include/linux/phy/phy.h
+++ b/include/linux/phy/phy.h
@@ -34,6 +34,7 @@ enum phy_mode {
PHY_MODE_USB_DEVICE_HS,
PHY_MODE_USB_DEVICE_SS,
PHY_MODE_USB_OTG,
+ PHY_MODE_UART,
PHY_MODE_UFS_HS_A,
PHY_MODE_UFS_HS_B,
PHY_MODE_PCIE,
@@ -70,6 +71,7 @@ enum phy_media {
* @power_on: powering on the phy
* @power_off: powering off the phy
* @set_mode: set the mode of the phy
+ * @get_mode_ext: get the extented mode of the phy
* @set_media: set the media type of the phy (optional)
* @set_speed: set the speed of the phy (optional)
* @reset: resetting the phy
@@ -83,6 +85,7 @@ struct phy_ops {
int (*power_on)(struct phy *phy);
int (*power_off)(struct phy *phy);
int (*set_mode)(struct phy *phy, enum phy_mode mode, int submode);
+ int (*get_mode_ext)(struct phy *phy);
int (*set_media)(struct phy *phy, enum phy_media media);
int (*set_speed)(struct phy *phy, int speed);
--
1.7.9.5
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 1/2] phy: introduce phy mode PHY_MODE_UART and phy_get_mode_ext()
@ 2021-07-27 10:50 ` Macpaul Lin
0 siblings, 0 replies; 22+ messages in thread
From: Macpaul Lin @ 2021-07-27 10:50 UTC (permalink / raw)
To: linux-phy, Chunfeng Yun, Kishon Vijay Abraham I, Vinod Koul,
Matthias Brugger
Cc: Ainge Hsu, Eddie Hung, Kuohong Wang, Mediatek WSD Upstream,
Macpaul Lin, Macpaul Lin, linux-kernel, linux-arm-kernel,
linux-usb, linux-mediatek
Some embedded platform shared PINs between USB and UART.
For example, some phone will use special cable detection in boot loader
to switch USB port function into UART mode. Hence Kernel need to query
the hardware state from PHY registers to confirm the initialzation flow
for PHY and USB driver.
To support this kind of PIN switch, new PHY MODE and query API is
required. Here we introduce a new PHY mode: PHY_MODE_UART.
API phy_get_mode_ext() can be used to query the MODE from hardware
instead of reading it from phy attributes.
Signed-off-by: Macpaul Lin <macpaul.lin@mediatek.com>
---
drivers/phy/phy-core.c | 17 +++++++++++++++++
include/linux/phy/phy.h | 3 +++
2 files changed, 20 insertions(+)
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
index ccb575b..b8f6539 100644
--- a/drivers/phy/phy-core.c
+++ b/drivers/phy/phy-core.c
@@ -373,6 +373,23 @@ int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode)
}
EXPORT_SYMBOL_GPL(phy_set_mode_ext);
+int phy_get_mode_ext(struct phy *phy)
+{
+ int ret;
+
+ if (!phy || !phy->ops->get_mode_ext)
+ return 0;
+
+ mutex_lock(&phy->mutex);
+ ret = phy->ops->get_mode_ext(phy);
+ if (!ret)
+ ret = phy->attrs.mode;
+ mutex_unlock(&phy->mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(phy_get_mode_ext);
+
int phy_set_media(struct phy *phy, enum phy_media media)
{
int ret;
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index 0ed434d..7d32c6b 100644
--- a/include/linux/phy/phy.h
+++ b/include/linux/phy/phy.h
@@ -34,6 +34,7 @@ enum phy_mode {
PHY_MODE_USB_DEVICE_HS,
PHY_MODE_USB_DEVICE_SS,
PHY_MODE_USB_OTG,
+ PHY_MODE_UART,
PHY_MODE_UFS_HS_A,
PHY_MODE_UFS_HS_B,
PHY_MODE_PCIE,
@@ -70,6 +71,7 @@ enum phy_media {
* @power_on: powering on the phy
* @power_off: powering off the phy
* @set_mode: set the mode of the phy
+ * @get_mode_ext: get the extented mode of the phy
* @set_media: set the media type of the phy (optional)
* @set_speed: set the speed of the phy (optional)
* @reset: resetting the phy
@@ -83,6 +85,7 @@ struct phy_ops {
int (*power_on)(struct phy *phy);
int (*power_off)(struct phy *phy);
int (*set_mode)(struct phy *phy, enum phy_mode mode, int submode);
+ int (*get_mode_ext)(struct phy *phy);
int (*set_media)(struct phy *phy, enum phy_media media);
int (*set_speed)(struct phy *phy, int speed);
--
1.7.9.5
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 2/2] phy: mediatek: phy-mtk-tphy: support USB2UART switch
2021-07-27 10:50 ` Macpaul Lin
(?)
(?)
@ 2021-07-27 10:50 ` Macpaul Lin
-1 siblings, 0 replies; 22+ messages in thread
From: Macpaul Lin @ 2021-07-27 10:50 UTC (permalink / raw)
To: linux-phy, Chunfeng Yun, Kishon Vijay Abraham I, Vinod Koul,
Matthias Brugger
Cc: Ainge Hsu, Eddie Hung, Kuohong Wang, Mediatek WSD Upstream,
Macpaul Lin, Macpaul Lin, linux-kernel, linux-arm-kernel,
linux-usb, linux-mediatek
Some embedded platform shared PINs between USB and UART.
For example, some phone will use special cable detection in boot loader
to switch USB port function into UART mode.
This patch support USB2UART switch function in phy-mtk-tphy.
1. Implement USB2UART switch API support in phy-mtk-tphy.
2. Use PHY_MODE_UART support according to new mode in phy.h.
3. Use mtk_phy_get_mode_ext() to query the current MODE from hardware.
Signed-off-by: Macpaul Lin <macpaul.lin@mediatek.com>
---
drivers/phy/mediatek/phy-mtk-tphy.c | 114 +++++++++++++++++++++++++++++++++++
1 file changed, 114 insertions(+)
diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
index cdbcc49..a7dfeec 100644
--- a/drivers/phy/mediatek/phy-mtk-tphy.c
+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
@@ -68,6 +68,7 @@
#define PA6_RG_U2_SQTH_VAL(x) (0xf & (x))
#define U3P_U2PHYACR4 0x020
+#define P2C_RG_USB20_DM_100K_EN BIT(17)
#define P2C_RG_USB20_GPIO_CTL BIT(9)
#define P2C_USB20_GPIO_MODE BIT(8)
#define P2C_U2_GPIO_CTR_MSK (P2C_RG_USB20_GPIO_CTL | P2C_USB20_GPIO_MODE)
@@ -76,6 +77,12 @@
#define P2C_RG_SIF_U2PLL_FORCE_ON BIT(24)
#define U3P_U2PHYDTM0 0x068
+#define P2C_RG_UART_MODE GENMASK(31, 30)
+#define P2C_RG_UART_MODE_VAL(x) ((0x3 & (x)) << 30)
+#define P2C_RG_UART_MODE_OFET (30)
+#define P2C_FORCE_UART_I BIT(29)
+#define P2C_FORCE_UART_BIAS_EN BIT(28)
+#define P2C_FORCE_UART_TX_OE BIT(27)
#define P2C_FORCE_UART_EN BIT(26)
#define P2C_FORCE_DATAIN BIT(23)
#define P2C_FORCE_DM_PULLDOWN BIT(21)
@@ -98,6 +105,8 @@
P2C_RG_DPPULLDOWN | P2C_RG_TERMSEL)
#define U3P_U2PHYDTM1 0x06C
+#define P2C_RG_UART_BIAS_EN BIT(18)
+#define P2C_RG_UART_TX_OE BIT(17)
#define P2C_RG_UART_EN BIT(16)
#define P2C_FORCE_IDDIG BIT(9)
#define P2C_RG_VBUSVALID BIT(5)
@@ -600,6 +609,90 @@ static void u2_phy_instance_exit(struct mtk_tphy *tphy,
}
}
+static void u2_phy_instance_set_mode_2uart(struct u2phy_banks *u2_banks)
+{
+ u32 tmp;
+
+ /* Clear PA6_RG_U2_BC11_SW_EN */
+ tmp = readl(u2_banks->com + U3P_USBPHYACR6);
+ tmp &= ~(PA6_RG_U2_BC11_SW_EN);
+ writel(tmp, u2_banks->com + U3P_USBPHYACR6);
+
+ /* Set P2C_RG_SUSPENDM */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp |= P2C_RG_SUSPENDM;
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Set P2C_FORCE_SUSPENDM */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp |= P2C_FORCE_SUSPENDM;
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Clear and Set P2C_RG_UART_MODE to 2'b01 */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp &= ~(P2C_RG_UART_MODE);
+ tmp |= P2C_RG_UART_MODE_VAL(0x1);
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Clear P2C_FORCE_UART_I */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp &= ~(P2C_FORCE_UART_I);
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Set P2C_FORCE_UART_BIAS_EN */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp |= P2C_FORCE_UART_BIAS_EN;
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Set P2C_FORCE_UART_TX_OE */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp |= P2C_FORCE_UART_TX_OE;
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Set P2C_FORCE_UART_EN */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp |= P2C_FORCE_UART_EN;
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Set P2C_RG_UART_BIAS_EN */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp |= P2C_RG_UART_BIAS_EN;
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Set P2C_RG_UART_TX_OE */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp |= P2C_RG_UART_TX_OE;
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Set P2C_RG_UART_EN */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp |= P2C_RG_UART_EN;
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Set P2C_RG_USB20_DM_100K_EN */
+ tmp = readl(u2_banks->com + U3P_U2PHYACR4);
+ tmp |= P2C_RG_USB20_DM_100K_EN;
+ writel(tmp, u2_banks->com + U3P_U2PHYACR4);
+
+ /* Clear P2C_RG_DMPULLDOWN, P2C_RG_DPPULLDOWN */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp &= ~(P2C_RG_DPPULLDOWN | P2C_RG_DMPULLDOWN);
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+}
+
+static int u2_phy_instance_get_mode_ext(struct mtk_tphy *tphy, struct mtk_phy_instance *instance)
+{
+ struct u2phy_banks *u2_banks = &instance->u2_banks;
+ u32 tmp;
+
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+
+ if ((tmp & P2C_RG_UART_MODE) >> P2C_RG_UART_MODE_OFET)
+ return PHY_MODE_UART;
+ else
+ return PHY_MODE_USB_OTG;
+}
+
static void u2_phy_instance_set_mode(struct mtk_tphy *tphy,
struct mtk_phy_instance *instance,
enum phy_mode mode)
@@ -609,6 +702,9 @@ static void u2_phy_instance_set_mode(struct mtk_tphy *tphy,
tmp = readl(u2_banks->com + U3P_U2PHYDTM1);
switch (mode) {
+ case PHY_MODE_UART:
+ u2_phy_instance_set_mode_2uart(u2_banks);
+ return;
case PHY_MODE_USB_DEVICE:
tmp |= P2C_FORCE_IDDIG | P2C_RG_IDDIG;
break;
@@ -933,6 +1029,10 @@ static int mtk_phy_init(struct phy *phy)
return ret;
}
+ ret = u2_phy_instance_get_mode_ext(tphy, instance);
+ if (ret == PHY_MODE_UART)
+ return 0;
+
switch (instance->type) {
case PHY_TYPE_USB2:
u2_phy_instance_init(tphy, instance);
@@ -996,6 +1096,19 @@ static int mtk_phy_exit(struct phy *phy)
return 0;
}
+static int mtk_phy_get_mode_ext(struct phy *phy)
+{
+ struct mtk_phy_instance *instance = phy_get_drvdata(phy);
+ struct mtk_tphy *tphy = dev_get_drvdata(phy->dev.parent);
+ int ret;
+
+ ret = 0;
+ if (instance->type == PHY_TYPE_USB2)
+ ret = u2_phy_instance_get_mode_ext(tphy, instance);
+
+ return ret;
+}
+
static int mtk_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
{
struct mtk_phy_instance *instance = phy_get_drvdata(phy);
@@ -1060,6 +1173,7 @@ static struct phy *mtk_phy_xlate(struct device *dev,
.power_on = mtk_phy_power_on,
.power_off = mtk_phy_power_off,
.set_mode = mtk_phy_set_mode,
+ .get_mode_ext = mtk_phy_get_mode_ext,
.owner = THIS_MODULE,
};
--
1.7.9.5
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 2/2] phy: mediatek: phy-mtk-tphy: support USB2UART switch
@ 2021-07-27 10:50 ` Macpaul Lin
0 siblings, 0 replies; 22+ messages in thread
From: Macpaul Lin @ 2021-07-27 10:50 UTC (permalink / raw)
To: linux-phy, Chunfeng Yun, Kishon Vijay Abraham I, Vinod Koul,
Matthias Brugger
Cc: Ainge Hsu, Eddie Hung, Kuohong Wang, Mediatek WSD Upstream,
Macpaul Lin, Macpaul Lin, linux-kernel, linux-arm-kernel,
linux-usb, linux-mediatek
Some embedded platform shared PINs between USB and UART.
For example, some phone will use special cable detection in boot loader
to switch USB port function into UART mode.
This patch support USB2UART switch function in phy-mtk-tphy.
1. Implement USB2UART switch API support in phy-mtk-tphy.
2. Use PHY_MODE_UART support according to new mode in phy.h.
3. Use mtk_phy_get_mode_ext() to query the current MODE from hardware.
Signed-off-by: Macpaul Lin <macpaul.lin@mediatek.com>
---
drivers/phy/mediatek/phy-mtk-tphy.c | 114 +++++++++++++++++++++++++++++++++++
1 file changed, 114 insertions(+)
diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
index cdbcc49..a7dfeec 100644
--- a/drivers/phy/mediatek/phy-mtk-tphy.c
+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
@@ -68,6 +68,7 @@
#define PA6_RG_U2_SQTH_VAL(x) (0xf & (x))
#define U3P_U2PHYACR4 0x020
+#define P2C_RG_USB20_DM_100K_EN BIT(17)
#define P2C_RG_USB20_GPIO_CTL BIT(9)
#define P2C_USB20_GPIO_MODE BIT(8)
#define P2C_U2_GPIO_CTR_MSK (P2C_RG_USB20_GPIO_CTL | P2C_USB20_GPIO_MODE)
@@ -76,6 +77,12 @@
#define P2C_RG_SIF_U2PLL_FORCE_ON BIT(24)
#define U3P_U2PHYDTM0 0x068
+#define P2C_RG_UART_MODE GENMASK(31, 30)
+#define P2C_RG_UART_MODE_VAL(x) ((0x3 & (x)) << 30)
+#define P2C_RG_UART_MODE_OFET (30)
+#define P2C_FORCE_UART_I BIT(29)
+#define P2C_FORCE_UART_BIAS_EN BIT(28)
+#define P2C_FORCE_UART_TX_OE BIT(27)
#define P2C_FORCE_UART_EN BIT(26)
#define P2C_FORCE_DATAIN BIT(23)
#define P2C_FORCE_DM_PULLDOWN BIT(21)
@@ -98,6 +105,8 @@
P2C_RG_DPPULLDOWN | P2C_RG_TERMSEL)
#define U3P_U2PHYDTM1 0x06C
+#define P2C_RG_UART_BIAS_EN BIT(18)
+#define P2C_RG_UART_TX_OE BIT(17)
#define P2C_RG_UART_EN BIT(16)
#define P2C_FORCE_IDDIG BIT(9)
#define P2C_RG_VBUSVALID BIT(5)
@@ -600,6 +609,90 @@ static void u2_phy_instance_exit(struct mtk_tphy *tphy,
}
}
+static void u2_phy_instance_set_mode_2uart(struct u2phy_banks *u2_banks)
+{
+ u32 tmp;
+
+ /* Clear PA6_RG_U2_BC11_SW_EN */
+ tmp = readl(u2_banks->com + U3P_USBPHYACR6);
+ tmp &= ~(PA6_RG_U2_BC11_SW_EN);
+ writel(tmp, u2_banks->com + U3P_USBPHYACR6);
+
+ /* Set P2C_RG_SUSPENDM */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp |= P2C_RG_SUSPENDM;
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Set P2C_FORCE_SUSPENDM */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp |= P2C_FORCE_SUSPENDM;
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Clear and Set P2C_RG_UART_MODE to 2'b01 */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp &= ~(P2C_RG_UART_MODE);
+ tmp |= P2C_RG_UART_MODE_VAL(0x1);
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Clear P2C_FORCE_UART_I */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp &= ~(P2C_FORCE_UART_I);
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Set P2C_FORCE_UART_BIAS_EN */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp |= P2C_FORCE_UART_BIAS_EN;
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Set P2C_FORCE_UART_TX_OE */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp |= P2C_FORCE_UART_TX_OE;
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Set P2C_FORCE_UART_EN */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp |= P2C_FORCE_UART_EN;
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Set P2C_RG_UART_BIAS_EN */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp |= P2C_RG_UART_BIAS_EN;
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Set P2C_RG_UART_TX_OE */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp |= P2C_RG_UART_TX_OE;
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Set P2C_RG_UART_EN */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp |= P2C_RG_UART_EN;
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Set P2C_RG_USB20_DM_100K_EN */
+ tmp = readl(u2_banks->com + U3P_U2PHYACR4);
+ tmp |= P2C_RG_USB20_DM_100K_EN;
+ writel(tmp, u2_banks->com + U3P_U2PHYACR4);
+
+ /* Clear P2C_RG_DMPULLDOWN, P2C_RG_DPPULLDOWN */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp &= ~(P2C_RG_DPPULLDOWN | P2C_RG_DMPULLDOWN);
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+}
+
+static int u2_phy_instance_get_mode_ext(struct mtk_tphy *tphy, struct mtk_phy_instance *instance)
+{
+ struct u2phy_banks *u2_banks = &instance->u2_banks;
+ u32 tmp;
+
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+
+ if ((tmp & P2C_RG_UART_MODE) >> P2C_RG_UART_MODE_OFET)
+ return PHY_MODE_UART;
+ else
+ return PHY_MODE_USB_OTG;
+}
+
static void u2_phy_instance_set_mode(struct mtk_tphy *tphy,
struct mtk_phy_instance *instance,
enum phy_mode mode)
@@ -609,6 +702,9 @@ static void u2_phy_instance_set_mode(struct mtk_tphy *tphy,
tmp = readl(u2_banks->com + U3P_U2PHYDTM1);
switch (mode) {
+ case PHY_MODE_UART:
+ u2_phy_instance_set_mode_2uart(u2_banks);
+ return;
case PHY_MODE_USB_DEVICE:
tmp |= P2C_FORCE_IDDIG | P2C_RG_IDDIG;
break;
@@ -933,6 +1029,10 @@ static int mtk_phy_init(struct phy *phy)
return ret;
}
+ ret = u2_phy_instance_get_mode_ext(tphy, instance);
+ if (ret == PHY_MODE_UART)
+ return 0;
+
switch (instance->type) {
case PHY_TYPE_USB2:
u2_phy_instance_init(tphy, instance);
@@ -996,6 +1096,19 @@ static int mtk_phy_exit(struct phy *phy)
return 0;
}
+static int mtk_phy_get_mode_ext(struct phy *phy)
+{
+ struct mtk_phy_instance *instance = phy_get_drvdata(phy);
+ struct mtk_tphy *tphy = dev_get_drvdata(phy->dev.parent);
+ int ret;
+
+ ret = 0;
+ if (instance->type == PHY_TYPE_USB2)
+ ret = u2_phy_instance_get_mode_ext(tphy, instance);
+
+ return ret;
+}
+
static int mtk_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
{
struct mtk_phy_instance *instance = phy_get_drvdata(phy);
@@ -1060,6 +1173,7 @@ static struct phy *mtk_phy_xlate(struct device *dev,
.power_on = mtk_phy_power_on,
.power_off = mtk_phy_power_off,
.set_mode = mtk_phy_set_mode,
+ .get_mode_ext = mtk_phy_get_mode_ext,
.owner = THIS_MODULE,
};
--
1.7.9.5
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 2/2] phy: mediatek: phy-mtk-tphy: support USB2UART switch
@ 2021-07-27 10:50 ` Macpaul Lin
0 siblings, 0 replies; 22+ messages in thread
From: Macpaul Lin @ 2021-07-27 10:50 UTC (permalink / raw)
To: linux-phy, Chunfeng Yun, Kishon Vijay Abraham I, Vinod Koul,
Matthias Brugger
Cc: Ainge Hsu, Eddie Hung, Kuohong Wang, Mediatek WSD Upstream,
Macpaul Lin, Macpaul Lin, linux-kernel, linux-arm-kernel,
linux-usb, linux-mediatek
Some embedded platform shared PINs between USB and UART.
For example, some phone will use special cable detection in boot loader
to switch USB port function into UART mode.
This patch support USB2UART switch function in phy-mtk-tphy.
1. Implement USB2UART switch API support in phy-mtk-tphy.
2. Use PHY_MODE_UART support according to new mode in phy.h.
3. Use mtk_phy_get_mode_ext() to query the current MODE from hardware.
Signed-off-by: Macpaul Lin <macpaul.lin@mediatek.com>
---
drivers/phy/mediatek/phy-mtk-tphy.c | 114 +++++++++++++++++++++++++++++++++++
1 file changed, 114 insertions(+)
diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
index cdbcc49..a7dfeec 100644
--- a/drivers/phy/mediatek/phy-mtk-tphy.c
+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
@@ -68,6 +68,7 @@
#define PA6_RG_U2_SQTH_VAL(x) (0xf & (x))
#define U3P_U2PHYACR4 0x020
+#define P2C_RG_USB20_DM_100K_EN BIT(17)
#define P2C_RG_USB20_GPIO_CTL BIT(9)
#define P2C_USB20_GPIO_MODE BIT(8)
#define P2C_U2_GPIO_CTR_MSK (P2C_RG_USB20_GPIO_CTL | P2C_USB20_GPIO_MODE)
@@ -76,6 +77,12 @@
#define P2C_RG_SIF_U2PLL_FORCE_ON BIT(24)
#define U3P_U2PHYDTM0 0x068
+#define P2C_RG_UART_MODE GENMASK(31, 30)
+#define P2C_RG_UART_MODE_VAL(x) ((0x3 & (x)) << 30)
+#define P2C_RG_UART_MODE_OFET (30)
+#define P2C_FORCE_UART_I BIT(29)
+#define P2C_FORCE_UART_BIAS_EN BIT(28)
+#define P2C_FORCE_UART_TX_OE BIT(27)
#define P2C_FORCE_UART_EN BIT(26)
#define P2C_FORCE_DATAIN BIT(23)
#define P2C_FORCE_DM_PULLDOWN BIT(21)
@@ -98,6 +105,8 @@
P2C_RG_DPPULLDOWN | P2C_RG_TERMSEL)
#define U3P_U2PHYDTM1 0x06C
+#define P2C_RG_UART_BIAS_EN BIT(18)
+#define P2C_RG_UART_TX_OE BIT(17)
#define P2C_RG_UART_EN BIT(16)
#define P2C_FORCE_IDDIG BIT(9)
#define P2C_RG_VBUSVALID BIT(5)
@@ -600,6 +609,90 @@ static void u2_phy_instance_exit(struct mtk_tphy *tphy,
}
}
+static void u2_phy_instance_set_mode_2uart(struct u2phy_banks *u2_banks)
+{
+ u32 tmp;
+
+ /* Clear PA6_RG_U2_BC11_SW_EN */
+ tmp = readl(u2_banks->com + U3P_USBPHYACR6);
+ tmp &= ~(PA6_RG_U2_BC11_SW_EN);
+ writel(tmp, u2_banks->com + U3P_USBPHYACR6);
+
+ /* Set P2C_RG_SUSPENDM */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp |= P2C_RG_SUSPENDM;
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Set P2C_FORCE_SUSPENDM */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp |= P2C_FORCE_SUSPENDM;
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Clear and Set P2C_RG_UART_MODE to 2'b01 */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp &= ~(P2C_RG_UART_MODE);
+ tmp |= P2C_RG_UART_MODE_VAL(0x1);
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Clear P2C_FORCE_UART_I */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp &= ~(P2C_FORCE_UART_I);
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Set P2C_FORCE_UART_BIAS_EN */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp |= P2C_FORCE_UART_BIAS_EN;
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Set P2C_FORCE_UART_TX_OE */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp |= P2C_FORCE_UART_TX_OE;
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Set P2C_FORCE_UART_EN */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp |= P2C_FORCE_UART_EN;
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Set P2C_RG_UART_BIAS_EN */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp |= P2C_RG_UART_BIAS_EN;
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Set P2C_RG_UART_TX_OE */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp |= P2C_RG_UART_TX_OE;
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Set P2C_RG_UART_EN */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp |= P2C_RG_UART_EN;
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Set P2C_RG_USB20_DM_100K_EN */
+ tmp = readl(u2_banks->com + U3P_U2PHYACR4);
+ tmp |= P2C_RG_USB20_DM_100K_EN;
+ writel(tmp, u2_banks->com + U3P_U2PHYACR4);
+
+ /* Clear P2C_RG_DMPULLDOWN, P2C_RG_DPPULLDOWN */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp &= ~(P2C_RG_DPPULLDOWN | P2C_RG_DMPULLDOWN);
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+}
+
+static int u2_phy_instance_get_mode_ext(struct mtk_tphy *tphy, struct mtk_phy_instance *instance)
+{
+ struct u2phy_banks *u2_banks = &instance->u2_banks;
+ u32 tmp;
+
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+
+ if ((tmp & P2C_RG_UART_MODE) >> P2C_RG_UART_MODE_OFET)
+ return PHY_MODE_UART;
+ else
+ return PHY_MODE_USB_OTG;
+}
+
static void u2_phy_instance_set_mode(struct mtk_tphy *tphy,
struct mtk_phy_instance *instance,
enum phy_mode mode)
@@ -609,6 +702,9 @@ static void u2_phy_instance_set_mode(struct mtk_tphy *tphy,
tmp = readl(u2_banks->com + U3P_U2PHYDTM1);
switch (mode) {
+ case PHY_MODE_UART:
+ u2_phy_instance_set_mode_2uart(u2_banks);
+ return;
case PHY_MODE_USB_DEVICE:
tmp |= P2C_FORCE_IDDIG | P2C_RG_IDDIG;
break;
@@ -933,6 +1029,10 @@ static int mtk_phy_init(struct phy *phy)
return ret;
}
+ ret = u2_phy_instance_get_mode_ext(tphy, instance);
+ if (ret == PHY_MODE_UART)
+ return 0;
+
switch (instance->type) {
case PHY_TYPE_USB2:
u2_phy_instance_init(tphy, instance);
@@ -996,6 +1096,19 @@ static int mtk_phy_exit(struct phy *phy)
return 0;
}
+static int mtk_phy_get_mode_ext(struct phy *phy)
+{
+ struct mtk_phy_instance *instance = phy_get_drvdata(phy);
+ struct mtk_tphy *tphy = dev_get_drvdata(phy->dev.parent);
+ int ret;
+
+ ret = 0;
+ if (instance->type == PHY_TYPE_USB2)
+ ret = u2_phy_instance_get_mode_ext(tphy, instance);
+
+ return ret;
+}
+
static int mtk_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
{
struct mtk_phy_instance *instance = phy_get_drvdata(phy);
@@ -1060,6 +1173,7 @@ static struct phy *mtk_phy_xlate(struct device *dev,
.power_on = mtk_phy_power_on,
.power_off = mtk_phy_power_off,
.set_mode = mtk_phy_set_mode,
+ .get_mode_ext = mtk_phy_get_mode_ext,
.owner = THIS_MODULE,
};
--
1.7.9.5
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 2/2] phy: mediatek: phy-mtk-tphy: support USB2UART switch
@ 2021-07-27 10:50 ` Macpaul Lin
0 siblings, 0 replies; 22+ messages in thread
From: Macpaul Lin @ 2021-07-27 10:50 UTC (permalink / raw)
To: linux-phy, Chunfeng Yun, Kishon Vijay Abraham I, Vinod Koul,
Matthias Brugger
Cc: Ainge Hsu, Eddie Hung, Kuohong Wang, Mediatek WSD Upstream,
Macpaul Lin, Macpaul Lin, linux-kernel, linux-arm-kernel,
linux-usb, linux-mediatek
Some embedded platform shared PINs between USB and UART.
For example, some phone will use special cable detection in boot loader
to switch USB port function into UART mode.
This patch support USB2UART switch function in phy-mtk-tphy.
1. Implement USB2UART switch API support in phy-mtk-tphy.
2. Use PHY_MODE_UART support according to new mode in phy.h.
3. Use mtk_phy_get_mode_ext() to query the current MODE from hardware.
Signed-off-by: Macpaul Lin <macpaul.lin@mediatek.com>
---
drivers/phy/mediatek/phy-mtk-tphy.c | 114 +++++++++++++++++++++++++++++++++++
1 file changed, 114 insertions(+)
diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
index cdbcc49..a7dfeec 100644
--- a/drivers/phy/mediatek/phy-mtk-tphy.c
+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
@@ -68,6 +68,7 @@
#define PA6_RG_U2_SQTH_VAL(x) (0xf & (x))
#define U3P_U2PHYACR4 0x020
+#define P2C_RG_USB20_DM_100K_EN BIT(17)
#define P2C_RG_USB20_GPIO_CTL BIT(9)
#define P2C_USB20_GPIO_MODE BIT(8)
#define P2C_U2_GPIO_CTR_MSK (P2C_RG_USB20_GPIO_CTL | P2C_USB20_GPIO_MODE)
@@ -76,6 +77,12 @@
#define P2C_RG_SIF_U2PLL_FORCE_ON BIT(24)
#define U3P_U2PHYDTM0 0x068
+#define P2C_RG_UART_MODE GENMASK(31, 30)
+#define P2C_RG_UART_MODE_VAL(x) ((0x3 & (x)) << 30)
+#define P2C_RG_UART_MODE_OFET (30)
+#define P2C_FORCE_UART_I BIT(29)
+#define P2C_FORCE_UART_BIAS_EN BIT(28)
+#define P2C_FORCE_UART_TX_OE BIT(27)
#define P2C_FORCE_UART_EN BIT(26)
#define P2C_FORCE_DATAIN BIT(23)
#define P2C_FORCE_DM_PULLDOWN BIT(21)
@@ -98,6 +105,8 @@
P2C_RG_DPPULLDOWN | P2C_RG_TERMSEL)
#define U3P_U2PHYDTM1 0x06C
+#define P2C_RG_UART_BIAS_EN BIT(18)
+#define P2C_RG_UART_TX_OE BIT(17)
#define P2C_RG_UART_EN BIT(16)
#define P2C_FORCE_IDDIG BIT(9)
#define P2C_RG_VBUSVALID BIT(5)
@@ -600,6 +609,90 @@ static void u2_phy_instance_exit(struct mtk_tphy *tphy,
}
}
+static void u2_phy_instance_set_mode_2uart(struct u2phy_banks *u2_banks)
+{
+ u32 tmp;
+
+ /* Clear PA6_RG_U2_BC11_SW_EN */
+ tmp = readl(u2_banks->com + U3P_USBPHYACR6);
+ tmp &= ~(PA6_RG_U2_BC11_SW_EN);
+ writel(tmp, u2_banks->com + U3P_USBPHYACR6);
+
+ /* Set P2C_RG_SUSPENDM */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp |= P2C_RG_SUSPENDM;
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Set P2C_FORCE_SUSPENDM */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp |= P2C_FORCE_SUSPENDM;
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Clear and Set P2C_RG_UART_MODE to 2'b01 */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp &= ~(P2C_RG_UART_MODE);
+ tmp |= P2C_RG_UART_MODE_VAL(0x1);
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Clear P2C_FORCE_UART_I */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp &= ~(P2C_FORCE_UART_I);
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Set P2C_FORCE_UART_BIAS_EN */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp |= P2C_FORCE_UART_BIAS_EN;
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Set P2C_FORCE_UART_TX_OE */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp |= P2C_FORCE_UART_TX_OE;
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Set P2C_FORCE_UART_EN */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp |= P2C_FORCE_UART_EN;
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Set P2C_RG_UART_BIAS_EN */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp |= P2C_RG_UART_BIAS_EN;
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Set P2C_RG_UART_TX_OE */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp |= P2C_RG_UART_TX_OE;
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Set P2C_RG_UART_EN */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp |= P2C_RG_UART_EN;
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+
+ /* Set P2C_RG_USB20_DM_100K_EN */
+ tmp = readl(u2_banks->com + U3P_U2PHYACR4);
+ tmp |= P2C_RG_USB20_DM_100K_EN;
+ writel(tmp, u2_banks->com + U3P_U2PHYACR4);
+
+ /* Clear P2C_RG_DMPULLDOWN, P2C_RG_DPPULLDOWN */
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+ tmp &= ~(P2C_RG_DPPULLDOWN | P2C_RG_DMPULLDOWN);
+ writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
+}
+
+static int u2_phy_instance_get_mode_ext(struct mtk_tphy *tphy, struct mtk_phy_instance *instance)
+{
+ struct u2phy_banks *u2_banks = &instance->u2_banks;
+ u32 tmp;
+
+ tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
+
+ if ((tmp & P2C_RG_UART_MODE) >> P2C_RG_UART_MODE_OFET)
+ return PHY_MODE_UART;
+ else
+ return PHY_MODE_USB_OTG;
+}
+
static void u2_phy_instance_set_mode(struct mtk_tphy *tphy,
struct mtk_phy_instance *instance,
enum phy_mode mode)
@@ -609,6 +702,9 @@ static void u2_phy_instance_set_mode(struct mtk_tphy *tphy,
tmp = readl(u2_banks->com + U3P_U2PHYDTM1);
switch (mode) {
+ case PHY_MODE_UART:
+ u2_phy_instance_set_mode_2uart(u2_banks);
+ return;
case PHY_MODE_USB_DEVICE:
tmp |= P2C_FORCE_IDDIG | P2C_RG_IDDIG;
break;
@@ -933,6 +1029,10 @@ static int mtk_phy_init(struct phy *phy)
return ret;
}
+ ret = u2_phy_instance_get_mode_ext(tphy, instance);
+ if (ret == PHY_MODE_UART)
+ return 0;
+
switch (instance->type) {
case PHY_TYPE_USB2:
u2_phy_instance_init(tphy, instance);
@@ -996,6 +1096,19 @@ static int mtk_phy_exit(struct phy *phy)
return 0;
}
+static int mtk_phy_get_mode_ext(struct phy *phy)
+{
+ struct mtk_phy_instance *instance = phy_get_drvdata(phy);
+ struct mtk_tphy *tphy = dev_get_drvdata(phy->dev.parent);
+ int ret;
+
+ ret = 0;
+ if (instance->type == PHY_TYPE_USB2)
+ ret = u2_phy_instance_get_mode_ext(tphy, instance);
+
+ return ret;
+}
+
static int mtk_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
{
struct mtk_phy_instance *instance = phy_get_drvdata(phy);
@@ -1060,6 +1173,7 @@ static struct phy *mtk_phy_xlate(struct device *dev,
.power_on = mtk_phy_power_on,
.power_off = mtk_phy_power_off,
.set_mode = mtk_phy_set_mode,
+ .get_mode_ext = mtk_phy_get_mode_ext,
.owner = THIS_MODULE,
};
--
1.7.9.5
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH 2/2] phy: mediatek: phy-mtk-tphy: support USB2UART switch
2021-07-27 10:50 ` Macpaul Lin
(?)
(?)
@ 2021-07-28 1:55 ` Chunfeng Yun
-1 siblings, 0 replies; 22+ messages in thread
From: Chunfeng Yun @ 2021-07-28 1:55 UTC (permalink / raw)
To: Macpaul Lin
Cc: linux-phy, Kishon Vijay Abraham I, Vinod Koul, Matthias Brugger,
Ainge Hsu, Eddie Hung, Kuohong Wang, Mediatek WSD Upstream,
Macpaul Lin, linux-kernel, linux-arm-kernel, linux-usb,
linux-mediatek
On Tue, 2021-07-27 at 18:50 +0800, Macpaul Lin wrote:
> Some embedded platform shared PINs between USB and UART.
> For example, some phone will use special cable detection in boot loader
> to switch USB port function into UART mode.
>
> This patch support USB2UART switch function in phy-mtk-tphy.
> 1. Implement USB2UART switch API support in phy-mtk-tphy.
> 2. Use PHY_MODE_UART support according to new mode in phy.h.
> 3. Use mtk_phy_get_mode_ext() to query the current MODE from hardware.
>
> Signed-off-by: Macpaul Lin <macpaul.lin@mediatek.com>
> ---
> drivers/phy/mediatek/phy-mtk-tphy.c | 114 +++++++++++++++++++++++++++++++++++
> 1 file changed, 114 insertions(+)
>
title: please use "phy: phy-mtk-tphy: ..." as other patches
> diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
> index cdbcc49..a7dfeec 100644
> --- a/drivers/phy/mediatek/phy-mtk-tphy.c
> +++ b/drivers/phy/mediatek/phy-mtk-tphy.c
> @@ -68,6 +68,7 @@
> #define PA6_RG_U2_SQTH_VAL(x) (0xf & (x))
>
> #define U3P_U2PHYACR4 0x020
> +#define P2C_RG_USB20_DM_100K_EN BIT(17)
> #define P2C_RG_USB20_GPIO_CTL BIT(9)
> #define P2C_USB20_GPIO_MODE BIT(8)
> #define P2C_U2_GPIO_CTR_MSK (P2C_RG_USB20_GPIO_CTL | P2C_USB20_GPIO_MODE)
> @@ -76,6 +77,12 @@
> #define P2C_RG_SIF_U2PLL_FORCE_ON BIT(24)
>
> #define U3P_U2PHYDTM0 0x068
> +#define P2C_RG_UART_MODE GENMASK(31, 30)
> +#define P2C_RG_UART_MODE_VAL(x) ((0x3 & (x)) << 30)
> +#define P2C_RG_UART_MODE_OFET (30)
> +#define P2C_FORCE_UART_I BIT(29)
> +#define P2C_FORCE_UART_BIAS_EN BIT(28)
> +#define P2C_FORCE_UART_TX_OE BIT(27)
> #define P2C_FORCE_UART_EN BIT(26)
> #define P2C_FORCE_DATAIN BIT(23)
> #define P2C_FORCE_DM_PULLDOWN BIT(21)
> @@ -98,6 +105,8 @@
> P2C_RG_DPPULLDOWN | P2C_RG_TERMSEL)
>
> #define U3P_U2PHYDTM1 0x06C
> +#define P2C_RG_UART_BIAS_EN BIT(18)
> +#define P2C_RG_UART_TX_OE BIT(17)
> #define P2C_RG_UART_EN BIT(16)
> #define P2C_FORCE_IDDIG BIT(9)
> #define P2C_RG_VBUSVALID BIT(5)
> @@ -600,6 +609,90 @@ static void u2_phy_instance_exit(struct mtk_tphy *tphy,
> }
> }
>
> +static void u2_phy_instance_set_mode_2uart(struct u2phy_banks *u2_banks)
> +{
> + u32 tmp;
> +
> + /* Clear PA6_RG_U2_BC11_SW_EN */
remove the comments
> + tmp = readl(u2_banks->com + U3P_USBPHYACR6);
> + tmp &= ~(PA6_RG_U2_BC11_SW_EN);
> + writel(tmp, u2_banks->com + U3P_USBPHYACR6);
> +
> + /* Set P2C_RG_SUSPENDM */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp |= P2C_RG_SUSPENDM;
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Set P2C_FORCE_SUSPENDM */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp |= P2C_FORCE_SUSPENDM;
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Clear and Set P2C_RG_UART_MODE to 2'b01 */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp &= ~(P2C_RG_UART_MODE);
> + tmp |= P2C_RG_UART_MODE_VAL(0x1);
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Clear P2C_FORCE_UART_I */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp &= ~(P2C_FORCE_UART_I);
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Set P2C_FORCE_UART_BIAS_EN */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp |= P2C_FORCE_UART_BIAS_EN;
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Set P2C_FORCE_UART_TX_OE */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp |= P2C_FORCE_UART_TX_OE;
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Set P2C_FORCE_UART_EN */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp |= P2C_FORCE_UART_EN;
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Set P2C_RG_UART_BIAS_EN */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp |= P2C_RG_UART_BIAS_EN;
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Set P2C_RG_UART_TX_OE */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp |= P2C_RG_UART_TX_OE;
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Set P2C_RG_UART_EN */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp |= P2C_RG_UART_EN;
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Set P2C_RG_USB20_DM_100K_EN */
> + tmp = readl(u2_banks->com + U3P_U2PHYACR4);
> + tmp |= P2C_RG_USB20_DM_100K_EN;
> + writel(tmp, u2_banks->com + U3P_U2PHYACR4);
> +
> + /* Clear P2C_RG_DMPULLDOWN, P2C_RG_DPPULLDOWN */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp &= ~(P2C_RG_DPPULLDOWN | P2C_RG_DMPULLDOWN);
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +}
> +
> +static int u2_phy_instance_get_mode_ext(struct mtk_tphy *tphy, struct mtk_phy_instance *instance)
> +{
> + struct u2phy_banks *u2_banks = &instance->u2_banks;
> + u32 tmp;
> +
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> +
> + if ((tmp & P2C_RG_UART_MODE) >> P2C_RG_UART_MODE_OFET)
> + return PHY_MODE_UART;
> + else
> + return PHY_MODE_USB_OTG;
> +}
> +
> static void u2_phy_instance_set_mode(struct mtk_tphy *tphy,
> struct mtk_phy_instance *instance,
> enum phy_mode mode)
> @@ -609,6 +702,9 @@ static void u2_phy_instance_set_mode(struct mtk_tphy *tphy,
>
> tmp = readl(u2_banks->com + U3P_U2PHYDTM1);
> switch (mode) {
> + case PHY_MODE_UART:
> + u2_phy_instance_set_mode_2uart(u2_banks);
How do you use this helper?
Can we switch back to usb phy mode if switching to uart?
When switch to uart mode, if the host supports multi-ports, it will
cause the host can't enter sleep mode anymore.
> + return;
> case PHY_MODE_USB_DEVICE:
> tmp |= P2C_FORCE_IDDIG | P2C_RG_IDDIG;
> break;
> @@ -933,6 +1029,10 @@ static int mtk_phy_init(struct phy *phy)
> return ret;
> }
>
> + ret = u2_phy_instance_get_mode_ext(tphy, instance);
> + if (ret == PHY_MODE_UART)
> + return 0;
> +
> switch (instance->type) {
> case PHY_TYPE_USB2:
> u2_phy_instance_init(tphy, instance);
> @@ -996,6 +1096,19 @@ static int mtk_phy_exit(struct phy *phy)
> return 0;
> }
>
> +static int mtk_phy_get_mode_ext(struct phy *phy)
> +{
> + struct mtk_phy_instance *instance = phy_get_drvdata(phy);
> + struct mtk_tphy *tphy = dev_get_drvdata(phy->dev.parent);
> + int ret;
> +
> + ret = 0;
> + if (instance->type == PHY_TYPE_USB2)
> + ret = u2_phy_instance_get_mode_ext(tphy, instance);
> +
> + return ret;
> +}
> +
> static int mtk_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
> {
> struct mtk_phy_instance *instance = phy_get_drvdata(phy);
> @@ -1060,6 +1173,7 @@ static struct phy *mtk_phy_xlate(struct device *dev,
> .power_on = mtk_phy_power_on,
> .power_off = mtk_phy_power_off,
> .set_mode = mtk_phy_set_mode,
> + .get_mode_ext = mtk_phy_get_mode_ext,
> .owner = THIS_MODULE,
> };
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 2/2] phy: mediatek: phy-mtk-tphy: support USB2UART switch
@ 2021-07-28 1:55 ` Chunfeng Yun
0 siblings, 0 replies; 22+ messages in thread
From: Chunfeng Yun @ 2021-07-28 1:55 UTC (permalink / raw)
To: Macpaul Lin
Cc: linux-phy, Kishon Vijay Abraham I, Vinod Koul, Matthias Brugger,
Ainge Hsu, Eddie Hung, Kuohong Wang, Mediatek WSD Upstream,
Macpaul Lin, linux-kernel, linux-arm-kernel, linux-usb,
linux-mediatek
On Tue, 2021-07-27 at 18:50 +0800, Macpaul Lin wrote:
> Some embedded platform shared PINs between USB and UART.
> For example, some phone will use special cable detection in boot loader
> to switch USB port function into UART mode.
>
> This patch support USB2UART switch function in phy-mtk-tphy.
> 1. Implement USB2UART switch API support in phy-mtk-tphy.
> 2. Use PHY_MODE_UART support according to new mode in phy.h.
> 3. Use mtk_phy_get_mode_ext() to query the current MODE from hardware.
>
> Signed-off-by: Macpaul Lin <macpaul.lin@mediatek.com>
> ---
> drivers/phy/mediatek/phy-mtk-tphy.c | 114 +++++++++++++++++++++++++++++++++++
> 1 file changed, 114 insertions(+)
>
title: please use "phy: phy-mtk-tphy: ..." as other patches
> diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
> index cdbcc49..a7dfeec 100644
> --- a/drivers/phy/mediatek/phy-mtk-tphy.c
> +++ b/drivers/phy/mediatek/phy-mtk-tphy.c
> @@ -68,6 +68,7 @@
> #define PA6_RG_U2_SQTH_VAL(x) (0xf & (x))
>
> #define U3P_U2PHYACR4 0x020
> +#define P2C_RG_USB20_DM_100K_EN BIT(17)
> #define P2C_RG_USB20_GPIO_CTL BIT(9)
> #define P2C_USB20_GPIO_MODE BIT(8)
> #define P2C_U2_GPIO_CTR_MSK (P2C_RG_USB20_GPIO_CTL | P2C_USB20_GPIO_MODE)
> @@ -76,6 +77,12 @@
> #define P2C_RG_SIF_U2PLL_FORCE_ON BIT(24)
>
> #define U3P_U2PHYDTM0 0x068
> +#define P2C_RG_UART_MODE GENMASK(31, 30)
> +#define P2C_RG_UART_MODE_VAL(x) ((0x3 & (x)) << 30)
> +#define P2C_RG_UART_MODE_OFET (30)
> +#define P2C_FORCE_UART_I BIT(29)
> +#define P2C_FORCE_UART_BIAS_EN BIT(28)
> +#define P2C_FORCE_UART_TX_OE BIT(27)
> #define P2C_FORCE_UART_EN BIT(26)
> #define P2C_FORCE_DATAIN BIT(23)
> #define P2C_FORCE_DM_PULLDOWN BIT(21)
> @@ -98,6 +105,8 @@
> P2C_RG_DPPULLDOWN | P2C_RG_TERMSEL)
>
> #define U3P_U2PHYDTM1 0x06C
> +#define P2C_RG_UART_BIAS_EN BIT(18)
> +#define P2C_RG_UART_TX_OE BIT(17)
> #define P2C_RG_UART_EN BIT(16)
> #define P2C_FORCE_IDDIG BIT(9)
> #define P2C_RG_VBUSVALID BIT(5)
> @@ -600,6 +609,90 @@ static void u2_phy_instance_exit(struct mtk_tphy *tphy,
> }
> }
>
> +static void u2_phy_instance_set_mode_2uart(struct u2phy_banks *u2_banks)
> +{
> + u32 tmp;
> +
> + /* Clear PA6_RG_U2_BC11_SW_EN */
remove the comments
> + tmp = readl(u2_banks->com + U3P_USBPHYACR6);
> + tmp &= ~(PA6_RG_U2_BC11_SW_EN);
> + writel(tmp, u2_banks->com + U3P_USBPHYACR6);
> +
> + /* Set P2C_RG_SUSPENDM */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp |= P2C_RG_SUSPENDM;
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Set P2C_FORCE_SUSPENDM */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp |= P2C_FORCE_SUSPENDM;
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Clear and Set P2C_RG_UART_MODE to 2'b01 */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp &= ~(P2C_RG_UART_MODE);
> + tmp |= P2C_RG_UART_MODE_VAL(0x1);
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Clear P2C_FORCE_UART_I */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp &= ~(P2C_FORCE_UART_I);
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Set P2C_FORCE_UART_BIAS_EN */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp |= P2C_FORCE_UART_BIAS_EN;
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Set P2C_FORCE_UART_TX_OE */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp |= P2C_FORCE_UART_TX_OE;
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Set P2C_FORCE_UART_EN */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp |= P2C_FORCE_UART_EN;
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Set P2C_RG_UART_BIAS_EN */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp |= P2C_RG_UART_BIAS_EN;
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Set P2C_RG_UART_TX_OE */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp |= P2C_RG_UART_TX_OE;
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Set P2C_RG_UART_EN */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp |= P2C_RG_UART_EN;
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Set P2C_RG_USB20_DM_100K_EN */
> + tmp = readl(u2_banks->com + U3P_U2PHYACR4);
> + tmp |= P2C_RG_USB20_DM_100K_EN;
> + writel(tmp, u2_banks->com + U3P_U2PHYACR4);
> +
> + /* Clear P2C_RG_DMPULLDOWN, P2C_RG_DPPULLDOWN */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp &= ~(P2C_RG_DPPULLDOWN | P2C_RG_DMPULLDOWN);
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +}
> +
> +static int u2_phy_instance_get_mode_ext(struct mtk_tphy *tphy, struct mtk_phy_instance *instance)
> +{
> + struct u2phy_banks *u2_banks = &instance->u2_banks;
> + u32 tmp;
> +
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> +
> + if ((tmp & P2C_RG_UART_MODE) >> P2C_RG_UART_MODE_OFET)
> + return PHY_MODE_UART;
> + else
> + return PHY_MODE_USB_OTG;
> +}
> +
> static void u2_phy_instance_set_mode(struct mtk_tphy *tphy,
> struct mtk_phy_instance *instance,
> enum phy_mode mode)
> @@ -609,6 +702,9 @@ static void u2_phy_instance_set_mode(struct mtk_tphy *tphy,
>
> tmp = readl(u2_banks->com + U3P_U2PHYDTM1);
> switch (mode) {
> + case PHY_MODE_UART:
> + u2_phy_instance_set_mode_2uart(u2_banks);
How do you use this helper?
Can we switch back to usb phy mode if switching to uart?
When switch to uart mode, if the host supports multi-ports, it will
cause the host can't enter sleep mode anymore.
> + return;
> case PHY_MODE_USB_DEVICE:
> tmp |= P2C_FORCE_IDDIG | P2C_RG_IDDIG;
> break;
> @@ -933,6 +1029,10 @@ static int mtk_phy_init(struct phy *phy)
> return ret;
> }
>
> + ret = u2_phy_instance_get_mode_ext(tphy, instance);
> + if (ret == PHY_MODE_UART)
> + return 0;
> +
> switch (instance->type) {
> case PHY_TYPE_USB2:
> u2_phy_instance_init(tphy, instance);
> @@ -996,6 +1096,19 @@ static int mtk_phy_exit(struct phy *phy)
> return 0;
> }
>
> +static int mtk_phy_get_mode_ext(struct phy *phy)
> +{
> + struct mtk_phy_instance *instance = phy_get_drvdata(phy);
> + struct mtk_tphy *tphy = dev_get_drvdata(phy->dev.parent);
> + int ret;
> +
> + ret = 0;
> + if (instance->type == PHY_TYPE_USB2)
> + ret = u2_phy_instance_get_mode_ext(tphy, instance);
> +
> + return ret;
> +}
> +
> static int mtk_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
> {
> struct mtk_phy_instance *instance = phy_get_drvdata(phy);
> @@ -1060,6 +1173,7 @@ static struct phy *mtk_phy_xlate(struct device *dev,
> .power_on = mtk_phy_power_on,
> .power_off = mtk_phy_power_off,
> .set_mode = mtk_phy_set_mode,
> + .get_mode_ext = mtk_phy_get_mode_ext,
> .owner = THIS_MODULE,
> };
>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 2/2] phy: mediatek: phy-mtk-tphy: support USB2UART switch
@ 2021-07-28 1:55 ` Chunfeng Yun
0 siblings, 0 replies; 22+ messages in thread
From: Chunfeng Yun @ 2021-07-28 1:55 UTC (permalink / raw)
To: Macpaul Lin
Cc: linux-phy, Kishon Vijay Abraham I, Vinod Koul, Matthias Brugger,
Ainge Hsu, Eddie Hung, Kuohong Wang, Mediatek WSD Upstream,
Macpaul Lin, linux-kernel, linux-arm-kernel, linux-usb,
linux-mediatek
On Tue, 2021-07-27 at 18:50 +0800, Macpaul Lin wrote:
> Some embedded platform shared PINs between USB and UART.
> For example, some phone will use special cable detection in boot loader
> to switch USB port function into UART mode.
>
> This patch support USB2UART switch function in phy-mtk-tphy.
> 1. Implement USB2UART switch API support in phy-mtk-tphy.
> 2. Use PHY_MODE_UART support according to new mode in phy.h.
> 3. Use mtk_phy_get_mode_ext() to query the current MODE from hardware.
>
> Signed-off-by: Macpaul Lin <macpaul.lin@mediatek.com>
> ---
> drivers/phy/mediatek/phy-mtk-tphy.c | 114 +++++++++++++++++++++++++++++++++++
> 1 file changed, 114 insertions(+)
>
title: please use "phy: phy-mtk-tphy: ..." as other patches
> diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
> index cdbcc49..a7dfeec 100644
> --- a/drivers/phy/mediatek/phy-mtk-tphy.c
> +++ b/drivers/phy/mediatek/phy-mtk-tphy.c
> @@ -68,6 +68,7 @@
> #define PA6_RG_U2_SQTH_VAL(x) (0xf & (x))
>
> #define U3P_U2PHYACR4 0x020
> +#define P2C_RG_USB20_DM_100K_EN BIT(17)
> #define P2C_RG_USB20_GPIO_CTL BIT(9)
> #define P2C_USB20_GPIO_MODE BIT(8)
> #define P2C_U2_GPIO_CTR_MSK (P2C_RG_USB20_GPIO_CTL | P2C_USB20_GPIO_MODE)
> @@ -76,6 +77,12 @@
> #define P2C_RG_SIF_U2PLL_FORCE_ON BIT(24)
>
> #define U3P_U2PHYDTM0 0x068
> +#define P2C_RG_UART_MODE GENMASK(31, 30)
> +#define P2C_RG_UART_MODE_VAL(x) ((0x3 & (x)) << 30)
> +#define P2C_RG_UART_MODE_OFET (30)
> +#define P2C_FORCE_UART_I BIT(29)
> +#define P2C_FORCE_UART_BIAS_EN BIT(28)
> +#define P2C_FORCE_UART_TX_OE BIT(27)
> #define P2C_FORCE_UART_EN BIT(26)
> #define P2C_FORCE_DATAIN BIT(23)
> #define P2C_FORCE_DM_PULLDOWN BIT(21)
> @@ -98,6 +105,8 @@
> P2C_RG_DPPULLDOWN | P2C_RG_TERMSEL)
>
> #define U3P_U2PHYDTM1 0x06C
> +#define P2C_RG_UART_BIAS_EN BIT(18)
> +#define P2C_RG_UART_TX_OE BIT(17)
> #define P2C_RG_UART_EN BIT(16)
> #define P2C_FORCE_IDDIG BIT(9)
> #define P2C_RG_VBUSVALID BIT(5)
> @@ -600,6 +609,90 @@ static void u2_phy_instance_exit(struct mtk_tphy *tphy,
> }
> }
>
> +static void u2_phy_instance_set_mode_2uart(struct u2phy_banks *u2_banks)
> +{
> + u32 tmp;
> +
> + /* Clear PA6_RG_U2_BC11_SW_EN */
remove the comments
> + tmp = readl(u2_banks->com + U3P_USBPHYACR6);
> + tmp &= ~(PA6_RG_U2_BC11_SW_EN);
> + writel(tmp, u2_banks->com + U3P_USBPHYACR6);
> +
> + /* Set P2C_RG_SUSPENDM */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp |= P2C_RG_SUSPENDM;
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Set P2C_FORCE_SUSPENDM */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp |= P2C_FORCE_SUSPENDM;
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Clear and Set P2C_RG_UART_MODE to 2'b01 */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp &= ~(P2C_RG_UART_MODE);
> + tmp |= P2C_RG_UART_MODE_VAL(0x1);
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Clear P2C_FORCE_UART_I */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp &= ~(P2C_FORCE_UART_I);
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Set P2C_FORCE_UART_BIAS_EN */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp |= P2C_FORCE_UART_BIAS_EN;
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Set P2C_FORCE_UART_TX_OE */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp |= P2C_FORCE_UART_TX_OE;
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Set P2C_FORCE_UART_EN */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp |= P2C_FORCE_UART_EN;
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Set P2C_RG_UART_BIAS_EN */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp |= P2C_RG_UART_BIAS_EN;
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Set P2C_RG_UART_TX_OE */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp |= P2C_RG_UART_TX_OE;
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Set P2C_RG_UART_EN */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp |= P2C_RG_UART_EN;
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Set P2C_RG_USB20_DM_100K_EN */
> + tmp = readl(u2_banks->com + U3P_U2PHYACR4);
> + tmp |= P2C_RG_USB20_DM_100K_EN;
> + writel(tmp, u2_banks->com + U3P_U2PHYACR4);
> +
> + /* Clear P2C_RG_DMPULLDOWN, P2C_RG_DPPULLDOWN */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp &= ~(P2C_RG_DPPULLDOWN | P2C_RG_DMPULLDOWN);
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +}
> +
> +static int u2_phy_instance_get_mode_ext(struct mtk_tphy *tphy, struct mtk_phy_instance *instance)
> +{
> + struct u2phy_banks *u2_banks = &instance->u2_banks;
> + u32 tmp;
> +
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> +
> + if ((tmp & P2C_RG_UART_MODE) >> P2C_RG_UART_MODE_OFET)
> + return PHY_MODE_UART;
> + else
> + return PHY_MODE_USB_OTG;
> +}
> +
> static void u2_phy_instance_set_mode(struct mtk_tphy *tphy,
> struct mtk_phy_instance *instance,
> enum phy_mode mode)
> @@ -609,6 +702,9 @@ static void u2_phy_instance_set_mode(struct mtk_tphy *tphy,
>
> tmp = readl(u2_banks->com + U3P_U2PHYDTM1);
> switch (mode) {
> + case PHY_MODE_UART:
> + u2_phy_instance_set_mode_2uart(u2_banks);
How do you use this helper?
Can we switch back to usb phy mode if switching to uart?
When switch to uart mode, if the host supports multi-ports, it will
cause the host can't enter sleep mode anymore.
> + return;
> case PHY_MODE_USB_DEVICE:
> tmp |= P2C_FORCE_IDDIG | P2C_RG_IDDIG;
> break;
> @@ -933,6 +1029,10 @@ static int mtk_phy_init(struct phy *phy)
> return ret;
> }
>
> + ret = u2_phy_instance_get_mode_ext(tphy, instance);
> + if (ret == PHY_MODE_UART)
> + return 0;
> +
> switch (instance->type) {
> case PHY_TYPE_USB2:
> u2_phy_instance_init(tphy, instance);
> @@ -996,6 +1096,19 @@ static int mtk_phy_exit(struct phy *phy)
> return 0;
> }
>
> +static int mtk_phy_get_mode_ext(struct phy *phy)
> +{
> + struct mtk_phy_instance *instance = phy_get_drvdata(phy);
> + struct mtk_tphy *tphy = dev_get_drvdata(phy->dev.parent);
> + int ret;
> +
> + ret = 0;
> + if (instance->type == PHY_TYPE_USB2)
> + ret = u2_phy_instance_get_mode_ext(tphy, instance);
> +
> + return ret;
> +}
> +
> static int mtk_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
> {
> struct mtk_phy_instance *instance = phy_get_drvdata(phy);
> @@ -1060,6 +1173,7 @@ static struct phy *mtk_phy_xlate(struct device *dev,
> .power_on = mtk_phy_power_on,
> .power_off = mtk_phy_power_off,
> .set_mode = mtk_phy_set_mode,
> + .get_mode_ext = mtk_phy_get_mode_ext,
> .owner = THIS_MODULE,
> };
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 2/2] phy: mediatek: phy-mtk-tphy: support USB2UART switch
@ 2021-07-28 1:55 ` Chunfeng Yun
0 siblings, 0 replies; 22+ messages in thread
From: Chunfeng Yun @ 2021-07-28 1:55 UTC (permalink / raw)
To: Macpaul Lin
Cc: linux-phy, Kishon Vijay Abraham I, Vinod Koul, Matthias Brugger,
Ainge Hsu, Eddie Hung, Kuohong Wang, Mediatek WSD Upstream,
Macpaul Lin, linux-kernel, linux-arm-kernel, linux-usb,
linux-mediatek
On Tue, 2021-07-27 at 18:50 +0800, Macpaul Lin wrote:
> Some embedded platform shared PINs between USB and UART.
> For example, some phone will use special cable detection in boot loader
> to switch USB port function into UART mode.
>
> This patch support USB2UART switch function in phy-mtk-tphy.
> 1. Implement USB2UART switch API support in phy-mtk-tphy.
> 2. Use PHY_MODE_UART support according to new mode in phy.h.
> 3. Use mtk_phy_get_mode_ext() to query the current MODE from hardware.
>
> Signed-off-by: Macpaul Lin <macpaul.lin@mediatek.com>
> ---
> drivers/phy/mediatek/phy-mtk-tphy.c | 114 +++++++++++++++++++++++++++++++++++
> 1 file changed, 114 insertions(+)
>
title: please use "phy: phy-mtk-tphy: ..." as other patches
> diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
> index cdbcc49..a7dfeec 100644
> --- a/drivers/phy/mediatek/phy-mtk-tphy.c
> +++ b/drivers/phy/mediatek/phy-mtk-tphy.c
> @@ -68,6 +68,7 @@
> #define PA6_RG_U2_SQTH_VAL(x) (0xf & (x))
>
> #define U3P_U2PHYACR4 0x020
> +#define P2C_RG_USB20_DM_100K_EN BIT(17)
> #define P2C_RG_USB20_GPIO_CTL BIT(9)
> #define P2C_USB20_GPIO_MODE BIT(8)
> #define P2C_U2_GPIO_CTR_MSK (P2C_RG_USB20_GPIO_CTL | P2C_USB20_GPIO_MODE)
> @@ -76,6 +77,12 @@
> #define P2C_RG_SIF_U2PLL_FORCE_ON BIT(24)
>
> #define U3P_U2PHYDTM0 0x068
> +#define P2C_RG_UART_MODE GENMASK(31, 30)
> +#define P2C_RG_UART_MODE_VAL(x) ((0x3 & (x)) << 30)
> +#define P2C_RG_UART_MODE_OFET (30)
> +#define P2C_FORCE_UART_I BIT(29)
> +#define P2C_FORCE_UART_BIAS_EN BIT(28)
> +#define P2C_FORCE_UART_TX_OE BIT(27)
> #define P2C_FORCE_UART_EN BIT(26)
> #define P2C_FORCE_DATAIN BIT(23)
> #define P2C_FORCE_DM_PULLDOWN BIT(21)
> @@ -98,6 +105,8 @@
> P2C_RG_DPPULLDOWN | P2C_RG_TERMSEL)
>
> #define U3P_U2PHYDTM1 0x06C
> +#define P2C_RG_UART_BIAS_EN BIT(18)
> +#define P2C_RG_UART_TX_OE BIT(17)
> #define P2C_RG_UART_EN BIT(16)
> #define P2C_FORCE_IDDIG BIT(9)
> #define P2C_RG_VBUSVALID BIT(5)
> @@ -600,6 +609,90 @@ static void u2_phy_instance_exit(struct mtk_tphy *tphy,
> }
> }
>
> +static void u2_phy_instance_set_mode_2uart(struct u2phy_banks *u2_banks)
> +{
> + u32 tmp;
> +
> + /* Clear PA6_RG_U2_BC11_SW_EN */
remove the comments
> + tmp = readl(u2_banks->com + U3P_USBPHYACR6);
> + tmp &= ~(PA6_RG_U2_BC11_SW_EN);
> + writel(tmp, u2_banks->com + U3P_USBPHYACR6);
> +
> + /* Set P2C_RG_SUSPENDM */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp |= P2C_RG_SUSPENDM;
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Set P2C_FORCE_SUSPENDM */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp |= P2C_FORCE_SUSPENDM;
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Clear and Set P2C_RG_UART_MODE to 2'b01 */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp &= ~(P2C_RG_UART_MODE);
> + tmp |= P2C_RG_UART_MODE_VAL(0x1);
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Clear P2C_FORCE_UART_I */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp &= ~(P2C_FORCE_UART_I);
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Set P2C_FORCE_UART_BIAS_EN */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp |= P2C_FORCE_UART_BIAS_EN;
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Set P2C_FORCE_UART_TX_OE */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp |= P2C_FORCE_UART_TX_OE;
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Set P2C_FORCE_UART_EN */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp |= P2C_FORCE_UART_EN;
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Set P2C_RG_UART_BIAS_EN */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp |= P2C_RG_UART_BIAS_EN;
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Set P2C_RG_UART_TX_OE */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp |= P2C_RG_UART_TX_OE;
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Set P2C_RG_UART_EN */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp |= P2C_RG_UART_EN;
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +
> + /* Set P2C_RG_USB20_DM_100K_EN */
> + tmp = readl(u2_banks->com + U3P_U2PHYACR4);
> + tmp |= P2C_RG_USB20_DM_100K_EN;
> + writel(tmp, u2_banks->com + U3P_U2PHYACR4);
> +
> + /* Clear P2C_RG_DMPULLDOWN, P2C_RG_DPPULLDOWN */
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> + tmp &= ~(P2C_RG_DPPULLDOWN | P2C_RG_DMPULLDOWN);
> + writel(tmp, u2_banks->com + U3P_U2PHYDTM0);
> +}
> +
> +static int u2_phy_instance_get_mode_ext(struct mtk_tphy *tphy, struct mtk_phy_instance *instance)
> +{
> + struct u2phy_banks *u2_banks = &instance->u2_banks;
> + u32 tmp;
> +
> + tmp = readl(u2_banks->com + U3P_U2PHYDTM0);
> +
> + if ((tmp & P2C_RG_UART_MODE) >> P2C_RG_UART_MODE_OFET)
> + return PHY_MODE_UART;
> + else
> + return PHY_MODE_USB_OTG;
> +}
> +
> static void u2_phy_instance_set_mode(struct mtk_tphy *tphy,
> struct mtk_phy_instance *instance,
> enum phy_mode mode)
> @@ -609,6 +702,9 @@ static void u2_phy_instance_set_mode(struct mtk_tphy *tphy,
>
> tmp = readl(u2_banks->com + U3P_U2PHYDTM1);
> switch (mode) {
> + case PHY_MODE_UART:
> + u2_phy_instance_set_mode_2uart(u2_banks);
How do you use this helper?
Can we switch back to usb phy mode if switching to uart?
When switch to uart mode, if the host supports multi-ports, it will
cause the host can't enter sleep mode anymore.
> + return;
> case PHY_MODE_USB_DEVICE:
> tmp |= P2C_FORCE_IDDIG | P2C_RG_IDDIG;
> break;
> @@ -933,6 +1029,10 @@ static int mtk_phy_init(struct phy *phy)
> return ret;
> }
>
> + ret = u2_phy_instance_get_mode_ext(tphy, instance);
> + if (ret == PHY_MODE_UART)
> + return 0;
> +
> switch (instance->type) {
> case PHY_TYPE_USB2:
> u2_phy_instance_init(tphy, instance);
> @@ -996,6 +1096,19 @@ static int mtk_phy_exit(struct phy *phy)
> return 0;
> }
>
> +static int mtk_phy_get_mode_ext(struct phy *phy)
> +{
> + struct mtk_phy_instance *instance = phy_get_drvdata(phy);
> + struct mtk_tphy *tphy = dev_get_drvdata(phy->dev.parent);
> + int ret;
> +
> + ret = 0;
> + if (instance->type == PHY_TYPE_USB2)
> + ret = u2_phy_instance_get_mode_ext(tphy, instance);
> +
> + return ret;
> +}
> +
> static int mtk_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
> {
> struct mtk_phy_instance *instance = phy_get_drvdata(phy);
> @@ -1060,6 +1173,7 @@ static struct phy *mtk_phy_xlate(struct device *dev,
> .power_on = mtk_phy_power_on,
> .power_off = mtk_phy_power_off,
> .set_mode = mtk_phy_set_mode,
> + .get_mode_ext = mtk_phy_get_mode_ext,
> .owner = THIS_MODULE,
> };
>
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 1/2] phy: introduce phy mode PHY_MODE_UART and phy_get_mode_ext()
2021-07-27 10:50 ` Macpaul Lin
@ 2021-07-27 13:33 ` kernel test robot
-1 siblings, 0 replies; 22+ messages in thread
From: kernel test robot @ 2021-07-27 13:33 UTC (permalink / raw)
To: Macpaul Lin, linux-phy, Chunfeng Yun, Kishon Vijay Abraham I,
Vinod Koul, Matthias Brugger
Cc: kbuild-all, Ainge Hsu, Eddie Hung, Kuohong Wang,
Mediatek WSD Upstream, Macpaul Lin
[-- Attachment #1: Type: text/plain, Size: 2393 bytes --]
Hi Macpaul,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on linus/master]
[also build test WARNING on v5.14-rc3 next-20210726]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Macpaul-Lin/phy-introduce-phy-mode-PHY_MODE_UART-and-phy_get_mode_ext/20210727-185332
base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git ff1176468d368232b684f75e82563369208bc371
config: mips-randconfig-s031-20210727 (attached as .config)
compiler: mips-linux-gcc (GCC) 10.3.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# apt-get install sparse
# sparse version: v0.6.3-341-g8af24329-dirty
# https://github.com/0day-ci/linux/commit/fa58db3bf0689ed034e7871c053bfd65592b486e
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Macpaul-Lin/phy-introduce-phy-mode-PHY_MODE_UART-and-phy_get_mode_ext/20210727-185332
git checkout fa58db3bf0689ed034e7871c053bfd65592b486e
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-10.3.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=mips
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All warnings (new ones prefixed by >>):
>> drivers/phy/phy-core.c:376:5: warning: no previous prototype for 'phy_get_mode_ext' [-Wmissing-prototypes]
376 | int phy_get_mode_ext(struct phy *phy)
| ^~~~~~~~~~~~~~~~
vim +/phy_get_mode_ext +376 drivers/phy/phy-core.c
375
> 376 int phy_get_mode_ext(struct phy *phy)
377 {
378 int ret;
379
380 if (!phy || !phy->ops->get_mode_ext)
381 return 0;
382
383 mutex_lock(&phy->mutex);
384 ret = phy->ops->get_mode_ext(phy);
385 if (!ret)
386 ret = phy->attrs.mode;
387 mutex_unlock(&phy->mutex);
388
389 return ret;
390 }
391 EXPORT_SYMBOL_GPL(phy_get_mode_ext);
392
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 30531 bytes --]
[-- Attachment #3: Type: text/plain, Size: 112 bytes --]
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 1/2] phy: introduce phy mode PHY_MODE_UART and phy_get_mode_ext()
2021-07-27 10:50 ` Macpaul Lin
@ 2021-07-27 15:48 ` kernel test robot
-1 siblings, 0 replies; 22+ messages in thread
From: kernel test robot @ 2021-07-27 15:48 UTC (permalink / raw)
To: Macpaul Lin, linux-phy, Chunfeng Yun, Kishon Vijay Abraham I,
Vinod Koul, Matthias Brugger
Cc: clang-built-linux, kbuild-all, Ainge Hsu, Eddie Hung,
Kuohong Wang, Mediatek WSD Upstream, Macpaul Lin
[-- Attachment #1: Type: text/plain, Size: 2658 bytes --]
Hi Macpaul,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on linus/master]
[also build test WARNING on v5.14-rc3 next-20210726]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Macpaul-Lin/phy-introduce-phy-mode-PHY_MODE_UART-and-phy_get_mode_ext/20210727-185332
base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git ff1176468d368232b684f75e82563369208bc371
config: x86_64-randconfig-c001-20210727 (attached as .config)
compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project c658b472f3e61e1818e1909bf02f3d65470018a5)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install x86_64 cross compiling tool for clang build
# apt-get install binutils-x86-64-linux-gnu
# https://github.com/0day-ci/linux/commit/fa58db3bf0689ed034e7871c053bfd65592b486e
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Macpaul-Lin/phy-introduce-phy-mode-PHY_MODE_UART-and-phy_get_mode_ext/20210727-185332
git checkout fa58db3bf0689ed034e7871c053bfd65592b486e
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All warnings (new ones prefixed by >>):
>> drivers/phy/phy-core.c:376:5: warning: no previous prototype for function 'phy_get_mode_ext' [-Wmissing-prototypes]
int phy_get_mode_ext(struct phy *phy)
^
drivers/phy/phy-core.c:376:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
int phy_get_mode_ext(struct phy *phy)
^
static
1 warning generated.
vim +/phy_get_mode_ext +376 drivers/phy/phy-core.c
375
> 376 int phy_get_mode_ext(struct phy *phy)
377 {
378 int ret;
379
380 if (!phy || !phy->ops->get_mode_ext)
381 return 0;
382
383 mutex_lock(&phy->mutex);
384 ret = phy->ops->get_mode_ext(phy);
385 if (!ret)
386 ret = phy->attrs.mode;
387 mutex_unlock(&phy->mutex);
388
389 return ret;
390 }
391 EXPORT_SYMBOL_GPL(phy_get_mode_ext);
392
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 34138 bytes --]
[-- Attachment #3: Type: text/plain, Size: 112 bytes --]
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 1/2] phy: introduce phy mode PHY_MODE_UART and phy_get_mode_ext()
2021-07-27 10:50 ` Macpaul Lin
@ 2021-07-27 15:48 ` kernel test robot
-1 siblings, 0 replies; 22+ messages in thread
From: kernel test robot @ 2021-07-27 15:48 UTC (permalink / raw)
To: Macpaul Lin, linux-phy, Chunfeng Yun, Kishon Vijay Abraham I,
Vinod Koul, Matthias Brugger
Cc: clang-built-linux, kbuild-all, Ainge Hsu, Eddie Hung,
Kuohong Wang, Mediatek WSD Upstream, Macpaul Lin
[-- Attachment #1: Type: text/plain, Size: 2658 bytes --]
Hi Macpaul,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on linus/master]
[also build test WARNING on v5.14-rc3 next-20210726]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Macpaul-Lin/phy-introduce-phy-mode-PHY_MODE_UART-and-phy_get_mode_ext/20210727-185332
base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git ff1176468d368232b684f75e82563369208bc371
config: x86_64-randconfig-a003-20210727 (attached as .config)
compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project c658b472f3e61e1818e1909bf02f3d65470018a5)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install x86_64 cross compiling tool for clang build
# apt-get install binutils-x86-64-linux-gnu
# https://github.com/0day-ci/linux/commit/fa58db3bf0689ed034e7871c053bfd65592b486e
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Macpaul-Lin/phy-introduce-phy-mode-PHY_MODE_UART-and-phy_get_mode_ext/20210727-185332
git checkout fa58db3bf0689ed034e7871c053bfd65592b486e
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All warnings (new ones prefixed by >>):
>> drivers/phy/phy-core.c:376:5: warning: no previous prototype for function 'phy_get_mode_ext' [-Wmissing-prototypes]
int phy_get_mode_ext(struct phy *phy)
^
drivers/phy/phy-core.c:376:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
int phy_get_mode_ext(struct phy *phy)
^
static
1 warning generated.
vim +/phy_get_mode_ext +376 drivers/phy/phy-core.c
375
> 376 int phy_get_mode_ext(struct phy *phy)
377 {
378 int ret;
379
380 if (!phy || !phy->ops->get_mode_ext)
381 return 0;
382
383 mutex_lock(&phy->mutex);
384 ret = phy->ops->get_mode_ext(phy);
385 if (!ret)
386 ret = phy->attrs.mode;
387 mutex_unlock(&phy->mutex);
388
389 return ret;
390 }
391 EXPORT_SYMBOL_GPL(phy_get_mode_ext);
392
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 36132 bytes --]
[-- Attachment #3: Type: text/plain, Size: 112 bytes --]
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 1/2] phy: introduce phy mode PHY_MODE_UART and phy_get_mode_ext()
2021-07-27 10:50 ` Macpaul Lin
(?)
(?)
@ 2021-07-28 1:35 ` Chunfeng Yun
-1 siblings, 0 replies; 22+ messages in thread
From: Chunfeng Yun @ 2021-07-28 1:35 UTC (permalink / raw)
To: Macpaul Lin
Cc: linux-phy, Kishon Vijay Abraham I, Vinod Koul, Matthias Brugger,
Ainge Hsu, Eddie Hung, Kuohong Wang, Mediatek WSD Upstream,
Macpaul Lin, linux-kernel, linux-arm-kernel, linux-usb,
linux-mediatek
On Tue, 2021-07-27 at 18:50 +0800, Macpaul Lin wrote:
> Some embedded platform shared PINs between USB and UART.
>
> For example, some phone will use special cable detection in boot loader
> to switch USB port function into UART mode. Hence Kernel need to query
> the hardware state from PHY registers to confirm the initialzation flow
> for PHY and USB driver.
>
> To support this kind of PIN switch, new PHY MODE and query API is
> required. Here we introduce a new PHY mode: PHY_MODE_UART.
>
> API phy_get_mode_ext() can be used to query the MODE from hardware
> instead of reading it from phy attributes.
>
> Signed-off-by: Macpaul Lin <macpaul.lin@mediatek.com>
> ---
> drivers/phy/phy-core.c | 17 +++++++++++++++++
> include/linux/phy/phy.h | 3 +++
> 2 files changed, 20 insertions(+)
>
> diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
> index ccb575b..b8f6539 100644
> --- a/drivers/phy/phy-core.c
> +++ b/drivers/phy/phy-core.c
> @@ -373,6 +373,23 @@ int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode)
> }
> EXPORT_SYMBOL_GPL(phy_set_mode_ext);
>
> +int phy_get_mode_ext(struct phy *phy)
> +{
> + int ret;
> +
> + if (!phy || !phy->ops->get_mode_ext)
> + return 0;
> +
> + mutex_lock(&phy->mutex);
> + ret = phy->ops->get_mode_ext(phy);
> + if (!ret)
> + ret = phy->attrs.mode;
> + mutex_unlock(&phy->mutex);
> +
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(phy_get_mode_ext);
> +
> int phy_set_media(struct phy *phy, enum phy_media media)
> {
> int ret;
> diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
> index 0ed434d..7d32c6b 100644
> --- a/include/linux/phy/phy.h
> +++ b/include/linux/phy/phy.h
> @@ -34,6 +34,7 @@ enum phy_mode {
> PHY_MODE_USB_DEVICE_HS,
> PHY_MODE_USB_DEVICE_SS,
> PHY_MODE_USB_OTG,
> + PHY_MODE_UART,
> PHY_MODE_UFS_HS_A,
> PHY_MODE_UFS_HS_B,
> PHY_MODE_PCIE,
> @@ -70,6 +71,7 @@ enum phy_media {
> * @power_on: powering on the phy
> * @power_off: powering off the phy
> * @set_mode: set the mode of the phy
> + * @get_mode_ext: get the extented mode of the phy
> * @set_media: set the media type of the phy (optional)
> * @set_speed: set the speed of the phy (optional)
> * @reset: resetting the phy
> @@ -83,6 +85,7 @@ struct phy_ops {
> int (*power_on)(struct phy *phy);
> int (*power_off)(struct phy *phy);
> int (*set_mode)(struct phy *phy, enum phy_mode mode, int submode);
> + int (*get_mode_ext)(struct phy *phy);
> int (*set_media)(struct phy *phy, enum phy_media media);
> int (*set_speed)(struct phy *phy, int speed);
>
add prototype of phy_get_mode_ext(struct phy *phy) for both cases that
CONFIG_GENERIC_PHY is enabled or not in linux/phy/phy.h
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 1/2] phy: introduce phy mode PHY_MODE_UART and phy_get_mode_ext()
@ 2021-07-28 1:35 ` Chunfeng Yun
0 siblings, 0 replies; 22+ messages in thread
From: Chunfeng Yun @ 2021-07-28 1:35 UTC (permalink / raw)
To: Macpaul Lin
Cc: linux-phy, Kishon Vijay Abraham I, Vinod Koul, Matthias Brugger,
Ainge Hsu, Eddie Hung, Kuohong Wang, Mediatek WSD Upstream,
Macpaul Lin, linux-kernel, linux-arm-kernel, linux-usb,
linux-mediatek
On Tue, 2021-07-27 at 18:50 +0800, Macpaul Lin wrote:
> Some embedded platform shared PINs between USB and UART.
>
> For example, some phone will use special cable detection in boot loader
> to switch USB port function into UART mode. Hence Kernel need to query
> the hardware state from PHY registers to confirm the initialzation flow
> for PHY and USB driver.
>
> To support this kind of PIN switch, new PHY MODE and query API is
> required. Here we introduce a new PHY mode: PHY_MODE_UART.
>
> API phy_get_mode_ext() can be used to query the MODE from hardware
> instead of reading it from phy attributes.
>
> Signed-off-by: Macpaul Lin <macpaul.lin@mediatek.com>
> ---
> drivers/phy/phy-core.c | 17 +++++++++++++++++
> include/linux/phy/phy.h | 3 +++
> 2 files changed, 20 insertions(+)
>
> diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
> index ccb575b..b8f6539 100644
> --- a/drivers/phy/phy-core.c
> +++ b/drivers/phy/phy-core.c
> @@ -373,6 +373,23 @@ int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode)
> }
> EXPORT_SYMBOL_GPL(phy_set_mode_ext);
>
> +int phy_get_mode_ext(struct phy *phy)
> +{
> + int ret;
> +
> + if (!phy || !phy->ops->get_mode_ext)
> + return 0;
> +
> + mutex_lock(&phy->mutex);
> + ret = phy->ops->get_mode_ext(phy);
> + if (!ret)
> + ret = phy->attrs.mode;
> + mutex_unlock(&phy->mutex);
> +
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(phy_get_mode_ext);
> +
> int phy_set_media(struct phy *phy, enum phy_media media)
> {
> int ret;
> diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
> index 0ed434d..7d32c6b 100644
> --- a/include/linux/phy/phy.h
> +++ b/include/linux/phy/phy.h
> @@ -34,6 +34,7 @@ enum phy_mode {
> PHY_MODE_USB_DEVICE_HS,
> PHY_MODE_USB_DEVICE_SS,
> PHY_MODE_USB_OTG,
> + PHY_MODE_UART,
> PHY_MODE_UFS_HS_A,
> PHY_MODE_UFS_HS_B,
> PHY_MODE_PCIE,
> @@ -70,6 +71,7 @@ enum phy_media {
> * @power_on: powering on the phy
> * @power_off: powering off the phy
> * @set_mode: set the mode of the phy
> + * @get_mode_ext: get the extented mode of the phy
> * @set_media: set the media type of the phy (optional)
> * @set_speed: set the speed of the phy (optional)
> * @reset: resetting the phy
> @@ -83,6 +85,7 @@ struct phy_ops {
> int (*power_on)(struct phy *phy);
> int (*power_off)(struct phy *phy);
> int (*set_mode)(struct phy *phy, enum phy_mode mode, int submode);
> + int (*get_mode_ext)(struct phy *phy);
> int (*set_media)(struct phy *phy, enum phy_media media);
> int (*set_speed)(struct phy *phy, int speed);
>
add prototype of phy_get_mode_ext(struct phy *phy) for both cases that
CONFIG_GENERIC_PHY is enabled or not in linux/phy/phy.h
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 1/2] phy: introduce phy mode PHY_MODE_UART and phy_get_mode_ext()
@ 2021-07-28 1:35 ` Chunfeng Yun
0 siblings, 0 replies; 22+ messages in thread
From: Chunfeng Yun @ 2021-07-28 1:35 UTC (permalink / raw)
To: Macpaul Lin
Cc: linux-phy, Kishon Vijay Abraham I, Vinod Koul, Matthias Brugger,
Ainge Hsu, Eddie Hung, Kuohong Wang, Mediatek WSD Upstream,
Macpaul Lin, linux-kernel, linux-arm-kernel, linux-usb,
linux-mediatek
On Tue, 2021-07-27 at 18:50 +0800, Macpaul Lin wrote:
> Some embedded platform shared PINs between USB and UART.
>
> For example, some phone will use special cable detection in boot loader
> to switch USB port function into UART mode. Hence Kernel need to query
> the hardware state from PHY registers to confirm the initialzation flow
> for PHY and USB driver.
>
> To support this kind of PIN switch, new PHY MODE and query API is
> required. Here we introduce a new PHY mode: PHY_MODE_UART.
>
> API phy_get_mode_ext() can be used to query the MODE from hardware
> instead of reading it from phy attributes.
>
> Signed-off-by: Macpaul Lin <macpaul.lin@mediatek.com>
> ---
> drivers/phy/phy-core.c | 17 +++++++++++++++++
> include/linux/phy/phy.h | 3 +++
> 2 files changed, 20 insertions(+)
>
> diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
> index ccb575b..b8f6539 100644
> --- a/drivers/phy/phy-core.c
> +++ b/drivers/phy/phy-core.c
> @@ -373,6 +373,23 @@ int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode)
> }
> EXPORT_SYMBOL_GPL(phy_set_mode_ext);
>
> +int phy_get_mode_ext(struct phy *phy)
> +{
> + int ret;
> +
> + if (!phy || !phy->ops->get_mode_ext)
> + return 0;
> +
> + mutex_lock(&phy->mutex);
> + ret = phy->ops->get_mode_ext(phy);
> + if (!ret)
> + ret = phy->attrs.mode;
> + mutex_unlock(&phy->mutex);
> +
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(phy_get_mode_ext);
> +
> int phy_set_media(struct phy *phy, enum phy_media media)
> {
> int ret;
> diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
> index 0ed434d..7d32c6b 100644
> --- a/include/linux/phy/phy.h
> +++ b/include/linux/phy/phy.h
> @@ -34,6 +34,7 @@ enum phy_mode {
> PHY_MODE_USB_DEVICE_HS,
> PHY_MODE_USB_DEVICE_SS,
> PHY_MODE_USB_OTG,
> + PHY_MODE_UART,
> PHY_MODE_UFS_HS_A,
> PHY_MODE_UFS_HS_B,
> PHY_MODE_PCIE,
> @@ -70,6 +71,7 @@ enum phy_media {
> * @power_on: powering on the phy
> * @power_off: powering off the phy
> * @set_mode: set the mode of the phy
> + * @get_mode_ext: get the extented mode of the phy
> * @set_media: set the media type of the phy (optional)
> * @set_speed: set the speed of the phy (optional)
> * @reset: resetting the phy
> @@ -83,6 +85,7 @@ struct phy_ops {
> int (*power_on)(struct phy *phy);
> int (*power_off)(struct phy *phy);
> int (*set_mode)(struct phy *phy, enum phy_mode mode, int submode);
> + int (*get_mode_ext)(struct phy *phy);
> int (*set_media)(struct phy *phy, enum phy_media media);
> int (*set_speed)(struct phy *phy, int speed);
>
add prototype of phy_get_mode_ext(struct phy *phy) for both cases that
CONFIG_GENERIC_PHY is enabled or not in linux/phy/phy.h
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 1/2] phy: introduce phy mode PHY_MODE_UART and phy_get_mode_ext()
@ 2021-07-28 1:35 ` Chunfeng Yun
0 siblings, 0 replies; 22+ messages in thread
From: Chunfeng Yun @ 2021-07-28 1:35 UTC (permalink / raw)
To: Macpaul Lin
Cc: linux-phy, Kishon Vijay Abraham I, Vinod Koul, Matthias Brugger,
Ainge Hsu, Eddie Hung, Kuohong Wang, Mediatek WSD Upstream,
Macpaul Lin, linux-kernel, linux-arm-kernel, linux-usb,
linux-mediatek
On Tue, 2021-07-27 at 18:50 +0800, Macpaul Lin wrote:
> Some embedded platform shared PINs between USB and UART.
>
> For example, some phone will use special cable detection in boot loader
> to switch USB port function into UART mode. Hence Kernel need to query
> the hardware state from PHY registers to confirm the initialzation flow
> for PHY and USB driver.
>
> To support this kind of PIN switch, new PHY MODE and query API is
> required. Here we introduce a new PHY mode: PHY_MODE_UART.
>
> API phy_get_mode_ext() can be used to query the MODE from hardware
> instead of reading it from phy attributes.
>
> Signed-off-by: Macpaul Lin <macpaul.lin@mediatek.com>
> ---
> drivers/phy/phy-core.c | 17 +++++++++++++++++
> include/linux/phy/phy.h | 3 +++
> 2 files changed, 20 insertions(+)
>
> diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
> index ccb575b..b8f6539 100644
> --- a/drivers/phy/phy-core.c
> +++ b/drivers/phy/phy-core.c
> @@ -373,6 +373,23 @@ int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode)
> }
> EXPORT_SYMBOL_GPL(phy_set_mode_ext);
>
> +int phy_get_mode_ext(struct phy *phy)
> +{
> + int ret;
> +
> + if (!phy || !phy->ops->get_mode_ext)
> + return 0;
> +
> + mutex_lock(&phy->mutex);
> + ret = phy->ops->get_mode_ext(phy);
> + if (!ret)
> + ret = phy->attrs.mode;
> + mutex_unlock(&phy->mutex);
> +
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(phy_get_mode_ext);
> +
> int phy_set_media(struct phy *phy, enum phy_media media)
> {
> int ret;
> diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
> index 0ed434d..7d32c6b 100644
> --- a/include/linux/phy/phy.h
> +++ b/include/linux/phy/phy.h
> @@ -34,6 +34,7 @@ enum phy_mode {
> PHY_MODE_USB_DEVICE_HS,
> PHY_MODE_USB_DEVICE_SS,
> PHY_MODE_USB_OTG,
> + PHY_MODE_UART,
> PHY_MODE_UFS_HS_A,
> PHY_MODE_UFS_HS_B,
> PHY_MODE_PCIE,
> @@ -70,6 +71,7 @@ enum phy_media {
> * @power_on: powering on the phy
> * @power_off: powering off the phy
> * @set_mode: set the mode of the phy
> + * @get_mode_ext: get the extented mode of the phy
> * @set_media: set the media type of the phy (optional)
> * @set_speed: set the speed of the phy (optional)
> * @reset: resetting the phy
> @@ -83,6 +85,7 @@ struct phy_ops {
> int (*power_on)(struct phy *phy);
> int (*power_off)(struct phy *phy);
> int (*set_mode)(struct phy *phy, enum phy_mode mode, int submode);
> + int (*get_mode_ext)(struct phy *phy);
> int (*set_media)(struct phy *phy, enum phy_media media);
> int (*set_speed)(struct phy *phy, int speed);
>
add prototype of phy_get_mode_ext(struct phy *phy) for both cases that
CONFIG_GENERIC_PHY is enabled or not in linux/phy/phy.h
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply [flat|nested] 22+ messages in thread