PD#161622: usb: enable usb suspend.
Change-Id: I28e2ac7855dbdfe0299592189af179575a264272
Signed-off-by: Yue Wang <yue.wang@amlogic.com>
compatible = "amlogic, amlogic-new-usb2-v2";
status = "disable";
reg = <0x0 0xffe09000 0x0 0x80
- 0x0 0xffd01008 0x0 0x4
+ 0x0 0xffd01008 0x0 0x100
0x0 0xff636000 0x0 0x2000
0x0 0xff63a000 0x0 0x2000>;
pll-setting-1 = <0x09400414>;
struct notifier_block nb;
struct delayed_work work;
+
+ u32 host_plug;
} dwc_otg_device_t;
/*We must clear S3C24XX_EINTPEND external interrupt register
GET_CORE_IF(pcd)->core_global_regs;
uint8_t utmi16b, utmi8b;
int speed;
+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
+
DWC_DEBUGPL(DBG_PCD, "SPEED ENUM\n");
+ if (core_if->controller_type == USB_OTG) {
+ if (core_if->phy_interface == 0) {
+ if (pcd->otg_dev->host_plug) {
+ gintsts.d32 = 0;
+ gintsts.b.enumdone = 1;
+ DWC_WRITE_REG32(&GET_CORE_IF(pcd)->
+ core_global_regs->gintsts, gintsts.d32);
+ DWC_DEBUGPL(DBG_PCD, "false speed emun\n");
+ return 1;
+ }
+ }
+ }
if (GET_CORE_IF(pcd)->snpsid >= OTG_CORE_REV_2_60a) {
utmi16b = 6;
unsigned long value, void *pdata)
{
dwc_otg_device_t *otg_dev;
+ dwc_otg_core_global_regs_t *global_regs;
otg_dev = container_of(nb, dwc_otg_device_t, nb);
+ global_regs = otg_dev->core_if->core_global_regs;
if (value) {
DWC_DEBUGPL(DBG_PCDV, "start usb device\n");
+ otg_dev->host_plug = 0;
dwc_otg_enable_global_interrupts(otg_dev->core_if);
+ if (otg_dev->core_if->phy_interface == 0)
+ dwc_otg_enable_device_interrupts(otg_dev->core_if);
otg_dev->pcd->core_if->pcd_cb->start(otg_dev->pcd);
} else {
+ otg_dev->host_plug = 1;
DWC_DEBUGPL(DBG_PCDV, "stop usb device\n");
dwc_otg_disable_global_interrupts(otg_dev->core_if);
+
+ /* Disable all interrupts. */
+ if (otg_dev->core_if->phy_interface == 0)
+ DWC_WRITE_REG32(&global_regs->gintmsk, 0);
+
otg_dev->pcd->core_if->pcd_cb->stop(otg_dev->pcd);
}
struct u2p_aml_regs_v2 u2p_aml_regs;
union u2p_r0_v2 reg0;
union u2p_r1_v2 reg1;
- //u32 val;
+ u32 val;
- if (phy->suspend_flag) {
- phy->suspend_flag = 0;
- for (i = 0; i < phy->portnum; i++) {
- for (j = 0; j < 2; j++) {
- u2p_aml_regs.u2p_r_v2[j] = (void __iomem *)
- ((unsigned long)phy->regs + i*PHY_REGISTER_SIZE
- + 4 * j);
- }
- }
- /*TO DO: set usb phy to low power mode*/
- return 0;
- }
+ val = readl((void __iomem *)
+ ((unsigned long)phy->reset_regs + (0x21 * 4 - 0x8)));
+ writel((val | (0x3 << 16)), (void __iomem *)
+ ((unsigned long)phy->reset_regs + (0x21 * 4 - 0x8)));
amlogic_new_usbphy_reset_v2(phy);
reg0.d32 = readl(u2p_aml_regs.u2p_r_v2[0]);
reg0.b.POR = 1;
- reg0.b.host_device = 1;
- if (i == 1)
- reg0.b.IDPULLUP0 = 1;
+ if (phy->suspend_flag == 0) {
+ reg0.b.host_device = 1;
+ if (i == 1) {
+ reg0.b.IDPULLUP0 = 1;
+ reg0.b.DRVVBUS0 = 1;
+ }
+ }
writel(reg0.d32, u2p_aml_regs.u2p_r_v2[0]);
static void amlogic_new_usb2phy_shutdown(struct usb_phy *x)
{
struct amlogic_usb_v2 *phy = phy_to_amlusb(x);
- struct u2p_aml_regs_v2 u2p_aml_regs;
- int i, j;
+ u32 val;
- phy->suspend_flag = 1;
- for (i = phy->portnum - 1; i >= 0; i--) {
- for (j = 0; j < 2; j++) {
- u2p_aml_regs.u2p_r_v2[j] = (void __iomem *)
- ((unsigned long)phy->regs + i*PHY_REGISTER_SIZE
- + 4 * j);
- }
+ /* set usb phy to low power mode */
+ val = readl((void __iomem *)
+ ((unsigned long)phy->reset_regs + (0x21 * 4 - 0x8)));
+ writel((val & (~(0x3 << 16))), (void __iomem *)
+ ((unsigned long)phy->reset_regs + (0x21 * 4 - 0x8)));
- /*TO DO: set usb phy to low power mode*/
- }
+ phy->suspend_flag = 1;
}
static int amlogic_new_usb2_probe(struct platform_device *pdev)
phy->regs = phy_base;
phy->reset_regs = reset_base;
phy->portnum = portnum;
- phy->suspend_flag = 0;
phy->phy.dev = phy->dev;
phy->phy.label = "amlogic-usbphy2";
phy->phy.init = amlogic_new_usb2_init;
phy->pll_setting[0] = pll_setting[0];
phy->pll_setting[1] = pll_setting[1];
phy->pll_setting[2] = pll_setting[2];
+ phy->suspend_flag = 0;
for (i = 0; i < portnum; i++)
phy->phy_cfg[i] = phy_cfg_base[i];
blocking_notifier_call_chain
(&aml_new_usb_v2_notifier_list, is_device_on, NULL);
}
-//EXPORT_SYMBOL(aml_new_usb_notifier_call);
static void set_usb_vbus_power
(struct gpio_desc *usb_gd, int pin, char is_power_on)
{
struct amlogic_usb_v2 *phy = phy_to_amlusb(x);
+ if (phy->phy.flags == AML_USB3_PHY_ENABLE)
+ clk_disable_unprepare(phy->clk);
+
phy->suspend_flag = 1;
}
int i = 0;
if (phy->suspend_flag) {
+ if (phy->phy.flags == AML_USB3_PHY_ENABLE)
+ clk_prepare_enable(phy->clk);
phy->suspend_flag = 0;
return 0;
}
writel(r5.d32, usb_new_aml_regs_v2.usb_r_v2[5]);
/* config usb3 phy */
- if (phy->portnum > 0) {
+ if (phy->phy.flags == AML_USB3_PHY_ENABLE) {
r3.d32 = readl(usb_new_aml_regs_v2.usb_r_v2[3]);
r3.b.p30_ssc_en = 1;
r3.b.p30_ref_ssp_en = 1;
}
xhci->port_array[i] = major_revision;
if (major_revision == 0x03)
+#ifdef CONFIG_AMLOGIC_USB
+ if (xhci->quirks & XHCI_AML_SUPER_SPEED_SUPPORT)
+ xhci->num_usb3_ports++;
+ else
+ xhci->num_usb3_ports = 0;
+#else
xhci->num_usb3_ports++;
+#endif
else
xhci->num_usb2_ports++;
}