Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Cadence USBSS and USBSSP DRD Driver.
0004  *
0005  * Copyright (C) 2018-2020 Cadence.
0006  * Copyright (C) 2019 Texas Instruments
0007  *
0008  * Author: Pawel Laszczak <pawell@cadence.com>
0009  *         Roger Quadros <rogerq@ti.com>
0010  *
0011  */
0012 #include <linux/kernel.h>
0013 #include <linux/interrupt.h>
0014 #include <linux/delay.h>
0015 #include <linux/iopoll.h>
0016 #include <linux/usb/otg.h>
0017 
0018 #include "drd.h"
0019 #include "core.h"
0020 
0021 /**
0022  * cdns_set_mode - change mode of OTG Core
0023  * @cdns: pointer to context structure
0024  * @mode: selected mode from cdns_role
0025  *
0026  * Returns 0 on success otherwise negative errno
0027  */
0028 static int cdns_set_mode(struct cdns *cdns, enum usb_dr_mode mode)
0029 {
0030     void __iomem  *override_reg;
0031     u32 reg;
0032 
0033     switch (mode) {
0034     case USB_DR_MODE_PERIPHERAL:
0035         break;
0036     case USB_DR_MODE_HOST:
0037         break;
0038     case USB_DR_MODE_OTG:
0039         dev_dbg(cdns->dev, "Set controller to OTG mode\n");
0040 
0041         if (cdns->version == CDNSP_CONTROLLER_V2)
0042             override_reg = &cdns->otg_cdnsp_regs->override;
0043         else if (cdns->version == CDNS3_CONTROLLER_V1)
0044             override_reg = &cdns->otg_v1_regs->override;
0045         else
0046             override_reg = &cdns->otg_v0_regs->ctrl1;
0047 
0048         reg = readl(override_reg);
0049 
0050         if (cdns->version != CDNS3_CONTROLLER_V0)
0051             reg |= OVERRIDE_IDPULLUP;
0052         else
0053             reg |= OVERRIDE_IDPULLUP_V0;
0054 
0055         writel(reg, override_reg);
0056 
0057         if (cdns->version == CDNS3_CONTROLLER_V1) {
0058             /*
0059              * Enable work around feature built into the
0060              * controller to address issue with RX Sensitivity
0061              * est (EL_17) for USB2 PHY. The issue only occures
0062              * for 0x0002450D controller version.
0063              */
0064             if (cdns->phyrst_a_enable) {
0065                 reg = readl(&cdns->otg_v1_regs->phyrst_cfg);
0066                 reg |= PHYRST_CFG_PHYRST_A_ENABLE;
0067                 writel(reg, &cdns->otg_v1_regs->phyrst_cfg);
0068             }
0069         }
0070 
0071         /*
0072          * Hardware specification says: "ID_VALUE must be valid within
0073          * 50ms after idpullup is set to '1" so driver must wait
0074          * 50ms before reading this pin.
0075          */
0076         usleep_range(50000, 60000);
0077         break;
0078     default:
0079         dev_err(cdns->dev, "Unsupported mode of operation %d\n", mode);
0080         return -EINVAL;
0081     }
0082 
0083     return 0;
0084 }
0085 
0086 int cdns_get_id(struct cdns *cdns)
0087 {
0088     int id;
0089 
0090     id = readl(&cdns->otg_regs->sts) & OTGSTS_ID_VALUE;
0091     dev_dbg(cdns->dev, "OTG ID: %d", id);
0092 
0093     return id;
0094 }
0095 
0096 int cdns_get_vbus(struct cdns *cdns)
0097 {
0098     int vbus;
0099 
0100     vbus = !!(readl(&cdns->otg_regs->sts) & OTGSTS_VBUS_VALID);
0101     dev_dbg(cdns->dev, "OTG VBUS: %d", vbus);
0102 
0103     return vbus;
0104 }
0105 
0106 void cdns_clear_vbus(struct cdns *cdns)
0107 {
0108     u32 reg;
0109 
0110     if (cdns->version != CDNSP_CONTROLLER_V2)
0111         return;
0112 
0113     reg = readl(&cdns->otg_cdnsp_regs->override);
0114     reg |= OVERRIDE_SESS_VLD_SEL;
0115     writel(reg, &cdns->otg_cdnsp_regs->override);
0116 }
0117 EXPORT_SYMBOL_GPL(cdns_clear_vbus);
0118 
0119 void cdns_set_vbus(struct cdns *cdns)
0120 {
0121     u32 reg;
0122 
0123     if (cdns->version != CDNSP_CONTROLLER_V2)
0124         return;
0125 
0126     reg = readl(&cdns->otg_cdnsp_regs->override);
0127     reg &= ~OVERRIDE_SESS_VLD_SEL;
0128     writel(reg, &cdns->otg_cdnsp_regs->override);
0129 }
0130 EXPORT_SYMBOL_GPL(cdns_set_vbus);
0131 
0132 bool cdns_is_host(struct cdns *cdns)
0133 {
0134     if (cdns->dr_mode == USB_DR_MODE_HOST)
0135         return true;
0136     else if (cdns_get_id(cdns) == CDNS3_ID_HOST)
0137         return true;
0138 
0139     return false;
0140 }
0141 
0142 bool cdns_is_device(struct cdns *cdns)
0143 {
0144     if (cdns->dr_mode == USB_DR_MODE_PERIPHERAL)
0145         return true;
0146     else if (cdns->dr_mode == USB_DR_MODE_OTG)
0147         if (cdns_get_id(cdns) == CDNS3_ID_PERIPHERAL)
0148             return true;
0149 
0150     return false;
0151 }
0152 
0153 /**
0154  * cdns_otg_disable_irq - Disable all OTG interrupts
0155  * @cdns: Pointer to controller context structure
0156  */
0157 static void cdns_otg_disable_irq(struct cdns *cdns)
0158 {
0159     writel(0, &cdns->otg_irq_regs->ien);
0160 }
0161 
0162 /**
0163  * cdns_otg_enable_irq - enable id and sess_valid interrupts
0164  * @cdns: Pointer to controller context structure
0165  */
0166 static void cdns_otg_enable_irq(struct cdns *cdns)
0167 {
0168     writel(OTGIEN_ID_CHANGE_INT | OTGIEN_VBUSVALID_RISE_INT |
0169            OTGIEN_VBUSVALID_FALL_INT, &cdns->otg_irq_regs->ien);
0170 }
0171 
0172 /**
0173  * cdns_drd_host_on - start host.
0174  * @cdns: Pointer to controller context structure.
0175  *
0176  * Returns 0 on success otherwise negative errno.
0177  */
0178 int cdns_drd_host_on(struct cdns *cdns)
0179 {
0180     u32 val, ready_bit;
0181     int ret;
0182 
0183     /* Enable host mode. */
0184     writel(OTGCMD_HOST_BUS_REQ | OTGCMD_OTG_DIS,
0185            &cdns->otg_regs->cmd);
0186 
0187     if (cdns->version == CDNSP_CONTROLLER_V2)
0188         ready_bit = OTGSTS_CDNSP_XHCI_READY;
0189     else
0190         ready_bit = OTGSTS_CDNS3_XHCI_READY;
0191 
0192     dev_dbg(cdns->dev, "Waiting till Host mode is turned on\n");
0193     ret = readl_poll_timeout_atomic(&cdns->otg_regs->sts, val,
0194                     val & ready_bit, 1, 100000);
0195 
0196     if (ret)
0197         dev_err(cdns->dev, "timeout waiting for xhci_ready\n");
0198 
0199     phy_set_mode(cdns->usb3_phy, PHY_MODE_USB_HOST);
0200     return ret;
0201 }
0202 
0203 /**
0204  * cdns_drd_host_off - stop host.
0205  * @cdns: Pointer to controller context structure.
0206  */
0207 void cdns_drd_host_off(struct cdns *cdns)
0208 {
0209     u32 val;
0210 
0211     writel(OTGCMD_HOST_BUS_DROP | OTGCMD_DEV_BUS_DROP |
0212            OTGCMD_DEV_POWER_OFF | OTGCMD_HOST_POWER_OFF,
0213            &cdns->otg_regs->cmd);
0214 
0215     /* Waiting till H_IDLE state.*/
0216     readl_poll_timeout_atomic(&cdns->otg_regs->state, val,
0217                   !(val & OTGSTATE_HOST_STATE_MASK),
0218                   1, 2000000);
0219     phy_set_mode(cdns->usb3_phy, PHY_MODE_INVALID);
0220 }
0221 
0222 /**
0223  * cdns_drd_gadget_on - start gadget.
0224  * @cdns: Pointer to controller context structure.
0225  *
0226  * Returns 0 on success otherwise negative errno
0227  */
0228 int cdns_drd_gadget_on(struct cdns *cdns)
0229 {
0230     u32 reg = OTGCMD_OTG_DIS;
0231     u32 ready_bit;
0232     int ret, val;
0233 
0234     /* switch OTG core */
0235     writel(OTGCMD_DEV_BUS_REQ | reg, &cdns->otg_regs->cmd);
0236 
0237     dev_dbg(cdns->dev, "Waiting till Device mode is turned on\n");
0238 
0239     if (cdns->version == CDNSP_CONTROLLER_V2)
0240         ready_bit = OTGSTS_CDNSP_DEV_READY;
0241     else
0242         ready_bit = OTGSTS_CDNS3_DEV_READY;
0243 
0244     ret = readl_poll_timeout_atomic(&cdns->otg_regs->sts, val,
0245                     val & ready_bit, 1, 100000);
0246     if (ret) {
0247         dev_err(cdns->dev, "timeout waiting for dev_ready\n");
0248         return ret;
0249     }
0250 
0251     phy_set_mode(cdns->usb3_phy, PHY_MODE_USB_DEVICE);
0252     return 0;
0253 }
0254 EXPORT_SYMBOL_GPL(cdns_drd_gadget_on);
0255 
0256 /**
0257  * cdns_drd_gadget_off - stop gadget.
0258  * @cdns: Pointer to controller context structure.
0259  */
0260 void cdns_drd_gadget_off(struct cdns *cdns)
0261 {
0262     u32 val;
0263 
0264     /*
0265      * Driver should wait at least 10us after disabling Device
0266      * before turning-off Device (DEV_BUS_DROP).
0267      */
0268     usleep_range(20, 30);
0269     writel(OTGCMD_HOST_BUS_DROP | OTGCMD_DEV_BUS_DROP |
0270            OTGCMD_DEV_POWER_OFF | OTGCMD_HOST_POWER_OFF,
0271            &cdns->otg_regs->cmd);
0272     /* Waiting till DEV_IDLE state.*/
0273     readl_poll_timeout_atomic(&cdns->otg_regs->state, val,
0274                   !(val & OTGSTATE_DEV_STATE_MASK),
0275                   1, 2000000);
0276     phy_set_mode(cdns->usb3_phy, PHY_MODE_INVALID);
0277 }
0278 EXPORT_SYMBOL_GPL(cdns_drd_gadget_off);
0279 
0280 /**
0281  * cdns_init_otg_mode - initialize drd controller
0282  * @cdns: Pointer to controller context structure
0283  *
0284  * Returns 0 on success otherwise negative errno
0285  */
0286 static int cdns_init_otg_mode(struct cdns *cdns)
0287 {
0288     int ret;
0289 
0290     cdns_otg_disable_irq(cdns);
0291     /* clear all interrupts */
0292     writel(~0, &cdns->otg_irq_regs->ivect);
0293 
0294     ret = cdns_set_mode(cdns, USB_DR_MODE_OTG);
0295     if (ret)
0296         return ret;
0297 
0298     cdns_otg_enable_irq(cdns);
0299 
0300     return 0;
0301 }
0302 
0303 /**
0304  * cdns_drd_update_mode - initialize mode of operation
0305  * @cdns: Pointer to controller context structure
0306  *
0307  * Returns 0 on success otherwise negative errno
0308  */
0309 int cdns_drd_update_mode(struct cdns *cdns)
0310 {
0311     int ret;
0312 
0313     switch (cdns->dr_mode) {
0314     case USB_DR_MODE_PERIPHERAL:
0315         ret = cdns_set_mode(cdns, USB_DR_MODE_PERIPHERAL);
0316         break;
0317     case USB_DR_MODE_HOST:
0318         ret = cdns_set_mode(cdns, USB_DR_MODE_HOST);
0319         break;
0320     case USB_DR_MODE_OTG:
0321         ret = cdns_init_otg_mode(cdns);
0322         break;
0323     default:
0324         dev_err(cdns->dev, "Unsupported mode of operation %d\n",
0325             cdns->dr_mode);
0326         return -EINVAL;
0327     }
0328 
0329     return ret;
0330 }
0331 
0332 static irqreturn_t cdns_drd_thread_irq(int irq, void *data)
0333 {
0334     struct cdns *cdns = data;
0335 
0336     cdns_hw_role_switch(cdns);
0337 
0338     return IRQ_HANDLED;
0339 }
0340 
0341 /**
0342  * cdns_drd_irq - interrupt handler for OTG events
0343  *
0344  * @irq: irq number for cdns core device
0345  * @data: structure of cdns
0346  *
0347  * Returns IRQ_HANDLED or IRQ_NONE
0348  */
0349 static irqreturn_t cdns_drd_irq(int irq, void *data)
0350 {
0351     irqreturn_t ret = IRQ_NONE;
0352     struct cdns *cdns = data;
0353     u32 reg;
0354 
0355     if (cdns->dr_mode != USB_DR_MODE_OTG)
0356         return IRQ_NONE;
0357 
0358     if (cdns->in_lpm)
0359         return ret;
0360 
0361     reg = readl(&cdns->otg_irq_regs->ivect);
0362 
0363     if (!reg)
0364         return IRQ_NONE;
0365 
0366     if (reg & OTGIEN_ID_CHANGE_INT) {
0367         dev_dbg(cdns->dev, "OTG IRQ: new ID: %d\n",
0368             cdns_get_id(cdns));
0369 
0370         ret = IRQ_WAKE_THREAD;
0371     }
0372 
0373     if (reg & (OTGIEN_VBUSVALID_RISE_INT | OTGIEN_VBUSVALID_FALL_INT)) {
0374         dev_dbg(cdns->dev, "OTG IRQ: new VBUS: %d\n",
0375             cdns_get_vbus(cdns));
0376 
0377         ret = IRQ_WAKE_THREAD;
0378     }
0379 
0380     writel(~0, &cdns->otg_irq_regs->ivect);
0381     return ret;
0382 }
0383 
0384 int cdns_drd_init(struct cdns *cdns)
0385 {
0386     void __iomem *regs;
0387     u32 state;
0388     int ret;
0389 
0390     regs = devm_ioremap_resource(cdns->dev, &cdns->otg_res);
0391     if (IS_ERR(regs))
0392         return PTR_ERR(regs);
0393 
0394     /* Detection of DRD version. Controller has been released
0395      * in three versions. All are very similar and are software compatible,
0396      * but they have same changes in register maps.
0397      * The first register in oldest version is command register and it's
0398      * read only. Driver should read 0 from it. On the other hand, in v1
0399      * and v2 the first register contains device ID number which is not
0400      * set to 0. Driver uses this fact to detect the proper version of
0401      * controller.
0402      */
0403     cdns->otg_v0_regs = regs;
0404     if (!readl(&cdns->otg_v0_regs->cmd)) {
0405         cdns->version  = CDNS3_CONTROLLER_V0;
0406         cdns->otg_v1_regs = NULL;
0407         cdns->otg_cdnsp_regs = NULL;
0408         cdns->otg_regs = regs;
0409         cdns->otg_irq_regs = (struct cdns_otg_irq_regs __iomem  *)
0410                      &cdns->otg_v0_regs->ien;
0411         writel(1, &cdns->otg_v0_regs->simulate);
0412         dev_dbg(cdns->dev, "DRD version v0 (%08x)\n",
0413              readl(&cdns->otg_v0_regs->version));
0414     } else {
0415         cdns->otg_v0_regs = NULL;
0416         cdns->otg_v1_regs = regs;
0417         cdns->otg_cdnsp_regs = regs;
0418 
0419         cdns->otg_regs = (void __iomem *)&cdns->otg_v1_regs->cmd;
0420 
0421         if (readl(&cdns->otg_cdnsp_regs->did) == OTG_CDNSP_DID) {
0422             cdns->otg_irq_regs = (struct cdns_otg_irq_regs __iomem *)
0423                           &cdns->otg_cdnsp_regs->ien;
0424             cdns->version  = CDNSP_CONTROLLER_V2;
0425         } else {
0426             cdns->otg_irq_regs = (struct cdns_otg_irq_regs __iomem *)
0427                           &cdns->otg_v1_regs->ien;
0428             writel(1, &cdns->otg_v1_regs->simulate);
0429             cdns->version  = CDNS3_CONTROLLER_V1;
0430         }
0431 
0432         dev_dbg(cdns->dev, "DRD version v1 (ID: %08x, rev: %08x)\n",
0433              readl(&cdns->otg_v1_regs->did),
0434              readl(&cdns->otg_v1_regs->rid));
0435     }
0436 
0437     state = OTGSTS_STRAP(readl(&cdns->otg_regs->sts));
0438 
0439     /* Update dr_mode according to STRAP configuration. */
0440     cdns->dr_mode = USB_DR_MODE_OTG;
0441 
0442     if ((cdns->version == CDNSP_CONTROLLER_V2 &&
0443          state == OTGSTS_CDNSP_STRAP_HOST) ||
0444         (cdns->version != CDNSP_CONTROLLER_V2 &&
0445          state == OTGSTS_STRAP_HOST)) {
0446         dev_dbg(cdns->dev, "Controller strapped to HOST\n");
0447         cdns->dr_mode = USB_DR_MODE_HOST;
0448     } else if ((cdns->version == CDNSP_CONTROLLER_V2 &&
0449             state == OTGSTS_CDNSP_STRAP_GADGET) ||
0450            (cdns->version != CDNSP_CONTROLLER_V2 &&
0451             state == OTGSTS_STRAP_GADGET)) {
0452         dev_dbg(cdns->dev, "Controller strapped to PERIPHERAL\n");
0453         cdns->dr_mode = USB_DR_MODE_PERIPHERAL;
0454     }
0455 
0456     ret = devm_request_threaded_irq(cdns->dev, cdns->otg_irq,
0457                     cdns_drd_irq,
0458                     cdns_drd_thread_irq,
0459                     IRQF_SHARED,
0460                     dev_name(cdns->dev), cdns);
0461     if (ret) {
0462         dev_err(cdns->dev, "couldn't get otg_irq\n");
0463         return ret;
0464     }
0465 
0466     state = readl(&cdns->otg_regs->sts);
0467     if (OTGSTS_OTG_NRDY(state)) {
0468         dev_err(cdns->dev, "Cadence USB3 OTG device not ready\n");
0469         return -ENODEV;
0470     }
0471 
0472     return 0;
0473 }
0474 
0475 int cdns_drd_exit(struct cdns *cdns)
0476 {
0477     cdns_otg_disable_irq(cdns);
0478 
0479     return 0;
0480 }
0481 
0482 
0483 /* Indicate the cdns3 core was power lost before */
0484 bool cdns_power_is_lost(struct cdns *cdns)
0485 {
0486     if (cdns->version == CDNS3_CONTROLLER_V0) {
0487         if (!(readl(&cdns->otg_v0_regs->simulate) & BIT(0)))
0488             return true;
0489     } else {
0490         if (!(readl(&cdns->otg_v1_regs->simulate) & BIT(0)))
0491             return true;
0492     }
0493     return false;
0494 }
0495 EXPORT_SYMBOL_GPL(cdns_power_is_lost);