summaryrefslogtreecommitdiff
path: root/0008-board-rockpi4-dts-upper-port-host.patch
diff options
context:
space:
mode:
authorjc_gargma <jc_gargma@iserlohn-fortress.net>2020-04-05 23:07:13 -0700
committerjc_gargma <jc_gargma@iserlohn-fortress.net>2020-04-05 23:07:13 -0700
commitffc47b07d1ab6437d4fc0bf69e3425a95f6622a7 (patch)
tree7dcc613471fb804bcf5e52c59d93cdfb8e0c91e6 /0008-board-rockpi4-dts-upper-port-host.patch
parentUpdated to 5.5 (diff)
downloadlinux-pinebookpro-ffc47b07d1ab6437d4fc0bf69e3425a95f6622a7.tar.xz
Rebase to 5.6HEADmaster
Diffstat (limited to '0008-board-rockpi4-dts-upper-port-host.patch')
-rw-r--r--0008-board-rockpi4-dts-upper-port-host.patch463
1 files changed, 463 insertions, 0 deletions
diff --git a/0008-board-rockpi4-dts-upper-port-host.patch b/0008-board-rockpi4-dts-upper-port-host.patch
new file mode 100644
index 0000000..f6aa3e7
--- /dev/null
+++ b/0008-board-rockpi4-dts-upper-port-host.patch
@@ -0,0 +1,463 @@
+diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts
+index d02d053..ed2e44d 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts
+@@ -93,7 +93,7 @@
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc5v0_typec_en>;
+ regulator-name = "vcc5v0_typec";
+- regulator-always-on;
++ // regulator-always-on;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+@@ -631,6 +631,7 @@
+ status = "okay";
+
+ u2phy0_otg: otg-port {
++ vbus-supply = <&vcc5v0_typec>;
+ status = "okay";
+ };
+
+@@ -696,6 +697,7 @@
+
+ &usbdrd_dwc3_0 {
+ status = "okay";
++ extcon = <&u2phy0>;
+ dr_mode = "otg";
+ };
+
+
+diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+index eae865f..20d79232 100644
+--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+@@ -69,6 +69,7 @@ enum usb_chg_state {
+ static const unsigned int rockchip_usb2phy_extcon_cable[] = {
+ EXTCON_USB,
+ EXTCON_USB_HOST,
++ EXTCON_USB_VBUS_EN,
+ EXTCON_CHG_USB_SDP,
+ EXTCON_CHG_USB_CDP,
+ EXTCON_CHG_USB_DCP,
+@@ -129,13 +130,29 @@ struct rockchip_usb2phy_port_cfg {
+ struct usb2phy_reg bvalid_det_en;
+ struct usb2phy_reg bvalid_det_st;
+ struct usb2phy_reg bvalid_det_clr;
++ struct usb2phy_reg bypass_dm_en;
++ struct usb2phy_reg bypass_sel;
++ struct usb2phy_reg bypass_iomux;
++ struct usb2phy_reg bypass_bc;
++ struct usb2phy_reg bypass_otg;
++ struct usb2phy_reg bypass_host;
+ struct usb2phy_reg ls_det_en;
+ struct usb2phy_reg ls_det_st;
+ struct usb2phy_reg ls_det_clr;
++ struct usb2phy_reg iddig_output;
++ struct usb2phy_reg iddig_en;
++ struct usb2phy_reg idfall_det_en;
++ struct usb2phy_reg idfall_det_st;
++ struct usb2phy_reg idfall_det_clr;
++ struct usb2phy_reg idrise_det_en;
++ struct usb2phy_reg idrise_det_st;
++ struct usb2phy_reg idrise_det_clr;
+ struct usb2phy_reg utmi_avalid;
+ struct usb2phy_reg utmi_bvalid;
++ struct usb2phy_reg utmi_iddig;
+ struct usb2phy_reg utmi_ls;
+ struct usb2phy_reg utmi_hstdet;
++ struct usb2phy_reg vbus_det_en;
+ };
+
+
+@@ -178,13 +195,16 @@ struct rockchip_usb2phy_port {
+ unsigned int port_id;
+ bool suspended;
+ bool vbus_attached;
++ bool vbus_enabled;
+ int bvalid_irq;
+ int ls_irq;
+ int otg_mux_irq;
++ int id_irq;
+ struct mutex mutex;
+ struct delayed_work chg_work;
+ struct delayed_work otg_sm_work;
+ struct delayed_work sm_work;
++ struct regulator *vbus;
+ const struct rockchip_usb2phy_port_cfg *port_cfg;
+ struct notifier_block event_nb;
+ enum usb_otg_state state;
+@@ -214,6 +234,7 @@ struct rockchip_usb2phy {
+ struct clk *clk;
+ struct clk *clk480m;
+ struct clk_hw clk480m_hw;
++ bool edev_self;
+ enum usb_chg_state chg_state;
+ enum power_supply_type chg_type;
+ u8 dcd_retries;
+@@ -393,6 +414,8 @@ static int rockchip_usb2phy_extcon_register(struct rockchip_usb2phy *rphy)
+ dev_err(rphy->dev, "failed to register extcon device\n");
+ return ret;
+ }
++
++ rphy->edev_self = true;
+ }
+
+ rphy->edev = edev;
+@@ -400,6 +423,28 @@ static int rockchip_usb2phy_extcon_register(struct rockchip_usb2phy *rphy)
+ return 0;
+ }
+
++static int rockchip_set_vbus_power(struct rockchip_usb2phy_port *rport,bool en)
++{
++ int ret = 0;
++
++ if (!rport->vbus)
++ return 0;
++
++ if (en && !rport->vbus_enabled) {
++ ret = regulator_enable(rport->vbus);
++ if (ret)
++ dev_err(&rport->phy->dev,
++ "Failed to enable VBUS supply\n");
++ } else if (!en && rport->vbus_enabled) {
++ ret = regulator_disable(rport->vbus);
++ }
++
++ if (ret == 0)
++ rport->vbus_enabled = en;
++
++ return ret;
++}
++
+ static int rockchip_usb2phy_init(struct phy *phy)
+ {
+ struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
+@@ -407,10 +452,11 @@ static int rockchip_usb2phy_init(struct phy *phy)
+ int ret = 0;
+
+ mutex_lock(&rport->mutex);
+-
++printk("busb rport->port_id=%d\n",rport->port_id );
+ if (rport->port_id == USB2PHY_PORT_OTG) {
+ if (rport->mode != USB_DR_MODE_HOST &&
+ rport->mode != USB_DR_MODE_UNKNOWN) {
++ printk("busb enabled irq\n");
+ /* clear bvalid status and enable bvalid detect irq */
+ ret = property_enable(rphy->grf,
+ &rport->port_cfg->bvalid_det_clr,
+@@ -423,9 +469,34 @@ static int rockchip_usb2phy_init(struct phy *phy)
+ true);
+ if (ret)
+ goto out;
++
++ /* clear id status and enable id detect irq */
++ ret = property_enable(rphy->grf,
++ &rport->port_cfg->idfall_det_clr,
++ true);
++ if (ret)
++ goto out;
++
++ ret = property_enable(rphy->grf,
++ &rport->port_cfg->idfall_det_en,
++ true);
++ if (ret)
++ goto out;
++
++ ret = property_enable(rphy->grf,
++ &rport->port_cfg->idrise_det_clr,
++ true);
++ if (ret)
++ goto out;
++
++ ret = property_enable(rphy->grf,
++ &rport->port_cfg->idrise_det_en,
++ true);
++ if (ret)
++ goto out;
+
+ schedule_delayed_work(&rport->otg_sm_work,
+ OTG_SCHEDULE_DELAY * 3);
+ } else {
+ /* If OTG works in host only mode, do nothing. */
+ dev_dbg(&rport->phy->dev, "mode %d\n", rport->mode);
+@@ -458,7 +529,7 @@ static int rockchip_usb2phy_power_on(struct phy *phy)
+ int ret;
+
+ dev_dbg(&rport->phy->dev, "port power on\n");
+-
++printk("busb port power on\n");
+ if (!rport->suspended)
+ return 0;
+
+@@ -502,7 +573,7 @@ static int rockchip_usb2phy_power_off(struct phy *phy)
+ static int rockchip_usb2phy_exit(struct phy *phy)
+ {
+ struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
+-
++printk("busb rockchip_usb2phy_exit \n");
+ if (rport->port_id == USB2PHY_PORT_OTG &&
+ rport->mode != USB_DR_MODE_HOST &&
+ rport->mode != USB_DR_MODE_UNKNOWN) {
+@@ -514,11 +585,61 @@ static int rockchip_usb2phy_exit(struct phy *phy)
+ return 0;
+ }
+
++static int rockchip_usb2phy_set_mode(struct phy *phy, enum phy_mode mode , int submode)
++{
++ struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
++ struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent);
++ bool vbus_det_en;
++ int ret = 0;
++ if (rport->port_id != USB2PHY_PORT_OTG)
++ return ret;
++
++printk("busb rockchip_usb2phy_set_mode mode = %d,submode=%d\n",mode,submode);
++ switch (mode) {
++ case PHY_MODE_USB_OTG:
++ /*
++ * In case of using vbus to detect connect state by u2phy,
++ * enable vbus detect on otg mode.
++ *
++ * fallthrough
++ */
++ case PHY_MODE_USB_DEVICE:
++ /* Disable VBUS supply */
++ rockchip_set_vbus_power(rport, false);
++ extcon_set_state_sync(rphy->edev, EXTCON_USB_VBUS_EN, false);
++ vbus_det_en = true;
++ break;
++ case PHY_MODE_USB_HOST:
++ /* Enable VBUS supply */
++ ret = rockchip_set_vbus_power(rport, true);
++ if (ret) {
++ dev_err(&rport->phy->dev,
++ "Failed to set host mode\n");
++ return ret;
++ }
++
++ extcon_set_state_sync(rphy->edev, EXTCON_USB_VBUS_EN, true);
++ /* fallthrough */
++ case PHY_MODE_INVALID:
++ vbus_det_en = false;
++ break;
++ default:
++ dev_info(&rport->phy->dev, "illegal mode\n");
++ printk("busb illegal mode\n");
++ return ret;
++ }
++
++ ret = property_enable(rphy->grf, &rport->port_cfg->vbus_det_en, vbus_det_en);
++
++ return ret;
++}
++
+ static const struct phy_ops rockchip_usb2phy_ops = {
+ .init = rockchip_usb2phy_init,
+ .exit = rockchip_usb2phy_exit,
+ .power_on = rockchip_usb2phy_power_on,
+ .power_off = rockchip_usb2phy_power_off,
++// .set_mode = rockchip_usb2phy_set_mode,
+ .owner = THIS_MODULE,
+ };
+
+@@ -540,7 +661,7 @@ static void rockchip_usb2phy_otg_sm_work(struct work_struct *work)
+ delay = OTG_SCHEDULE_DELAY;
+ dev_dbg(&rport->phy->dev, "%s otg sm work\n",
+ usb_otg_state_string(rport->state));
+-
++ printk("busb rockchip_usb2phy_otg_sm_work %s otg sm work %d\n",usb_otg_state_string(rport->state),rport->state);
+ switch (rport->state) {
+ case OTG_STATE_UNDEFINED:
+ rport->state = OTG_STATE_B_IDLE;
+@@ -548,13 +669,16 @@ static void rockchip_usb2phy_otg_sm_work(struct work_struct *work)
+ rockchip_usb2phy_power_off(rport->phy);
+ /* fall through */
+ case OTG_STATE_B_IDLE:
++ printk("busb HOST = %d,VBUS_EN=%d,vbus_attached=%d\n",extcon_get_state(rphy->edev, EXTCON_USB_HOST),extcon_get_state(rphy->edev,EXTCON_USB_VBUS_EN),rport->vbus_attached);
+ if (extcon_get_state(rphy->edev, EXTCON_USB_HOST) > 0) {
+ dev_dbg(&rport->phy->dev, "usb otg host connect\n");
++ printk("busb usb otg host connect\n");
+ rport->state = OTG_STATE_A_HOST;
+ rockchip_usb2phy_power_on(rport->phy);
+ return;
+ } else if (vbus_attach) {
+ dev_dbg(&rport->phy->dev, "vbus_attach\n");
++ printk("busb vbus_attach rphy->chg_state = %d\n",rphy->chg_state);
+ switch (rphy->chg_state) {
+ case USB_CHG_STATE_UNDEFINED:
+ schedule_delayed_work(&rport->chg_work, 0);
+@@ -689,7 +813,7 @@ static void rockchip_chg_detect_work(struct work_struct *work)
+ struct regmap *base = get_reg_base(rphy);
+ bool is_dcd, tmout, vout;
+ unsigned long delay;
+-
++printk("busb chg detection work state = %d\n",rphy->chg_state);
+ dev_dbg(&rport->phy->dev, "chg detection work state = %d\n",
+ rphy->chg_state);
+ switch (rphy->chg_state) {
+@@ -923,6 +1047,42 @@ static irqreturn_t rockchip_usb2phy_bvalid_irq(int irq, void *data)
+ return IRQ_HANDLED;
+ }
+
++static irqreturn_t rockchip_usb2phy_id_irq(int irq, void *data)
++{
++ struct rockchip_usb2phy_port *rport = data;
++ struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
++ bool cable_vbus_state = false;
++printk("brian rockchip_usb2phy_id_irq \n");
++ if (!property_enabled(rphy->grf, &rport->port_cfg->idfall_det_st) &&
++ !property_enabled(rphy->grf, &rport->port_cfg->idrise_det_st))
++ return IRQ_NONE;
++
++ mutex_lock(&rport->mutex);
++
++ /* clear id fall or rise detect irq pending status */
++ if (property_enabled(rphy->grf, &rport->port_cfg->idfall_det_st)) {
++ property_enable(rphy->grf, &rport->port_cfg->idfall_det_clr,
++ true);
++ cable_vbus_state = true;
++ } else if (property_enabled(rphy->grf, &rport->port_cfg->idrise_det_st)) {
++ property_enable(rphy->grf, &rport->port_cfg->idrise_det_clr,
++ true);
++ cable_vbus_state = false;
++ }
++
++ extcon_set_state(rphy->edev, EXTCON_USB_HOST, cable_vbus_state);
++ extcon_set_state(rphy->edev, EXTCON_USB_VBUS_EN, cable_vbus_state);
++
++ extcon_sync(rphy->edev, EXTCON_USB_HOST);
++ extcon_sync(rphy->edev, EXTCON_USB_VBUS_EN);
++
++ rockchip_set_vbus_power(rport, cable_vbus_state);
++
++ mutex_unlock(&rport->mutex);
++
++ return IRQ_HANDLED;
++}
++
+ static irqreturn_t rockchip_usb2phy_otg_mux_irq(int irq, void *data)
+ {
+ struct rockchip_usb2phy_port *rport = data;
+@@ -980,7 +1140,8 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
+ struct rockchip_usb2phy_port *rport,
+ struct device_node *child_np)
+ {
+- int ret;
++ int ret = 0;
++ int iddig;
+
+ rport->port_id = USB2PHY_PORT_OTG;
+ rport->port_cfg = &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_OTG];
+@@ -994,13 +1155,34 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
+ */
+ rport->suspended = true;
+ rport->vbus_attached = false;
++ rport->vbus_enabled = false;
+
++ rport->vbus = devm_regulator_get_optional(&rport->phy->dev, "vbus");
++ if (IS_ERR(rport->vbus)) {
++ ret = PTR_ERR(rport->vbus);
++ if (ret == -EPROBE_DEFER)
++ return ret;
++ printk("busb Failed to get VBUS supply regulator\n");
++ dev_warn(&rport->phy->dev, "Failed to get VBUS supply regulator\n");
++ rport->vbus = NULL;
++ }
++ if(rport->vbus != NULL)
++ printk("busb get rport->vbus ok\n");
+ mutex_init(&rport->mutex);
+
+ rport->mode = of_usb_get_dr_mode_by_phy(child_np, -1);
+ if (rport->mode == USB_DR_MODE_HOST ||
+ rport->mode == USB_DR_MODE_UNKNOWN) {
+- ret = 0;
++ if(rphy->edev_self) {
++ extcon_set_state(rphy->edev, EXTCON_USB, false);
++ extcon_set_state(rphy->edev, EXTCON_USB_HOST, true);
++ extcon_set_state(rphy->edev, EXTCON_USB_VBUS_EN, true);
++ ret = rockchip_set_vbus_power(rport, true);
++ printk("busb rockchip_set_vbus_power ret=%d\n",ret);
++ if(ret)
++ return ret;
++ }
++ //ret = 0;
+ goto out;
+ }
+
+@@ -1044,6 +1226,37 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
+ "failed to request otg-bvalid irq handle\n");
+ goto out;
+ }
++
++ if (rphy->edev_self) {
++
++ rport->id_irq = of_irq_get_byname(child_np, "otg-id");
++ if (rport->id_irq < 0) {
++ dev_err(rphy->dev, "no otg id irq provided\n");
++ ret = rport->id_irq;
++ goto out;
++ }
++
++ ret = devm_request_threaded_irq(rphy->dev, rport->id_irq, NULL,
++ rockchip_usb2phy_id_irq,
++ IRQF_ONESHOT,
++ "rockchip_usb2phy_id", rport);
++ if (ret) {
++ dev_err(rphy->dev, "failed to request otg-id irq handle\n");
++ return ret;
++ }
++
++ iddig = property_enabled(rphy->grf, &rport->port_cfg->utmi_iddig);
++ if(!iddig) {
++ extcon_set_state(rphy->edev, EXTCON_USB, false);
++ extcon_set_state(rphy->edev, EXTCON_USB_HOST, true);
++ extcon_set_state(rphy->edev, EXTCON_USB_VBUS_EN, true);
++
++ ret = rockchip_set_vbus_power(rport, true);
++ printk("busb rockchip_set_vbus_power ret=%d\n",ret);
++ if (ret)
++ return ret;
++ }
++ }
+ }
+
+ if (!IS_ERR(rphy->edev)) {
+@@ -1108,6 +1321,7 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
+ phy_cfgs = match->data;
+ rphy->chg_state = USB_CHG_STATE_UNDEFINED;
+ rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
++ rphy->edev_self = false;
+ platform_set_drvdata(pdev, rphy);
+
+ ret = rockchip_usb2phy_extcon_register(rphy);
+@@ -1329,6 +1543,17 @@ static const struct rockchip_usb2phy_cfg rk3399_phy_cfgs[] = {
+ .bvalid_det_en = { 0xe3c0, 3, 3, 0, 1 },
+ .bvalid_det_st = { 0xe3e0, 3, 3, 0, 1 },
+ .bvalid_det_clr = { 0xe3d0, 3, 3, 0, 1 },
++ .bypass_dm_en = { 0xe450, 2, 2, 0, 1 },
++ .bypass_sel = { 0xe450, 3, 3, 0, 1 },
++ .idfall_det_en = { 0xe3c0, 5, 5, 0, 1 },
++ .idfall_det_st = { 0xe3e0, 5, 5, 0, 1 },
++ .idfall_det_clr = { 0xe3d0, 5, 5, 0, 1 },
++ .idrise_det_en = { 0xe3c0, 4, 4, 0, 1 },
++ .idrise_det_st = { 0xe3e0, 4, 4, 0, 1 },
++ .idrise_det_clr = { 0xe3d0, 4, 4, 0, 1 },
++ .ls_det_en = { 0xe3c0, 2, 2, 0, 1 },
++ .ls_det_st = { 0xe3e0, 2, 2, 0, 1 },
++ .ls_det_clr = { 0xe3d0, 2, 2, 0, 1 },
+ .utmi_avalid = { 0xe2ac, 7, 7, 0, 1 },
+ .utmi_bvalid = { 0xe2ac, 12, 12, 0, 1 },
+ },
+diff --git a/include/linux/extcon.h b/include/linux/extcon.h
+index 2bdf643..1c8e971 100644
+--- a/include/linux/extcon.h
++++ b/include/linux/extcon.h
+@@ -37,6 +37,7 @@
+ /* USB external connector */
+ #define EXTCON_USB 1
+ #define EXTCON_USB_HOST 2
++#define EXTCON_USB_VBUS_EN 3
+
+ /*
+ * Charging external connector