|
@@ -355,7 +355,16 @@ struct usb3phy_reg {
|
|
|
u32 write_enable;
|
|
|
};
|
|
|
|
|
|
+/**
|
|
|
+ * struct rockchip_usb3phy_port_cfg: usb3-phy port configuration.
|
|
|
+ * @reg: the base address for usb3-phy config.
|
|
|
+ * @typec_conn_dir: the register of type-c connector direction.
|
|
|
+ * @usb3tousb2_en: the register of type-c force usb2 to usb2 enable.
|
|
|
+ * @external_psm: the register of type-c phy external psm clock.
|
|
|
+ * @pipe_status: the register of type-c phy pipe status.
|
|
|
+ */
|
|
|
struct rockchip_usb3phy_port_cfg {
|
|
|
+ unsigned int reg;
|
|
|
struct usb3phy_reg typec_conn_dir;
|
|
|
struct usb3phy_reg usb3tousb2_en;
|
|
|
struct usb3phy_reg external_psm;
|
|
@@ -372,7 +381,7 @@ struct rockchip_typec_phy {
|
|
|
struct reset_control *uphy_rst;
|
|
|
struct reset_control *pipe_rst;
|
|
|
struct reset_control *tcphy_rst;
|
|
|
- struct rockchip_usb3phy_port_cfg port_cfgs;
|
|
|
+ const struct rockchip_usb3phy_port_cfg *port_cfgs;
|
|
|
/* mutex to protect access to individual PHYs */
|
|
|
struct mutex lock;
|
|
|
|
|
@@ -424,6 +433,24 @@ struct phy_reg dp_pll_cfg[] = {
|
|
|
{ 0x4, CMN_DIAG_PLL1_INCLK_CTRL },
|
|
|
};
|
|
|
|
|
|
+static const struct rockchip_usb3phy_port_cfg rk3399_usb3phy_port_cfgs[] = {
|
|
|
+ {
|
|
|
+ .reg = 0xff7c0000,
|
|
|
+ .typec_conn_dir = { 0xe580, 0, 16 },
|
|
|
+ .usb3tousb2_en = { 0xe580, 3, 19 },
|
|
|
+ .external_psm = { 0xe588, 14, 30 },
|
|
|
+ .pipe_status = { 0xe5c0, 0, 0 },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .reg = 0xff800000,
|
|
|
+ .typec_conn_dir = { 0xe58c, 0, 16 },
|
|
|
+ .usb3tousb2_en = { 0xe58c, 3, 19 },
|
|
|
+ .external_psm = { 0xe594, 14, 30 },
|
|
|
+ .pipe_status = { 0xe5c0, 16, 16 },
|
|
|
+ },
|
|
|
+ { /* sentinel */ }
|
|
|
+};
|
|
|
+
|
|
|
static void tcphy_cfg_24m(struct rockchip_typec_phy *tcphy)
|
|
|
{
|
|
|
u32 i, rdata;
|
|
@@ -691,7 +718,7 @@ static void tcphy_dp_aux_calibration(struct rockchip_typec_phy *tcphy)
|
|
|
|
|
|
static int tcphy_phy_init(struct rockchip_typec_phy *tcphy, u8 mode)
|
|
|
{
|
|
|
- struct rockchip_usb3phy_port_cfg *cfg = &tcphy->port_cfgs;
|
|
|
+ const struct rockchip_usb3phy_port_cfg *cfg = tcphy->port_cfgs;
|
|
|
int ret, i;
|
|
|
u32 val;
|
|
|
|
|
@@ -821,7 +848,7 @@ static int tcphy_get_mode(struct rockchip_typec_phy *tcphy)
|
|
|
static int rockchip_usb3_phy_power_on(struct phy *phy)
|
|
|
{
|
|
|
struct rockchip_typec_phy *tcphy = phy_get_drvdata(phy);
|
|
|
- struct rockchip_usb3phy_port_cfg *cfg = &tcphy->port_cfgs;
|
|
|
+ const struct rockchip_usb3phy_port_cfg *cfg = tcphy->port_cfgs;
|
|
|
const struct usb3phy_reg *reg = &cfg->pipe_status;
|
|
|
int timeout, new_mode, ret = 0;
|
|
|
u32 val;
|
|
@@ -984,51 +1011,9 @@ static const struct phy_ops rockchip_dp_phy_ops = {
|
|
|
.owner = THIS_MODULE,
|
|
|
};
|
|
|
|
|
|
-static int tcphy_get_param(struct device *dev,
|
|
|
- struct usb3phy_reg *reg,
|
|
|
- const char *name)
|
|
|
-{
|
|
|
- u32 buffer[3];
|
|
|
- int ret;
|
|
|
-
|
|
|
- ret = of_property_read_u32_array(dev->of_node, name, buffer, 3);
|
|
|
- if (ret) {
|
|
|
- dev_err(dev, "Can not parse %s\n", name);
|
|
|
- return ret;
|
|
|
- }
|
|
|
-
|
|
|
- reg->offset = buffer[0];
|
|
|
- reg->enable_bit = buffer[1];
|
|
|
- reg->write_enable = buffer[2];
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
static int tcphy_parse_dt(struct rockchip_typec_phy *tcphy,
|
|
|
struct device *dev)
|
|
|
{
|
|
|
- struct rockchip_usb3phy_port_cfg *cfg = &tcphy->port_cfgs;
|
|
|
- int ret;
|
|
|
-
|
|
|
- ret = tcphy_get_param(dev, &cfg->typec_conn_dir,
|
|
|
- "rockchip,typec-conn-dir");
|
|
|
- if (ret)
|
|
|
- return ret;
|
|
|
-
|
|
|
- ret = tcphy_get_param(dev, &cfg->usb3tousb2_en,
|
|
|
- "rockchip,usb3tousb2-en");
|
|
|
- if (ret)
|
|
|
- return ret;
|
|
|
-
|
|
|
- ret = tcphy_get_param(dev, &cfg->external_psm,
|
|
|
- "rockchip,external-psm");
|
|
|
- if (ret)
|
|
|
- return ret;
|
|
|
-
|
|
|
- ret = tcphy_get_param(dev, &cfg->pipe_status,
|
|
|
- "rockchip,pipe-status");
|
|
|
- if (ret)
|
|
|
- return ret;
|
|
|
-
|
|
|
tcphy->grf_regs = syscon_regmap_lookup_by_phandle(dev->of_node,
|
|
|
"rockchip,grf");
|
|
|
if (IS_ERR(tcphy->grf_regs)) {
|
|
@@ -1071,7 +1056,7 @@ static int tcphy_parse_dt(struct rockchip_typec_phy *tcphy,
|
|
|
|
|
|
static void typec_phy_pre_init(struct rockchip_typec_phy *tcphy)
|
|
|
{
|
|
|
- struct rockchip_usb3phy_port_cfg *cfg = &tcphy->port_cfgs;
|
|
|
+ const struct rockchip_usb3phy_port_cfg *cfg = tcphy->port_cfgs;
|
|
|
|
|
|
reset_control_assert(tcphy->tcphy_rst);
|
|
|
reset_control_assert(tcphy->uphy_rst);
|
|
@@ -1092,17 +1077,43 @@ static int rockchip_typec_phy_probe(struct platform_device *pdev)
|
|
|
struct rockchip_typec_phy *tcphy;
|
|
|
struct phy_provider *phy_provider;
|
|
|
struct resource *res;
|
|
|
- int ret;
|
|
|
+ const struct rockchip_usb3phy_port_cfg *phy_cfgs;
|
|
|
+ const struct of_device_id *match;
|
|
|
+ int index, ret;
|
|
|
|
|
|
tcphy = devm_kzalloc(dev, sizeof(*tcphy), GFP_KERNEL);
|
|
|
if (!tcphy)
|
|
|
return -ENOMEM;
|
|
|
|
|
|
+ match = of_match_device(dev->driver->of_match_table, dev);
|
|
|
+ if (!match || !match->data) {
|
|
|
+ dev_err(dev, "phy configs are not assigned!\n");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
|
tcphy->base = devm_ioremap_resource(dev, res);
|
|
|
if (IS_ERR(tcphy->base))
|
|
|
return PTR_ERR(tcphy->base);
|
|
|
|
|
|
+ phy_cfgs = match->data;
|
|
|
+ /* find out a proper config which can be matched with dt. */
|
|
|
+ index = 0;
|
|
|
+ while (phy_cfgs[index].reg) {
|
|
|
+ if (phy_cfgs[index].reg == res->start) {
|
|
|
+ tcphy->port_cfgs = &phy_cfgs[index];
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ ++index;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!tcphy->port_cfgs) {
|
|
|
+ dev_err(dev, "no phy-config can be matched with %s node\n",
|
|
|
+ np->name);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
ret = tcphy_parse_dt(tcphy, dev);
|
|
|
if (ret)
|
|
|
return ret;
|
|
@@ -1162,8 +1173,11 @@ static int rockchip_typec_phy_remove(struct platform_device *pdev)
|
|
|
}
|
|
|
|
|
|
static const struct of_device_id rockchip_typec_phy_dt_ids[] = {
|
|
|
- { .compatible = "rockchip,rk3399-typec-phy" },
|
|
|
- {}
|
|
|
+ {
|
|
|
+ .compatible = "rockchip,rk3399-typec-phy",
|
|
|
+ .data = &rk3399_usb3phy_port_cfgs
|
|
|
+ },
|
|
|
+ { /* sentinel */ }
|
|
|
};
|
|
|
|
|
|
MODULE_DEVICE_TABLE(of, rockchip_typec_phy_dt_ids);
|