void fpga_config_use_otg(__u32 sram_vbase) { __u32 reg_value = 0; reg_value = USBC_Readl(sram_vbase + 0x04); reg_value |= 0x01; USBC_Writel(reg_value, (sram_vbase + 0x04)); return ; }
void USBC_PHY_Clear_Ctl(void __iomem *regs, __u32 mask) { __u32 reg_val = 0; reg_val = USBC_Readl(regs + USBPHYC_REG_o_PHYCTL); reg_val &= ~(0x01 << mask); USBC_Writel(reg_val, (regs + USBPHYC_REG_o_PHYCTL)); return; }
void UsbPhyCtl(void __iomem *regs) { __u32 reg_val = 0; reg_val = USBC_Readl(regs + USBPHYC_REG_o_PHYCTL); reg_val |= (0x01 << USBC_PHY_CTL_VBUSVLDEXT); USBC_Writel(reg_val, (regs + USBPHYC_REG_o_PHYCTL)); return; }
/* ******************************************************************************* * hci_port_configure * * Description: * void * * Parameters: * void * * Return value: * void * * note: * void * ******************************************************************************* */ static void hci_port_configure(struct sw_hci_hcd *sw_hci, u32 enable) { unsigned long reg_value = 0; u32 usbc_sdram_hpcr = 0; if(sw_hci->usbc_no == 1){ usbc_sdram_hpcr = SW_SDRAM_REG_HPCR_USB1; reg_value = USBC_Readl(sw_hci->sdram_vbase + usbc_sdram_hpcr); if(enable && usb1_enable_configure_cnt == 0){ reg_value |= (1 << SW_SDRAM_BP_HPCR_ACCESS_EN); }else if(!enable && usb1_enable_configure_cnt == 1){ reg_value &= ~(1 << SW_SDRAM_BP_HPCR_ACCESS_EN); } USBC_Writel(reg_value, (sw_hci->sdram_vbase + usbc_sdram_hpcr)); if(enable){ usb1_enable_configure_cnt++; }else{ usb1_enable_configure_cnt--; } }else if(sw_hci->usbc_no == 2){ usbc_sdram_hpcr = SW_SDRAM_REG_HPCR_USB2; reg_value = USBC_Readl(sw_hci->sdram_vbase + usbc_sdram_hpcr); if(enable && usb2_enable_configure_cnt == 0){ reg_value |= (1 << SW_SDRAM_BP_HPCR_ACCESS_EN); }else if(!enable && usb2_enable_configure_cnt == 1){ reg_value &= ~(1 << SW_SDRAM_BP_HPCR_ACCESS_EN); } USBC_Writel(reg_value, (sw_hci->sdram_vbase + usbc_sdram_hpcr)); if(enable){ usb2_enable_configure_cnt++; }else{ usb2_enable_configure_cnt--; } }else{ DMSG_PANIC("EER: unkown usbc_no(%d)\n", sw_hci->usbc_no); return; } return; }
//static u32 close_usb_clock(sw_hcd_io_t *sw_hcd_io) static int close_clock(struct sw_hci_hcd *sw_hci, u32 ohci) { #if 0 u32 reg_value = 0; u32 ccmu_base = SW_VA_CCM_IO_BASE; //DMSG_INFO_HCD0("[%s]: close_usb_clock\n", sw_hcd_driver_name); //Gating AHB clock for USB_phy0 reg_value = USBC_Readl(ccmu_base + 0x60); reg_value &= ~(1 << 2); reg_value &= ~(1 << 1); /* AHB clock gate usb1 */ USBC_Writel(reg_value, (ccmu_base + 0x60)); //等sie的时钟变稳 reg_value = 10000; while(reg_value--); //Enable module clock for USB phy0 reg_value = USBC_Readl(ccmu_base + 0xcc); reg_value &= ~(1 << 9); reg_value &= ~(1 << 8); reg_value &= ~(1 << 6); reg_value &= ~(1 << 1); reg_value &= ~(1 << 0); //disable reset USBC_Writel(reg_value, (ccmu_base + 0xcc)); //延时 reg_value = 10000; while(reg_value--); sw_hci->clk_is_open = 0; DMSG_INFO("[hcd1]: close, 0x60(0x%x), 0xcc(0x%x)\n", (u32)USBC_Readl(SW_VA_CCM_IO_BASE + 0x60), (u32)USBC_Readl(SW_VA_CCM_IO_BASE + 0xcc)); #endif return 0; }
/* ******************************************************************************* * close_usb_clock * * Description: * * * Parameters: * void * * Return value: * void * * note: * void * ******************************************************************************* */ u32 close_usb_clock(sw_udc_io_t *sw_udc_io) { #if 0 u32 reg_value = 0; u32 ccmu_base = SW_VA_CCM_IO_BASE; DMSG_INFO_UDC("close_usb_clock\n"); //Gating AHB clock for USB_phy0 reg_value = USBC_Readl(ccmu_base + 0x60); reg_value &= ~(1 << 2); reg_value &= ~(1 << 1); reg_value &= ~(1 << 0); /* AHB clock gate usb0 */ USBC_Writel(reg_value, (ccmu_base + 0x60)); //等sie的时钟变稳 reg_value = 10000; while(reg_value--); //Enable module clock for USB phy0 reg_value = USBC_Readl(ccmu_base + 0xcc); reg_value &= ~(1 << 9); reg_value &= ~(1 << 8); reg_value &= ~(1 << 6); reg_value &= ~(1 << 1); reg_value &= ~(1 << 0); //disable reset USBC_Writel(reg_value, (ccmu_base + 0xcc)); //延时 reg_value = 10000; while(reg_value--); sw_udc_io->clk_is_open = 0; DMSG_INFO("[udc0]: close, 0x60(0x%x), 0xcc(0x%x)\n", (u32)USBC_Readl(SW_VA_CCM_IO_BASE + 0x60), (u32)USBC_Readl(SW_VA_CCM_IO_BASE + 0xcc)); #endif return 0; }
//static u32 open_usb_clock(sw_hcd_io_t *sw_hcd_io) static int open_clock(struct sw_hci_hcd *sw_hci, u32 ohci) { u32 reg_value = 0; u32 ccmu_base = SW_VA_CCM_IO_BASE; //DMSG_INFO_HCD0("[%s]: open_usb_clock\n", sw_hcd_driver_name); //Gating AHB clock for USB_phy0 reg_value = USBC_Readl(ccmu_base + 0x60); reg_value |= (1 << 2); reg_value |= (1 << 1); /* AHB clock gate usb1 */ USBC_Writel(reg_value, (ccmu_base + 0x60)); //delay to wati SIE stable reg_value = 10000; while(reg_value--); //Enable module clock for USB phy0 reg_value = USBC_Readl(ccmu_base + 0xcc); reg_value |= (1 << 9); reg_value |= (1 << 8); reg_value |= (1 << 6); reg_value |= (1 << 1); reg_value |= (1 << 0); //disable reset USBC_Writel(reg_value, (ccmu_base + 0xcc)); //delay some time reg_value = 10000; while(reg_value--); sw_hci->clk_is_open = 1; DMSG_INFO("[hcd1]: open, 0x60(0x%x), 0xcc(0x%x)\n", (u32)USBC_Readl(SW_VA_CCM_IO_BASE + 0x60), (u32)USBC_Readl(SW_VA_CCM_IO_BASE + 0xcc)); return 0; }
static void sunxi_setup_gpio(void) { #ifdef SUNXI_USB_FPGA int reg_val = 0; reg_val = USBC_Readl(0xf1c20800 + 0x6c + 0xc); //gpiod[30]:dm;gpiod[31]:dp; reg_val &= (~(0xff<<24)); reg_val |= (0x22<<24); USBC_Writel(reg_val, (0xf1c20800 + 0x6c + 0xc)); #else //gpio_set_cfg(GPIO_G(10), 2, 3); //gpio_set_pull(GPIO_G(10), 2, PIO_PULLDOWN); #endif }
/* ******************************************************************************* * open_usb_clock * * Description: * * * Parameters: * void * * Return value: * void * * note: * void * ******************************************************************************* */ u32 open_usb_clock(sw_udc_io_t *sw_udc_io) { u32 reg_value = 0; u32 ccmu_base = SW_VA_CCM_IO_BASE; DMSG_INFO_UDC("open_usb_clock\n"); //Gating AHB clock for USB_phy0 reg_value = USBC_Readl(ccmu_base + 0x60); reg_value |= (1 << 2); reg_value |= (1 << 1); reg_value |= (1 << 0); /* AHB clock gate usb0 */ USBC_Writel(reg_value, (ccmu_base + 0x60)); //delay to wati SIE stable reg_value = 10000; while(reg_value--); //Enable module clock for USB phy0 reg_value = USBC_Readl(ccmu_base + 0xcc); reg_value |= (1 << 9); reg_value |= (1 << 8); reg_value |= (1 << 6); reg_value |= (1 << 1); reg_value |= (1 << 0); USBC_Writel(reg_value, (ccmu_base + 0xcc)); //delay some time reg_value = 10000; while(reg_value--); sw_udc_io->clk_is_open = 1; DMSG_INFO("[udc0]: open, 0x60(0x%x), 0xcc(0x%x)\n", (u32)USBC_Readl(SW_VA_CCM_IO_BASE + 0x60), (u32)USBC_Readl(SW_VA_CCM_IO_BASE + 0xcc)); return 0; }
int switch_to_usb3(void) { struct platform_device *pdev = NULL; struct sunxi_otgc *otgc = NULL; pdev = sunxi_otg_pdev; if(pdev == NULL){ DMSG_PANIC("%s, pdev is NULL\n", __func__); return 0; } otgc = platform_get_drvdata(pdev); if(otgc == NULL){ DMSG_PANIC("%s, otgc is NULL\n", __func__); return 0; } sunxi_host_set_vbus(otgc, 0); USBC_Writel(otgc->regs, 0x10014, 0x43); msleep(500); sunxi_host_set_vbus(otgc, 1); USBC_Writel(otgc->regs, 0x10014, 0x40); return 0; }
static __u32 USBC_Phy_TpRead(__u32 usbc_no, __u32 addr, __u32 len) { __u32 temp = 0, ret = 0; __u32 i=0; __u32 j=0; for(j = len; j > 0; j--) { /* set the bit address to be read */ temp = USBC_Readl(USBC_Phy_GetCsr(usbc_no)); temp &= ~(0xff << 8); temp |= ((addr + j -1) << 8); USBC_Writel(temp, USBC_Phy_GetCsr(usbc_no)); for(i = 0; i < 0x4; i++); temp = USBC_Readl(USBC_Phy_GetCsr(usbc_no)); ret <<= 1; ret |= ((temp >> (16 + usbc_no)) & 0x1); } return ret; }
static void usb_passby(struct sunxi_hci_hcd *sunxi_hci, u32 enable) { unsigned long reg_value = 0; spinlock_t lock; unsigned long flags = 0; spin_lock_init(&lock); spin_lock_irqsave(&lock, flags); /*enable passby*/ if(sunxi_hci->usbc_no == 1){ reg_value = USBC_Readl(sunxi_hci->usb_vbase + SUNXI_USB_PMU_IRQ_ENABLE); if(enable && usb1_enable_passly_cnt == 0){ reg_value |= (1 << 10); /* AHB Master interface INCR8 enable */ reg_value |= (1 << 9); /* AHB Master interface burst type INCR4 enable */ reg_value |= (1 << 8); /* AHB Master interface INCRX align enable */ #ifdef SUNXI_USB_FPGA reg_value |= (0 << 0); /* enable ULPI, disable UTMI */ #else reg_value |= (1 << 0); /* enable UTMI, disable ULPI */ #endif }else if(!enable && usb1_enable_passly_cnt == 1){ reg_value &= ~(1 << 10); /* AHB Master interface INCR8 disable */ reg_value &= ~(1 << 9); /* AHB Master interface burst type INCR4 disable */ reg_value &= ~(1 << 8); /* AHB Master interface INCRX align disable */ reg_value &= ~(1 << 0); /* ULPI bypass disable */ } USBC_Writel(reg_value, (sunxi_hci->usb_vbase + SUNXI_USB_PMU_IRQ_ENABLE)); if(enable){ usb1_enable_passly_cnt++; }else{ usb1_enable_passly_cnt--; } }else if(sunxi_hci->usbc_no == 2){ reg_value = USBC_Readl(sunxi_hci->usb_vbase + SUNXI_USB_PMU_IRQ_ENABLE); if(enable && usb2_enable_passly_cnt == 0){ reg_value |= (1 << 10); /* AHB Master interface INCR8 enable */ reg_value |= (1 << 9); /* AHB Master interface burst type INCR4 enable */ reg_value |= (1 << 8); /* AHB Master interface INCRX align enable */ reg_value |= (1 << 0); /* ULPI bypass enable */ }else if(!enable && usb2_enable_passly_cnt == 1){ reg_value &= ~(1 << 10); /* AHB Master interface INCR8 disable */ reg_value &= ~(1 << 9); /* AHB Master interface burst type INCR4 disable */ reg_value &= ~(1 << 8); /* AHB Master interface INCRX align disable */ reg_value &= ~(1 << 0); /* ULPI bypass disable */ } USBC_Writel(reg_value, (sunxi_hci->usb_vbase + SUNXI_USB_PMU_IRQ_ENABLE)); if(enable){ usb2_enable_passly_cnt++; }else{ usb2_enable_passly_cnt--; } }else if(sunxi_hci->usbc_no == 3){ reg_value = USBC_Readl(sunxi_hci->usb_vbase + SUNXI_USB_PMU_IRQ_ENABLE); if(enable && usb3_enable_passly_cnt == 0){ reg_value |= (1 << 10); /* AHB Master interface INCR8 enable */ reg_value |= (1 << 9); /* AHB Master interface burst type INCR4 enable */ reg_value |= (1 << 8); /* AHB Master interface INCRX align enable */ reg_value |= (1 << 0); /* ULPI bypass enable */ }else if(!enable && usb3_enable_passly_cnt == 1){ reg_value &= ~(1 << 10); /* AHB Master interface INCR8 disable */ reg_value &= ~(1 << 9); /* AHB Master interface burst type INCR4 disable */ reg_value &= ~(1 << 8); /* AHB Master interface INCRX align disable */ reg_value &= ~(1 << 0); /* ULPI bypass disable */ } USBC_Writel(reg_value, (sunxi_hci->usb_vbase + SUNXI_USB_PMU_IRQ_ENABLE)); if(enable){ usb3_enable_passly_cnt++; }else{ usb3_enable_passly_cnt--; } }else{ DMSG_PANIC("EER: unkown usbc_no(%d)\n", sunxi_hci->usbc_no); spin_unlock_irqrestore(&lock, flags); return; } spin_unlock_irqrestore(&lock, flags); return; }
static int close_clock(struct sunxi_hci_hcd *sunxi_hci, u32 ohci) { #ifndef CONFIG_ARCH_SUN9IW1 u32 reg_value = 0; u32 ccmu_base = (u32 __force)SUNXI_CCM_VBASE; DMSG_INFO("[%s]: close clock\n", sunxi_hci->hci_name); //Gating AHB clock for USB_phy1 reg_value = USBC_Readl(ccmu_base + 0x60); reg_value &= ~(1 << 29); /* close AHB for ohci */ reg_value &= ~(1 << 26); /* close AHB for ehci */ USBC_Writel(reg_value, (ccmu_base + 0x60)); reg_value = USBC_Readl(ccmu_base + 0x2c0); reg_value &= ~(1 << 29); /* ohci reset control, assert */ reg_value &= ~(1 << 26); /* ehci reset control, assert */ USBC_Writel(reg_value, (ccmu_base + 0x2c0)); //delay to wati SIE stable reg_value = 10000; while(reg_value--); //Enable module clock for USB phy1 reg_value = USBC_Readl(ccmu_base + 0xcc); reg_value &= ~(1 << 16); /* close specal clock for ohci */ reg_value &= ~(1 << 9); /* close specal clock for usb phy1(ehci0,ohci0) */ reg_value &= ~(1 << 8); /* close specal clock for usb phy0(otg) */ reg_value &= ~(1 << 1); /* usb phy1 reset */ reg_value &= ~(1 << 0); /* usb phy0 reset */ USBC_Writel(reg_value, (ccmu_base + 0xcc)); return 0; #else u32 reg_value = 0; u32 ccmu_base = (u32)SUNXI_CCM_VBASE; DMSG_INFO("[%s]: close clock\n", sunxi_hci->hci_name); usb_hci_clock_cnt --; //AHB ALL clock gate reg_value = USBC_Readl(ccmu_base + 0x184); reg_value &= ~(1 << 1); /* AHB clock gate usb0 */ USBC_Writel(reg_value, (ccmu_base + 0x184)); reg_value = USBC_Readl(ccmu_base + 0x1A4); reg_value &= ~(1 << 0); /* AHB clock gate usb0 */ USBC_Writel(reg_value, (ccmu_base + 0x1A4)); reg_value = USBC_Readl(SUNXI_USB_CTRL_VBASE + 0x04); reg_value &= ~(0x01<<3); reg_value &= ~(0x01<<19); USBC_Writel(reg_value, SUNXI_USB_CTRL_VBASE + 0x04); reg_value = USBC_Readl(SUNXI_USB_CTRL_VBASE); reg_value &= ~(0x1<<3); reg_value &= ~(0x1<<4); reg_value &= ~(0x01<<18); USBC_Writel(reg_value, SUNXI_USB_CTRL_VBASE); return 0; #endif }
static int open_clock(struct sunxi_hci_hcd *sunxi_hci, u32 ohci) { #ifndef CONFIG_ARCH_SUN9IW1 u32 reg_value = 0; u32 ccmu_base = (u32 __force)SUNXI_CCM_VBASE; DMSG_INFO("[%s]: open clock\n", sunxi_hci->hci_name); //Gating AHB clock for USB_phy1 reg_value = USBC_Readl(ccmu_base + 0x60); reg_value |= (1 << 26); /* AHB clock gate ehci */ reg_value |= (1 << 29); /* AHB clock gate ohci */ USBC_Writel(reg_value, (ccmu_base + 0x60)); reg_value = USBC_Readl(ccmu_base + 0x2c0); reg_value |= (1 << 26); /* ehci reset control, de-assert */ reg_value |= (1 << 29); /* ohci reset control, de-assert */ USBC_Writel(reg_value, (ccmu_base + 0x2c0)); //delay to wati SIE stable reg_value = 10000; while(reg_value--); //Enable module clock for USB phy1 reg_value = USBC_Readl(ccmu_base + 0xcc); reg_value |= (1 << 16); /* gating specal clock for ohci */ reg_value |= (1 << 9); /* gating specal clock for usb phy1(ehci0,ohci0) */ reg_value |= (1 << 8); /* gating specal clock for usb phy0(otg) */ reg_value |= (1 << 1); /* usb phy1 reset */ reg_value |= (1 << 0); /* usb phy0 reset */ USBC_Writel(reg_value, (ccmu_base + 0xcc)); //delay some time reg_value = 10000; while(reg_value--); UsbPhyInit(sunxi_hci->usbc_no); printk("open_clock 0x60(0x%x), 0xcc(0x%x),0x2c0(0x%x)\n", (u32)USBC_Readl(ccmu_base + 0x60), (u32)USBC_Readl(ccmu_base + 0xcc), (u32)USBC_Readl(ccmu_base + 0x2c0)); return 0; #else u32 reg_value = 0; u32 i = 0; u32 ccmu_base = (u32)SUNXI_CCM_VBASE; DMSG_INFO("[%s]: open clock\n", sunxi_hci->hci_name); usb_hci_clock_cnt ++ ; //AHB ALL clock gate reg_value = USBC_Readl(ccmu_base + 0x184); reg_value |= (1 << 1); /* AHB clock gate usb0 */ USBC_Writel(reg_value, (ccmu_base + 0x184)); reg_value = USBC_Readl(ccmu_base + 0x1A4); reg_value |= (1 << 0); /* AHB clock gate usb0 */ USBC_Writel(reg_value, (ccmu_base + 0x1A4)); reg_value = USBC_Readl(SUNXI_USB_CTRL_VBASE + 0x04); reg_value &= ~(0x1f<<1); reg_value &= ~(0x01<<10); reg_value &= ~(0x01<<12); reg_value &= ~(0x1f<<17); reg_value |= (0x01<<3); USBC_Writel(reg_value, SUNXI_USB_CTRL_VBASE + 0x04); for(i=0; i<0x10; i++); reg_value = USBC_Readl(SUNXI_USB_CTRL_VBASE + 0x04); reg_value |= (0x01<<19); USBC_Writel(reg_value, SUNXI_USB_CTRL_VBASE + 0x04); reg_value = USBC_Readl(SUNXI_USB_CTRL_VBASE); reg_value &= ~(0xf<<1); reg_value &= ~(0xf<<17); reg_value |= (0x1<<3); reg_value |= (0x1<<4); USBC_Writel(reg_value, SUNXI_USB_CTRL_VBASE); for(i=0; i<0x10; i++); reg_value = USBC_Readl(SUNXI_USB_CTRL_VBASE); reg_value |= (0x01<<18); USBC_Writel(reg_value, SUNXI_USB_CTRL_VBASE); printk("open_clock 0x184(0x%x), 0x1A4(0x%x),0x%x(0x%x),0x%x(0x%x)\n", (u32)USBC_Readl(ccmu_base + 0x184), (u32)USBC_Readl(ccmu_base + 0x1A4), (u32)(SUNXI_USB_CTRL_VBASE + 0x04),(u32)USBC_Readl(SUNXI_USB_CTRL_VBASE + 0x04), (u32)SUNXI_USB_CTRL_VBASE, (u32)USBC_Readl(SUNXI_USB_CTRL_VBASE)); return 0; #endif }
static int open_hci_clock(struct sunxi_hci_hcd *sunxi_hci, u32 ohci) { int reg_value = 0; int i = 0; DMSG_INFO("[%s]: open hci clock,usbc_no:%d, is_ohci:%d\n", sunxi_hci->hci_name, sunxi_hci->usbc_no, ohci); switch (sunxi_hci->usbc_no){ case 1: /*PHY*/ reg_value = USBC_Readl(SUNXI_USB_CTRL_VBASE + HCI_PHY_CONTROL_REGISTER); reg_value |= (0x01<<1);// enable SCLK_GATING_HCI0_PHY USBC_Writel(reg_value, SUNXI_USB_CTRL_VBASE + HCI_PHY_CONTROL_REGISTER); for(i = 0; i < 0x10; i++); reg_value = USBC_Readl(SUNXI_USB_CTRL_VBASE + HCI_PHY_CONTROL_REGISTER); reg_value |= (0x01<<17);//enable HCI0_PHY_RST USBC_Writel(reg_value, SUNXI_USB_CTRL_VBASE + HCI_PHY_CONTROL_REGISTER); /*SIE*/ for(i = 0; i < 0x10; i++); reg_value = USBC_Readl(SUNXI_USB_CTRL_VBASE + HCI_SIE_CONTROL_REGISTER); reg_value |= (0x1<<1); //enable USB HCI0 AHB Gating reg_value |= (0x1<<17); //enable USB HCI0 Module Reset if(ohci){ reg_value |= (0x1<<2);//enable USB OHCI0 Special Clock(12M and 48M) Gating } USBC_Writel(reg_value, SUNXI_USB_CTRL_VBASE + HCI_SIE_CONTROL_REGISTER); break; case 2: //force high to ehci control reg_value = USBC_Readl(sunxi_hci->usb_vbase+ SUNXI_USB_PMU_IRQ_ENABLE); reg_value |= (1 << 1); reg_value |= (1 << 20); reg_value |= (1 << 17); USBC_Writel(reg_value, (sunxi_hci->usb_vbase+ SUNXI_USB_PMU_IRQ_ENABLE)); /*PHY*/ reg_value = USBC_Readl(SUNXI_USB_CTRL_VBASE + HCI_PHY_CONTROL_REGISTER); reg_value |= (0x01<<2); //enable 480M_GATING_HCI1_HSIC reg_value &= ~(0x01<<3); //disablde SCLK_GATING_HCI1_ULPIMP/ULPISP reg_value |= (0x01<<10); //enble 12M_GATING_HCI1_HSIC USBC_Writel(reg_value, SUNXI_USB_CTRL_VBASE + HCI_PHY_CONTROL_REGISTER); for(i = 0; i < 0x10; i++); reg_value = USBC_Readl(SUNXI_USB_CTRL_VBASE + HCI_PHY_CONTROL_REGISTER); reg_value |= (0x01<<18);//enbale HCI1_HSIC_RST reg_value &= ~(0x01<<19);//disenable HCI1_ULPIMP_RST/HCI1_ULPISP_RST USBC_Writel(reg_value, SUNXI_USB_CTRL_VBASE + HCI_PHY_CONTROL_REGISTER); /*SIE*/ for(i = 0; i < 0x10; i++); reg_value = USBC_Readl(SUNXI_USB_CTRL_VBASE + HCI_SIE_CONTROL_REGISTER); reg_value |= (0x1<<3); //enable USB HCI1 AHB Gating reg_value |= (0x1<<18); //enable USB HCI1 Module Reset if(ohci){ reg_value &= ~(0x1<<4); //disenable USB OHCI1 Special Clock(12M and 48M) Gating } USBC_Writel(reg_value, SUNXI_USB_CTRL_VBASE + HCI_SIE_CONTROL_REGISTER); break; case 3: /*PHY*/ reg_value = USBC_Readl(SUNXI_USB_CTRL_VBASE + HCI_PHY_CONTROL_REGISTER); reg_value |= (0x01<<5); //enable SCLK_GATING_HCI2_UTMIPHY reg_value &= ~(0x01<<4); //disablde 480M_GATING_HCI2_HSIC reg_value &= ~(0x01<<10); //disablde 12M_GATING_HCI2_HSIC USBC_Writel(reg_value, SUNXI_USB_CTRL_VBASE + HCI_PHY_CONTROL_REGISTER); for(i = 0; i < 0x10; i++); reg_value = USBC_Readl(SUNXI_USB_CTRL_VBASE + HCI_PHY_CONTROL_REGISTER); reg_value |= (0x01<<21);//enbale HCI2_UTMIPHY_RST reg_value &= ~(0x01<<20);//disenable HCI2_HSIC_RST USBC_Writel(reg_value, SUNXI_USB_CTRL_VBASE + HCI_PHY_CONTROL_REGISTER); /*SIE*/ for(i = 0; i < 0x10; i++); reg_value = USBC_Readl(SUNXI_USB_CTRL_VBASE + HCI_SIE_CONTROL_REGISTER); reg_value |= (0x1<<5); //enable USB HCI2 AHB Gating reg_value |= (0x1<<19); //enable USB HCI2 Module Reset if(ohci){ reg_value |= (0x1<<6); //enable USB OHCI1 Special Clock(12M and 48M) Gating } USBC_Writel(reg_value, SUNXI_USB_CTRL_VBASE + HCI_SIE_CONTROL_REGISTER); break; default: return 0; } return 0; }
static int open_clock(struct sunxi_hci_hcd *sunxi_hci, u32 ohci) { DMSG_INFO("[%s]: open clock, is_open: %d\n", sunxi_hci->hci_name, sunxi_hci->clk_is_open); #ifdef CONFIG_ARCH_SUN9IW1 #ifdef CONFIG_USB_SUNXI_HSIC if(regulator_enable(vbat_hsic_hdle) < 0){ DMSG_INFO("ERR: vbat_hsic: regulator_enable fail\n"); return 0; } #else if(regulator_enable(vbat_usbh_hdle) < 0){ DMSG_INFO("ERR: vbat_usbh: regulator_enable fail\n"); return 0; } #endif if(usb_hci_clock_cnt == 0 && (hci_ahb_gate != NULL)){ DMSG_INFO("clk_prepare_enable: hci_ahb_gate\n"); if(clk_prepare_enable(hci_ahb_gate)){ DMSG_PANIC("ERR:try to prepare_enable %s_ahb failed!\n", sunxi_hci->hci_name); } } usb_hci_clock_cnt ++; if(!sunxi_hci->clk_is_open){ sunxi_hci->clk_is_open = 1; open_hci_clock(sunxi_hci,ohci); } #else if(sunxi_hci->ahb && sunxi_hci->mod_usbphy && !sunxi_hci->clk_is_open){ sunxi_hci->clk_is_open = 1; if(clk_prepare_enable(sunxi_hci->ahb)){ DMSG_PANIC("ERR:try to prepare_enable %s_ahb failed!\n", sunxi_hci->hci_name); } mdelay(10); #ifdef CONFIG_USB_SUNXI_HSIC { u32 reg_value = 0; u32 i = 0; u32 ccmu_base = (u32)SUNXI_CCM_VBASE; reg_value = USBC_Readl(ccmu_base + 0xcc); reg_value |= (0x01<<10); reg_value |= (0x01<<11); USBC_Writel(reg_value, (ccmu_base + 0xcc)); for(i=0; i < 0x100; i++); reg_value |= (0x01 << 2); USBC_Writel(reg_value, (ccmu_base + 0xcc)); } #else if(clk_prepare_enable(sunxi_hci->mod_usbphy)){ DMSG_PANIC("ERR:try to prepare_enable %s_usbphy failed!\n", sunxi_hci->hci_name); } mdelay(10); #endif UsbPhyInit(sunxi_hci->usbc_no); }else{ DMSG_PANIC("[%s]: wrn: open clock failed, (0x%p, 0x%p, %d, 0x%p)\n", sunxi_hci->hci_name, sunxi_hci->ahb, sunxi_hci->mod_usbphy, sunxi_hci->clk_is_open, sunxi_hci->mod_usb); } #endif return 0; }
void clear_usb_reg(__u32 usb_base) { __u32 reg_val = 0; __u32 i = 0; /* global control and status */ reg_val = USBC_Readl(USBC_REG_EX_USB_GCS(usb_base)); reg_val = 0x20; USBC_Writel(reg_val, USBC_REG_EX_USB_GCS(usb_base)); /* endpoint interrupt flag */ reg_val = USBC_Readl(USBC_REG_EX_USB_EPINTF(usb_base)); reg_val = 0x44; USBC_Writel(reg_val, USBC_REG_EX_USB_EPINTF(usb_base)); /* endpoint interrupt enable */ reg_val = USBC_Readl(USBC_REG_EX_USB_EPINTE(usb_base)); reg_val = 0x48; USBC_Writel(reg_val, USBC_REG_EX_USB_EPINTE(usb_base)); /* bus interrupt flag */ reg_val = USBC_Readl(USBC_REG_EX_USB_BUSINTF(usb_base)); reg_val = 0x4c; USBC_Writel(reg_val, USBC_REG_EX_USB_BUSINTF(usb_base)); /* bus interrupt enable */ reg_val = USBC_Readl(USBC_REG_EX_USB_BUSINTE(usb_base)); reg_val = 0x50; USBC_Writel(reg_val, USBC_REG_EX_USB_BUSINTE(usb_base)); /* endpoint control status */ for(i = 0; i < USBC_MAX_EP_NUM; i++) { USBC_Writeb(i, USBC_REG_EPIND(usb_base)); /* endpoint control status */ if (i == 0) { reg_val = USBC_Readl(USBC_REG_EX_USB_CSR0(usb_base)); reg_val = 0x00; USBC_Writel(reg_val, USBC_REG_EX_USB_CSR0(usb_base)); } else { /* TX endpoint control status */ reg_val = USBC_Readl(USBC_REG_EX_USB_TXCSR(usb_base)); reg_val = 0x00; USBC_Writel(reg_val, USBC_REG_EX_USB_TXCSR(usb_base)); /* RX endpoint control status */ reg_val = USBC_Readl(USBC_REG_EX_USB_RXCSR(usb_base)); reg_val = 0x00; USBC_Writel(reg_val, USBC_REG_EX_USB_RXCSR(usb_base)); } /* TX fifo seting */ reg_val = USBC_Readl(USBC_REG_EX_USB_TXFIFO(usb_base)); reg_val = 0x90; USBC_Writel(reg_val, USBC_REG_EX_USB_TXFIFO(usb_base)); /* RX fifo seting */ reg_val = USBC_Readl(USBC_REG_EX_USB_RXFIFO(usb_base)); reg_val = 0x94; USBC_Writel(reg_val, USBC_REG_EX_USB_RXFIFO(usb_base)); /* function address */ reg_val = USBC_Readl(USBC_REG_EX_USB_FADDR(usb_base)); reg_val = 0x00; USBC_Writel(reg_val, USBC_REG_EX_USB_FADDR(usb_base)); } USBC_Writeb(0x00, USBC_REG_EPIND(usb_base)); return; }