forked from Minki/linux
usb: phy: omap: Add new device types and remove omap_control_usb3_phy_power()
Add support for new device types and in the process rid of "ti,type" device tree property. The correct type of device will be determined from the compatible string instead. Introduce a compatible string for each device type. At the moment we support 4 types OTGHS, USB2, PIPE3 (e.g. USB3) and DRA7USB2. Update DT binding information to reflect these changes. Also get rid of omap_control_usb3_phy_power(). Just one function i.e. omap_control_usb_phy_power() will now take care of all PHY types. Signed-off-by: Roger Quadros <rogerq@ti.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
4fd06af96b
commit
6cb9310a32
@ -83,22 +83,22 @@ omap_dwc3 {
|
||||
OMAP CONTROL USB
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "ti,omap-control-usb"
|
||||
- compatible: Should be one of
|
||||
"ti,control-phy-otghs" - if it has otghs_control mailbox register as on OMAP4.
|
||||
"ti,control-phy-usb2" - if it has Power down bit in control_dev_conf register
|
||||
e.g. USB2_PHY on OMAP5.
|
||||
"ti,control-phy-pipe3" - if it has DPLL and individual Rx & Tx power control
|
||||
e.g. USB3 PHY and SATA PHY on OMAP5.
|
||||
"ti,control-phy-dra7usb2" - if it has power down register like USB2 PHY on
|
||||
DRA7 platform.
|
||||
- reg : Address and length of the register set for the device. It contains
|
||||
the address of "control_dev_conf" and "otghs_control" or "phy_power_usb"
|
||||
depending upon omap4 or omap5.
|
||||
- reg-names: The names of the register addresses corresponding to the registers
|
||||
filled in "reg".
|
||||
- ti,type: This is used to differentiate whether the control module has
|
||||
usb mailbox or usb3 phy power. omap4 has usb mailbox in control module to
|
||||
notify events to the musb core and omap5 has usb3 phy power register to
|
||||
power on usb3 phy. Should be "1" if it has mailbox and "2" if it has usb3
|
||||
phy power.
|
||||
the address of "otghs_control" for control-phy-otghs or "power" register
|
||||
for other types.
|
||||
- reg-names: should be "otghs_control" control-phy-otghs and "power" for
|
||||
other types.
|
||||
|
||||
omap_control_usb: omap-control-usb@4a002300 {
|
||||
compatible = "ti,omap-control-usb";
|
||||
reg = <0x4a002300 0x4>,
|
||||
<0x4a00233c 0x4>;
|
||||
reg-names = "control_dev_conf", "otghs_control";
|
||||
ti,type = <1>;
|
||||
compatible = "ti,control-phy-otghs";
|
||||
reg = <0x4a00233c 0x4>;
|
||||
reg-names = "otghs_control";
|
||||
};
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/clk.h>
|
||||
@ -45,44 +46,6 @@ struct device *omap_get_control_dev(void)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(omap_get_control_dev);
|
||||
|
||||
/**
|
||||
* omap_control_usb3_phy_power - power on/off the serializer using control
|
||||
* module
|
||||
* @dev: the control module device
|
||||
* @on: 0 to off and 1 to on based on powering on or off the PHY
|
||||
*
|
||||
* usb3 PHY driver should call this API to power on or off the PHY.
|
||||
*/
|
||||
void omap_control_usb3_phy_power(struct device *dev, bool on)
|
||||
{
|
||||
u32 val;
|
||||
unsigned long rate;
|
||||
struct omap_control_usb *control_usb = dev_get_drvdata(dev);
|
||||
|
||||
if (control_usb->type != OMAP_CTRL_DEV_TYPE2)
|
||||
return;
|
||||
|
||||
rate = clk_get_rate(control_usb->sys_clk);
|
||||
rate = rate/1000000;
|
||||
|
||||
val = readl(control_usb->phy_power);
|
||||
|
||||
if (on) {
|
||||
val &= ~(OMAP_CTRL_USB_PWRCTL_CLK_CMD_MASK |
|
||||
OMAP_CTRL_USB_PWRCTL_CLK_FREQ_MASK);
|
||||
val |= OMAP_CTRL_USB3_PHY_TX_RX_POWERON <<
|
||||
OMAP_CTRL_USB_PWRCTL_CLK_CMD_SHIFT;
|
||||
val |= rate << OMAP_CTRL_USB_PWRCTL_CLK_FREQ_SHIFT;
|
||||
} else {
|
||||
val &= ~OMAP_CTRL_USB_PWRCTL_CLK_CMD_MASK;
|
||||
val |= OMAP_CTRL_USB3_PHY_TX_RX_POWEROFF <<
|
||||
OMAP_CTRL_USB_PWRCTL_CLK_CMD_SHIFT;
|
||||
}
|
||||
|
||||
writel(val, control_usb->phy_power);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(omap_control_usb3_phy_power);
|
||||
|
||||
/**
|
||||
* omap_control_usb_phy_power - power on/off the phy using control module reg
|
||||
* @dev: the control module device
|
||||
@ -91,16 +54,63 @@ EXPORT_SYMBOL_GPL(omap_control_usb3_phy_power);
|
||||
void omap_control_usb_phy_power(struct device *dev, int on)
|
||||
{
|
||||
u32 val;
|
||||
struct omap_control_usb *control_usb = dev_get_drvdata(dev);
|
||||
unsigned long rate;
|
||||
struct omap_control_usb *control_usb;
|
||||
|
||||
val = readl(control_usb->dev_conf);
|
||||
if (IS_ERR(dev) || !dev) {
|
||||
pr_err("%s: invalid device\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (on)
|
||||
val &= ~OMAP_CTRL_DEV_PHY_PD;
|
||||
else
|
||||
val |= OMAP_CTRL_DEV_PHY_PD;
|
||||
control_usb = dev_get_drvdata(dev);
|
||||
if (!control_usb) {
|
||||
dev_err(dev, "%s: invalid control usb device\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
writel(val, control_usb->dev_conf);
|
||||
if (control_usb->type == OMAP_CTRL_TYPE_OTGHS)
|
||||
return;
|
||||
|
||||
val = readl(control_usb->power);
|
||||
|
||||
switch (control_usb->type) {
|
||||
case OMAP_CTRL_TYPE_USB2:
|
||||
if (on)
|
||||
val &= ~OMAP_CTRL_DEV_PHY_PD;
|
||||
else
|
||||
val |= OMAP_CTRL_DEV_PHY_PD;
|
||||
break;
|
||||
|
||||
case OMAP_CTRL_TYPE_PIPE3:
|
||||
rate = clk_get_rate(control_usb->sys_clk);
|
||||
rate = rate/1000000;
|
||||
|
||||
if (on) {
|
||||
val &= ~(OMAP_CTRL_USB_PWRCTL_CLK_CMD_MASK |
|
||||
OMAP_CTRL_USB_PWRCTL_CLK_FREQ_MASK);
|
||||
val |= OMAP_CTRL_USB3_PHY_TX_RX_POWERON <<
|
||||
OMAP_CTRL_USB_PWRCTL_CLK_CMD_SHIFT;
|
||||
val |= rate << OMAP_CTRL_USB_PWRCTL_CLK_FREQ_SHIFT;
|
||||
} else {
|
||||
val &= ~OMAP_CTRL_USB_PWRCTL_CLK_CMD_MASK;
|
||||
val |= OMAP_CTRL_USB3_PHY_TX_RX_POWEROFF <<
|
||||
OMAP_CTRL_USB_PWRCTL_CLK_CMD_SHIFT;
|
||||
}
|
||||
break;
|
||||
|
||||
case OMAP_CTRL_TYPE_DRA7USB2:
|
||||
if (on)
|
||||
val &= ~OMAP_CTRL_USB2_PHY_PD;
|
||||
else
|
||||
val |= OMAP_CTRL_USB2_PHY_PD;
|
||||
break;
|
||||
default:
|
||||
dev_err(dev, "%s: type %d not recognized\n",
|
||||
__func__, control_usb->type);
|
||||
break;
|
||||
}
|
||||
|
||||
writel(val, control_usb->power);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(omap_control_usb_phy_power);
|
||||
|
||||
@ -172,7 +182,7 @@ void omap_control_usb_set_mode(struct device *dev,
|
||||
{
|
||||
struct omap_control_usb *ctrl_usb;
|
||||
|
||||
if (IS_ERR(dev) || control_usb->type != OMAP_CTRL_DEV_TYPE1)
|
||||
if (IS_ERR(dev) || control_usb->type != OMAP_CTRL_TYPE_OTGHS)
|
||||
return;
|
||||
|
||||
ctrl_usb = dev_get_drvdata(dev);
|
||||
@ -193,10 +203,45 @@ void omap_control_usb_set_mode(struct device *dev,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(omap_control_usb_set_mode);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
|
||||
static const enum omap_control_usb_type otghs_data = OMAP_CTRL_TYPE_OTGHS;
|
||||
static const enum omap_control_usb_type usb2_data = OMAP_CTRL_TYPE_USB2;
|
||||
static const enum omap_control_usb_type pipe3_data = OMAP_CTRL_TYPE_PIPE3;
|
||||
static const enum omap_control_usb_type dra7usb2_data = OMAP_CTRL_TYPE_DRA7USB2;
|
||||
|
||||
static const struct of_device_id omap_control_usb_id_table[] = {
|
||||
{
|
||||
.compatible = "ti,control-phy-otghs",
|
||||
.data = &otghs_data,
|
||||
},
|
||||
{
|
||||
.compatible = "ti,control-phy-usb2",
|
||||
.data = &usb2_data,
|
||||
},
|
||||
{
|
||||
.compatible = "ti,control-phy-pipe3",
|
||||
.data = &pipe3_data,
|
||||
},
|
||||
{
|
||||
.compatible = "ti,control-phy-dra7usb2",
|
||||
.data = &dra7usb2_data,
|
||||
},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, omap_control_usb_id_table);
|
||||
#endif
|
||||
|
||||
|
||||
static int omap_control_usb_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res;
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
const struct of_device_id *of_id;
|
||||
|
||||
of_id = of_match_device(of_match_ptr(omap_control_usb_id_table),
|
||||
&pdev->dev);
|
||||
if (!of_id)
|
||||
return -EINVAL;
|
||||
|
||||
control_usb = devm_kzalloc(&pdev->dev, sizeof(*control_usb),
|
||||
GFP_KERNEL);
|
||||
@ -205,36 +250,27 @@ static int omap_control_usb_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (np)
|
||||
of_property_read_u32(np, "ti,type", &control_usb->type);
|
||||
else
|
||||
return -EINVAL; /* We only support DT boot */
|
||||
control_usb->dev = &pdev->dev;
|
||||
control_usb->type = *(enum omap_control_usb_type *)of_id->data;
|
||||
|
||||
control_usb->dev = &pdev->dev;
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
||||
"control_dev_conf");
|
||||
control_usb->dev_conf = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(control_usb->dev_conf))
|
||||
return PTR_ERR(control_usb->dev_conf);
|
||||
|
||||
if (control_usb->type == OMAP_CTRL_DEV_TYPE1) {
|
||||
if (control_usb->type == OMAP_CTRL_TYPE_OTGHS) {
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
||||
"otghs_control");
|
||||
control_usb->otghs_control = devm_ioremap_resource(
|
||||
&pdev->dev, res);
|
||||
if (IS_ERR(control_usb->otghs_control))
|
||||
return PTR_ERR(control_usb->otghs_control);
|
||||
} else {
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
||||
"power");
|
||||
control_usb->power = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(control_usb->power)) {
|
||||
dev_err(&pdev->dev, "Couldn't get power register\n");
|
||||
return PTR_ERR(control_usb->power);
|
||||
}
|
||||
}
|
||||
|
||||
if (control_usb->type == OMAP_CTRL_DEV_TYPE2) {
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
||||
"phy_power_usb");
|
||||
control_usb->phy_power = devm_ioremap_resource(
|
||||
&pdev->dev, res);
|
||||
if (IS_ERR(control_usb->phy_power))
|
||||
return PTR_ERR(control_usb->phy_power);
|
||||
|
||||
if (control_usb->type == OMAP_CTRL_TYPE_PIPE3) {
|
||||
control_usb->sys_clk = devm_clk_get(control_usb->dev,
|
||||
"sys_clkin");
|
||||
if (IS_ERR(control_usb->sys_clk)) {
|
||||
@ -243,20 +279,11 @@ static int omap_control_usb_probe(struct platform_device *pdev)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
dev_set_drvdata(control_usb->dev, control_usb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id omap_control_usb_id_table[] = {
|
||||
{ .compatible = "ti,omap-control-usb" },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, omap_control_usb_id_table);
|
||||
#endif
|
||||
|
||||
static struct platform_driver omap_control_usb_driver = {
|
||||
.probe = omap_control_usb_probe,
|
||||
.driver = {
|
||||
|
@ -100,7 +100,7 @@ static int omap_usb3_suspend(struct usb_phy *x, int suspend)
|
||||
udelay(1);
|
||||
} while (--timeout);
|
||||
|
||||
omap_control_usb3_phy_power(phy->control_dev, 0);
|
||||
omap_control_usb_phy_power(phy->control_dev, 0);
|
||||
|
||||
phy->is_suspended = 1;
|
||||
} else if (!suspend && phy->is_suspended) {
|
||||
@ -189,7 +189,7 @@ static int omap_usb3_init(struct usb_phy *x)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
omap_control_usb3_phy_power(phy->control_dev, 1);
|
||||
omap_control_usb_phy_power(phy->control_dev, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -245,7 +245,7 @@ static int omap_usb3_probe(struct platform_device *pdev)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
omap_control_usb3_phy_power(phy->control_dev, 0);
|
||||
omap_control_usb_phy_power(phy->control_dev, 0);
|
||||
usb_add_phy_dev(&phy->phy);
|
||||
|
||||
platform_set_drvdata(pdev, phy);
|
||||
|
@ -19,16 +19,23 @@
|
||||
#ifndef __OMAP_CONTROL_USB_H__
|
||||
#define __OMAP_CONTROL_USB_H__
|
||||
|
||||
enum omap_control_usb_type {
|
||||
OMAP_CTRL_TYPE_OTGHS = 1, /* Mailbox OTGHS_CONTROL */
|
||||
OMAP_CTRL_TYPE_USB2, /* USB2_PHY, power down in CONTROL_DEV_CONF */
|
||||
OMAP_CTRL_TYPE_PIPE3, /* PIPE3 PHY, DPLL & seperate Rx/Tx power */
|
||||
OMAP_CTRL_TYPE_DRA7USB2, /* USB2 PHY, power and power_aux e.g. DRA7 */
|
||||
};
|
||||
|
||||
struct omap_control_usb {
|
||||
struct device *dev;
|
||||
|
||||
u32 __iomem *dev_conf;
|
||||
u32 __iomem *otghs_control;
|
||||
u32 __iomem *phy_power;
|
||||
u32 __iomem *power;
|
||||
u32 __iomem *power_aux;
|
||||
|
||||
struct clk *sys_clk;
|
||||
|
||||
u32 type;
|
||||
enum omap_control_usb_type type;
|
||||
};
|
||||
|
||||
enum omap_control_usb_mode {
|
||||
@ -38,10 +45,6 @@ enum omap_control_usb_mode {
|
||||
USB_MODE_DISCONNECT,
|
||||
};
|
||||
|
||||
/* To differentiate ctrl module IP having either mailbox or USB3 PHY power */
|
||||
#define OMAP_CTRL_DEV_TYPE1 0x1
|
||||
#define OMAP_CTRL_DEV_TYPE2 0x2
|
||||
|
||||
#define OMAP_CTRL_DEV_PHY_PD BIT(0)
|
||||
|
||||
#define OMAP_CTRL_DEV_AVALID BIT(0)
|
||||
@ -59,10 +62,11 @@ enum omap_control_usb_mode {
|
||||
#define OMAP_CTRL_USB3_PHY_TX_RX_POWERON 0x3
|
||||
#define OMAP_CTRL_USB3_PHY_TX_RX_POWEROFF 0x0
|
||||
|
||||
#define OMAP_CTRL_USB2_PHY_PD BIT(28)
|
||||
|
||||
#if IS_ENABLED(CONFIG_OMAP_CONTROL_USB)
|
||||
extern struct device *omap_get_control_dev(void);
|
||||
extern void omap_control_usb_phy_power(struct device *dev, int on);
|
||||
extern void omap_control_usb3_phy_power(struct device *dev, bool on);
|
||||
extern void omap_control_usb_set_mode(struct device *dev,
|
||||
enum omap_control_usb_mode mode);
|
||||
#else
|
||||
@ -75,10 +79,6 @@ static inline void omap_control_usb_phy_power(struct device *dev, int on)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void omap_control_usb3_phy_power(struct device *dev, int on)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void omap_control_usb_set_mode(struct device *dev,
|
||||
enum omap_control_usb_mode mode)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user