int dss_init(struct platform_device *pdev) { int r = 0, dss_irq; u32 rev; struct resource *dss_mem; bool skip_init = false; dss.pdata = pdev->dev.platform_data; dss.pdev = pdev; if (cpu_is_omap44xx()) dss_mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); else dss_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!dss_mem) { WARN_ON(1); r = -ENODEV; goto fail0; } dss.base = ioremap(dss_mem->start, resource_size(dss_mem)); if (!dss.base) { DSSERR("can't ioremap DSS\n"); r = -ENOMEM; goto fail0; } dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M | DSS_CLK_96M); dss_mainclk_enable(); #ifdef CONFIG_FB_OMAP_BOOTLOADER_INIT /* DISPC_CONTROL */ if (omap_readl(0x48050440) & 1) /* LCD enabled? */ skip_init = true; #endif if (!skip_init) { /* disable LCD and DIGIT output. This seems to fix the synclost * problem that we get, if the bootloader starts the DSS and * the kernel resets it */ omap_writel(omap_readl(0x48050440) & ~0x3, 0x48050440); /* We need to wait here a bit, otherwise we sometimes start to * get synclost errors, and after that only power cycle will * restore DSS functionality. I have no idea why this happens. * And we have to wait _before_ resetting the DSS, but after * enabling clocks. */ msleep(50); } /* autoidle */ REG_FLD_MOD(DSS_SYSCONFIG, 1, 0, 0); /* Select DPLL */ REG_FLD_MOD(DSS_CONTROL, 0, 0, 0); #ifdef CONFIG_OMAP2_DSS_VENC REG_FLD_MOD(DSS_CONTROL, 1, 4, 4); /* venc dac demen */ REG_FLD_MOD(DSS_CONTROL, 1, 3, 3); /* venc clock 4x enable */ REG_FLD_MOD(DSS_CONTROL, 0, 2, 2); /* venc clock mode = normal */ #endif if (!cpu_is_omap44xx()) r = request_irq(INT_24XX_DSS_IRQ, cpu_is_omap24xx() ? dss_irq_handler_omap2 : dss_irq_handler_omap3, 0, "OMAP DSS", NULL); else { dss_irq = platform_get_irq(pdev, 0); r = request_irq(dss_irq, dss_irq_handler_omap2, 0, "OMAP DSS", NULL); } if (r < 0) { DSSERR("omap2 dss: request_irq failed\n"); goto fail1; } if (cpu_is_omap34xx()) { dss.dpll4_m4_ck = clk_get(NULL, "dpll4_m4_ck"); if (IS_ERR(dss.dpll4_m4_ck)) { DSSERR("Failed to get dpll4_m4_ck\n"); r = PTR_ERR(dss.dpll4_m4_ck); goto fail2; } } dss.dsi1_clk_source = DSS_SRC_DSS1_ALWON_FCLK; dss.dsi2_clk_source = DSS_SRC_DSS1_ALWON_FCLK; dss.lcd1_clk_source = DSS_SRC_DSS1_ALWON_FCLK; dss.lcd2_clk_source = DSS_SRC_DSS1_ALWON_FCLK; dss.dispc_clk_source = DSS_SRC_DSS1_ALWON_FCLK; dss_save_context(); rev = dss_read_reg(DSS_REVISION); printk(KERN_INFO "OMAP DSS rev %d.%d\n", FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M | DSS_CLK_96M); return 0; fail2: if (!cpu_is_omap44xx()) free_irq(INT_24XX_DSS_IRQ, NULL); fail1: iounmap(dss.base); fail0: return r; }
int dss_init(bool skip_init) { int r; u32 rev; dss_base = dss.base = ioremap(DSS_BASE, DSS_SZ_REGS); if (!dss.base) { DSSERR("can't ioremap DSS\n"); r = -ENOMEM; goto fail0; } if (cpu_is_omap44xx()) test(); if (!skip_init) { /* disable LCD and DIGIT output. This seems to fix the synclost * problem that we get, if the bootloader starts the DSS and * the kernel resets it */ if (cpu_is_omap34xx()) omap_writel(omap_readl(0x48050440) & ~0x3, 0x48050440); /* We need to wait here a bit, otherwise we sometimes start to * get synclost errors, and after that only power cycle will * restore DSS functionality. I have no idea why this happens. * And we have to wait _before_ resetting the DSS, but after * enabling clocks. */ msleep(50); _omap_dss_reset(); } /* autoidle */ REG_FLD_MOD(DSS_SYSCONFIG, 1, 0, 0); /* Select DPLL */ REG_FLD_MOD(DSS_CONTROL, 0, 0, 0); if (!cpu_is_omap44xx()) { r = request_irq(INT_24XX_DSS_IRQ, cpu_is_omap24xx() ? dss_irq_handler_omap2 : dss_irq_handler_omap3, 0, "OMAP DSS", NULL); } else { r = request_irq(INT_44XX_DSS_IRQ, dss_irq_handler_omap3, 0, "OMAP DSS", (void *)1); } if (r < 0) { DSSERR("omap2 dss: request_irq failed\n"); goto fail1; } if (cpu_is_omap34xx()) { dss.dpll4_m4_ck = clk_get(NULL, "dpll4_m4_ck"); if (IS_ERR(dss.dpll4_m4_ck)) { DSSERR("Failed to get dpll4_m4_ck\n"); r = PTR_ERR(dss.dpll4_m4_ck); goto fail2; } } dss_save_context(); rev = dss_read_reg(DSS_REVISION); printk(KERN_INFO "OMAP DSS rev %d.%d\n", FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); return 0; fail2: free_irq(INT_24XX_DSS_IRQ, NULL); fail1: iounmap(dss.base); fail0: return r; }
/* PLATFORM DEVICE */ static int omap_dss_probe(struct platform_device *pdev) { struct omap_dss_board_info *pdata = pdev->dev.platform_data; int skip_init = 0; int r; int i; core.pdev = pdev; dss_init_overlay_managers(pdev); dss_init_overlays(pdev); r = dss_get_clocks(); if (r) goto fail0; dss_clk_enable_all_no_ctx(); core.ctx_id = dss_get_ctx_id(); DSSDBG("initial ctx id %u\n", core.ctx_id); #ifdef CONFIG_FB_OMAP_BOOTLOADER_INIT /* DISPC_CONTROL */ if (omap_readl(0x48050440) & 1) /* LCD enabled? */ skip_init = 1; #endif r = dss_init(skip_init); if (r) { DSSERR("Failed to initialize DSS\n"); goto fail0; } #ifdef CONFIG_OMAP2_DSS_RFBI r = rfbi_init(); if (r) { DSSERR("Failed to initialize rfbi\n"); goto fail0; } #endif r = dpi_init(); if (r) { DSSERR("Failed to initialize dpi\n"); goto fail0; } r = dispc_init(); if (r) { DSSERR("Failed to initialize dispc\n"); goto fail0; } #ifdef CONFIG_OMAP2_DSS_VENC r = venc_init(pdev); if (r) { DSSERR("Failed to initialize venc\n"); goto fail0; } #endif if (cpu_is_omap34xx()) { #ifdef CONFIG_OMAP2_DSS_SDI r = sdi_init(skip_init); if (r) { DSSERR("Failed to initialize SDI\n"); goto fail0; } #endif #ifdef CONFIG_OMAP2_DSS_DSI r = dsi_init(pdev); if (r) { DSSERR("Failed to initialize DSI\n"); goto fail0; } #endif } #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) r = dss_initialize_debugfs(); if (r) goto fail0; #endif for (i = 0; i < pdata->num_devices; ++i) { struct omap_dss_device *dssdev = pdata->devices[i]; r = omap_dss_register_device(dssdev); if (r) DSSERR("device reg failed %d\n", i); if (def_disp_name && strcmp(def_disp_name, dssdev->name) == 0) pdata->default_device = dssdev; } dss_clk_disable_all(); return 0; /* XXX fail correctly */ fail0: return r; }
static u32 __init omap_usb1_init(unsigned nwires) { u32 syscon1 = 0; if (cpu_class_is_omap1() && !cpu_is_omap15xx() && nwires != 6) { u32 l; l = omap_readl(USB_TRANSCEIVER_CTRL); l &= ~CONF_USB1_UNI_R; omap_writel(l, USB_TRANSCEIVER_CTRL); } if (cpu_is_omap24xx()) omap2_usb_devconf_clear(1, USB_BIDIR_TLL); if (nwires == 0) return 0; /* external transceiver */ if (cpu_class_is_omap1()) { omap_cfg_reg(USB1_TXD); omap_cfg_reg(USB1_TXEN); if (nwires != 3) omap_cfg_reg(USB1_RCV); } if (cpu_is_omap15xx()) { omap_cfg_reg(USB1_SEO); omap_cfg_reg(USB1_SPEED); // SUSP } else if (cpu_is_omap1610() || cpu_is_omap5912()) { omap_cfg_reg(W13_1610_USB1_SE0); omap_cfg_reg(R13_1610_USB1_SPEED); // SUSP } else if (cpu_is_omap1710()) { omap_cfg_reg(R13_1710_USB1_SE0); // SUSP } else if (cpu_is_omap24xx()) { /* NOTE: board-specific code must set up pin muxing for usb1, * since each signal could come out on either of two balls. */ } else { pr_debug("usb%d cpu unrecognized\n", 1); return 0; } switch (nwires) { case 2: if (!cpu_is_omap24xx()) goto bad; /* NOTE: board-specific code must override this setting if * this TLL link is not using DP/DM */ syscon1 = 1; omap2_usb_devconf_set(1, USB_BIDIR_TLL); break; case 3: syscon1 = 2; if (cpu_is_omap24xx()) omap2_usb_devconf_set(1, USB_BIDIR); break; case 4: syscon1 = 1; if (cpu_is_omap24xx()) omap2_usb_devconf_set(1, USB_BIDIR); break; case 6: if (cpu_is_omap24xx()) goto bad; syscon1 = 3; omap_cfg_reg(USB1_VP); omap_cfg_reg(USB1_VM); if (!cpu_is_omap15xx()) { u32 l; l = omap_readl(USB_TRANSCEIVER_CTRL); l |= CONF_USB1_UNI_R; omap_writel(l, USB_TRANSCEIVER_CTRL); } break; default: bad: printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", 1, nwires); } return syscon1 << 20; }
void __init omap_otg_init(struct omap_usb_config *config) { u32 syscon; int status; int alt_pingroup = 0; /* NOTE: no bus or clock setup (yet?) */ syscon = omap_readl(OTG_SYSCON_1) & 0xffff; if (!(syscon & OTG_RESET_DONE)) pr_debug("USB resets not complete?\n"); //omap_writew(0, OTG_IRQ_EN); /* pin muxing and transceiver pinouts */ if (config->pins[0] > 2) /* alt pingroup 2 */ alt_pingroup = 1; syscon |= omap_usb0_init(config->pins[0], is_usb0_device(config)); syscon |= omap_usb1_init(config->pins[1]); syscon |= omap_usb2_init(config->pins[2], alt_pingroup); pr_debug("OTG_SYSCON_1 = %08x\n", omap_readl(OTG_SYSCON_1)); omap_writel(syscon, OTG_SYSCON_1); syscon = config->hmc_mode; syscon |= USBX_SYNCHRO | (4 << 16) /* B_ASE0_BRST */; #ifdef CONFIG_USB_OTG if (config->otg) syscon |= OTG_EN; #endif if (cpu_class_is_omap1()) pr_debug("USB_TRANSCEIVER_CTRL = %03x\n", omap_readl(USB_TRANSCEIVER_CTRL)); pr_debug("OTG_SYSCON_2 = %08x\n", omap_readl(OTG_SYSCON_2)); omap_writel(syscon, OTG_SYSCON_2); printk("USB: hmc %d", config->hmc_mode); if (!alt_pingroup) printk(", usb2 alt %d wires", config->pins[2]); else if (config->pins[0]) printk(", usb0 %d wires%s", config->pins[0], is_usb0_device(config) ? " (dev)" : ""); if (config->pins[1]) printk(", usb1 %d wires", config->pins[1]); if (!alt_pingroup && config->pins[2]) printk(", usb2 %d wires", config->pins[2]); if (config->otg) printk(", Mini-AB on usb%d", config->otg - 1); printk("\n"); if (cpu_class_is_omap1()) { u16 w; /* leave USB clocks/controllers off until needed */ w = omap_readw(ULPD_SOFT_REQ); w &= ~SOFT_USB_CLK_REQ; omap_writew(w, ULPD_SOFT_REQ); w = omap_readw(ULPD_CLOCK_CTRL); w &= ~USB_MCLK_EN; w |= DIS_USB_PVCI_CLK; omap_writew(w, ULPD_CLOCK_CTRL); } syscon = omap_readl(OTG_SYSCON_1); syscon |= HST_IDLE_EN|DEV_IDLE_EN|OTG_IDLE_EN; #ifdef CONFIG_USB_GADGET_OMAP if (config->otg || config->register_dev) { syscon &= ~DEV_IDLE_EN; udc_device.dev.platform_data = config; /* FIXME patch IRQ numbers for omap730 */ status = platform_device_register(&udc_device); if (status) pr_debug("can't register UDC device, %d\n", status); } #endif #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) if (config->otg || config->register_host) { syscon &= ~HST_IDLE_EN; ohci_device.dev.platform_data = config; if (cpu_is_omap730()) ohci_resources[1].start = INT_730_USB_HHC_1; status = platform_device_register(&ohci_device); if (status) pr_debug("can't register OHCI device, %d\n", status); } #endif #ifdef CONFIG_USB_OTG if (config->otg) { syscon &= ~OTG_IDLE_EN; otg_device.dev.platform_data = config; if (cpu_is_omap730()) otg_resources[1].start = INT_730_USB_OTG; status = platform_device_register(&otg_device); if (status) pr_debug("can't register OTG device, %d\n", status); } #endif pr_debug("OTG_SYSCON_1 = %08x\n", omap_readl(OTG_SYSCON_1)); omap_writel(syscon, OTG_SYSCON_1); status = 0; }
static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup) { u32 syscon1 = 0; if (cpu_is_omap24xx()) { omap2_usb2_disable_5pinbitll(); alt_pingroup = 0; } if (alt_pingroup || nwires == 0) return 0; if (cpu_class_is_omap1() && !cpu_is_omap15xx() && nwires != 6) { u32 l; l = omap_readl(USB_TRANSCEIVER_CTRL); l &= ~CONF_USB2_UNI_R; omap_writel(l, USB_TRANSCEIVER_CTRL); } if (cpu_is_omap15xx()) { omap_cfg_reg(USB2_TXD); omap_cfg_reg(USB2_TXEN); omap_cfg_reg(USB2_SEO); if (nwires != 3) omap_cfg_reg(USB2_RCV); } else if (cpu_is_omap16xx()) { omap_cfg_reg(V6_USB2_TXD); omap_cfg_reg(W9_USB2_TXEN); omap_cfg_reg(W5_USB2_SE0); if (nwires != 3) omap_cfg_reg(Y5_USB2_RCV); } else if (cpu_is_omap24xx()) { omap_cfg_reg(Y11_24XX_USB2_DAT); omap_cfg_reg(AA10_24XX_USB2_SE0); if (nwires > 2) omap_cfg_reg(AA12_24XX_USB2_TXEN); if (nwires > 3) omap_cfg_reg(AA6_24XX_USB2_RCV); } else { pr_debug("usb%d cpu unrecognized\n", 1); return 0; } switch (nwires) { case 2: if (!cpu_is_omap24xx()) goto bad; syscon1 = 1; omap2_usb_devconf_set(2, USB_BIDIR_TLL); break; case 3: syscon1 = 2; if (cpu_is_omap24xx()) omap2_usb_devconf_set(2, USB_BIDIR); break; case 4: syscon1 = 1; if (cpu_is_omap24xx()) omap2_usb_devconf_set(2, USB_BIDIR); break; case 5: if (!cpu_is_omap24xx()) goto bad; omap_cfg_reg(AA4_24XX_USB2_TLLSE0); syscon1 = 3; omap2_usb2_enable_5pinunitll(); break; case 6: if (cpu_is_omap24xx()) goto bad; syscon1 = 3; if (cpu_is_omap15xx()) { omap_cfg_reg(USB2_VP); omap_cfg_reg(USB2_VM); } else { u32 l; omap_cfg_reg(AA9_USB2_VP); omap_cfg_reg(R9_USB2_VM); l = omap_readl(USB_TRANSCEIVER_CTRL); l |= CONF_USB2_UNI_R; omap_writel(l, USB_TRANSCEIVER_CTRL); } break; default: bad: printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", 2, nwires); } return syscon1 << 24; }
/* * OMAP4 MPUSS Low Power Entry Function * * The purpose of this function is to manage low power programming * of OMAP4 MPUSS subsystem * Paramenters: * cpu : CPU ID * power_state: Targetted Low power state. * * MPUSS Low power states * The basic rule is that the MPUSS power domain must be at the higher or * equal power state (state that consume more power) than the higher of the * two CPUs. For example, it is illegal for system power to be OFF, while * the power of one or both of the CPU is DORMANT. When an illegal state is * entered, then the hardware behavior is unpredictable. * * MPUSS state for the context save * save_state = * 0 - Nothing lost and no need to save: MPUSS INACTIVE * 1 - CPUx L1 and logic lost: MPUSS CSWR * 2 - CPUx L1 and logic lost + GIC lost: MPUSS OSWR * 3 - CPUx L1 and logic lost + GIC + L2 lost: MPUSS OFF */ void omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) { unsigned int save_state, wakeup_cpu; if (cpu > NR_CPUS) return; /* * Low power state not supported on ES1.0 silicon */ if (omap_rev() == OMAP4430_REV_ES1_0) { wmb(); do_wfi(); return; } switch (power_state) { case PWRDM_POWER_ON: case PWRDM_POWER_INACTIVE: save_state = 0; break; case PWRDM_POWER_OFF: save_state = 1; setup_wakeup_routine(cpu); save_local_timers(cpu); break; case PWRDM_POWER_RET: /* * CPUx CSWR is invalid hardware state. Additionally * CPUx OSWR doesn't give any gain vs CPUxOFF and * hence not supported */ default: /* Invalid state */ pr_debug("Invalid CPU low power state\n"); return; } /* * MPUSS book keeping should be executed by master * CPU only which is the last CPU to go down */ if (cpu) goto cpu_prepare; /* * Check MPUSS next state and save GIC if needed * GIC lost during MPU OFF and OSWR */ pwrdm_clear_all_prev_pwrst(mpuss_pd); if (omap4_device_off_read_next_state() && (omap_type() != OMAP2_DEVICE_TYPE_GP)) { /* FIXME: Check if this can be optimised */ save_secure_all(); save_ivahd_tesla_regs(); save_l3instr_regs(); save_state = 3; goto cpu_prepare; } switch (pwrdm_read_next_pwrst(mpuss_pd)) { case PWRDM_POWER_ON: case PWRDM_POWER_INACTIVE: /* No need to save MPUSS context */ break; case PWRDM_POWER_RET: /* MPUSS OSWR, logic lost */ if (pwrdm_read_logic_retst(mpuss_pd) == PWRDM_POWER_OFF) { if (omap_type() != OMAP2_DEVICE_TYPE_GP) { save_gic_wakeupgen_secure(); save_l3instr_regs(); } else { save_gic(); omap4_wakeupgen_save(); } save_state = 2; } break; case PWRDM_POWER_OFF: /* MPUSS OFF */ if (omap_type() != OMAP2_DEVICE_TYPE_GP) { save_secure_ram(); save_gic_wakeupgen_secure(); save_ivahd_tesla_regs(); save_l3instr_regs(); } else { save_gic(); omap4_wakeupgen_save(); } save_state = 3; break; default: /* Fall through */ ; } /* * Program the CPU targeted state */ cpu_prepare: clear_cpu_prev_pwrst(cpu); if (cpu) pwrdm_set_next_pwrst(cpu1_pwrdm, power_state); else pwrdm_set_next_pwrst(cpu0_pwrdm, power_state); scu_pwrst_prepare(cpu, power_state); /* * Call low level routine to enter to * targeted power state */ __omap4_cpu_suspend(cpu, save_state); wakeup_cpu = hard_smp_processor_id(); /* * Restore the CPUx and mpuss power state to ON otherwise * CPUx power domain can transitions to programmed low power * state while doing WFI outside the low powe code. On HS devices, * CPUx can do WFI outside idle thread which can result in * power domain domain transition if the previous state was * programmed to OFF/RET. */ if (wakeup_cpu) { pwrdm_set_next_pwrst(cpu1_pwrdm, PWRDM_POWER_ON); } else { pwrdm_set_next_pwrst(cpu0_pwrdm, PWRDM_POWER_ON); pwrdm_set_next_pwrst(mpuss_pd, PWRDM_POWER_ON); } /* * Check the CPUx previous power state */ if (read_cpu_prev_pwrst(wakeup_cpu) == PWRDM_POWER_OFF) { cpu_init(); restore_mmu_table_entry(); restore_local_timers(wakeup_cpu); } /* * Check MPUSS previous power state and enable * GIC if needed. */ switch (pwrdm_read_prev_pwrst(mpuss_pd)) { case PWRDM_POWER_ON: /* No need to restore */ break; case PWRDM_POWER_RET: /* FIXME: * if (pwrdm_read_prev_logic_pwrst(mpuss_pd) == PWRDM_POWER_OFF) */ if (omap_readl(0x4a306324) == PWRDM_POWER_OFF) break; case PWRDM_POWER_OFF: /* * Enable GIC distributor */ if (!wakeup_cpu) { if ((omap_type() == OMAP2_DEVICE_TYPE_GP) && omap4_device_off_read_prev_state()) { restore_gic(); omap4_wakeupgen_restore(); } enable_gic_distributor(); if (omap_type() != OMAP2_DEVICE_TYPE_GP) { restore_ivahd_tesla_regs(); restore_l3instr_regs(); } } /* * Enable GIC cpu inrterface */ enable_gic_cpu_interface(); break; default: ; } }
static int isp1301_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget) { struct isp1301 *isp = container_of(otg, struct isp1301, otg); #ifndef CONFIG_USB_OTG u32 l; #endif if (!otg || isp != the_transceiver) return -ENODEV; if (!gadget) { omap_writew(0, OTG_IRQ_EN); if (!isp->otg.default_a) enable_vbus_draw(isp, 0); usb_gadget_vbus_disconnect(isp->otg.gadget); isp->otg.gadget = NULL; power_down(isp); return 0; } #ifdef CONFIG_USB_OTG isp->otg.gadget = gadget; dev_dbg(&isp->client->dev, "registered gadget\n"); /* gadget driver may be suspended until vbus_connect () */ if (isp->otg.host) return isp1301_otg_enable(isp); return 0; #elif !defined(CONFIG_USB_OHCI_HCD) && !defined(CONFIG_USB_OHCI_HCD_MODULE) isp->otg.gadget = gadget; // FIXME update its refcount l = omap_readl(OTG_CTRL) & OTG_CTRL_MASK; l &= ~(OTG_XCEIV_OUTPUTS|OTG_CTRL_BITS); l |= OTG_ID; omap_writel(l, OTG_CTRL); power_up(isp); isp->otg.state = OTG_STATE_B_IDLE; if (machine_is_omap_h2() || machine_is_omap_h3()) isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0); isp1301_set_bits(isp, ISP1301_INTERRUPT_RISING, INTR_SESS_VLD); isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING, INTR_VBUS_VLD); dev_info(&isp->client->dev, "B-Peripheral sessions ok\n"); dump_regs(isp, __func__); /* If this has a Mini-AB connector, this mode is highly * nonstandard ... but can be handy for testing, so long * as you don't plug a Mini-A cable into the jack. */ if (isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE) & INTR_VBUS_VLD) b_peripheral(isp); return 0; #else dev_dbg(&isp->client->dev, "peripheral sessions not allowed\n"); return -EINVAL; #endif }
static void check_state(struct isp1301 *isp, const char *tag) { enum usb_otg_state state = OTG_STATE_UNDEFINED; u8 fsm = omap_readw(OTG_TEST) & 0x0ff; unsigned extra = 0; switch (fsm) { /* default-b */ case 0x0: state = OTG_STATE_B_IDLE; break; case 0x3: case 0x7: extra = 1; case 0x1: state = OTG_STATE_B_PERIPHERAL; break; case 0x11: state = OTG_STATE_B_SRP_INIT; break; /* extra dual-role default-b states */ case 0x12: case 0x13: case 0x16: extra = 1; case 0x17: state = OTG_STATE_B_WAIT_ACON; break; case 0x34: state = OTG_STATE_B_HOST; break; /* default-a */ case 0x36: state = OTG_STATE_A_IDLE; break; case 0x3c: state = OTG_STATE_A_WAIT_VFALL; break; case 0x7d: state = OTG_STATE_A_VBUS_ERR; break; case 0x9e: case 0x9f: extra = 1; case 0x89: state = OTG_STATE_A_PERIPHERAL; break; case 0xb7: state = OTG_STATE_A_WAIT_VRISE; break; case 0xb8: state = OTG_STATE_A_WAIT_BCON; break; case 0xb9: state = OTG_STATE_A_HOST; break; case 0xba: state = OTG_STATE_A_SUSPEND; break; default: break; } if (isp->otg.state == state && !extra) return; pr_debug("otg: %s FSM %s/%02x, %s, %06x\n", tag, state_string(state), fsm, state_name(isp), omap_readl(OTG_CTRL)); }
static int omap1610_irda_startup(struct net_device *dev) { __ECHO_IN; /* Enable UART3 clock and set UART3 to IrDA mode */ omap_writel(omap_readl(MOD_CONF_CTRL_0) | (1 << 31) | (1 << 15), MOD_CONF_CTRL_0); if (machine_is_omap_h2()) { // omap_cfg_reg(Y15_1610_GPIO17); omap_writel(omap_readl(FUNC_MUX_CTRL_A) | 7, FUNC_MUX_CTRL_A); omap_set_gpio_direction(OMAP1610_H2_FIRSEL_GPIO, 0); omap_set_gpio_dataout(OMAP1610_H2_FIRSEL_GPIO, 0); } omap_writeb(0x07, UART3_MDR1); /* Put UART3 in reset mode */ /* Clear DLH and DLL */ omap_writeb(1 << 7, UART3_LCR); omap_writeb(0, UART3_DLL); omap_writeb(0, UART3_DLH); omap_writeb(0xbf, UART3_LCR); omap_writeb(1 << 4, UART3_EFR); omap_writeb(1 << 7, UART3_LCR); /* Enable access to UART3_TLR and UART3_TCR registers */ omap_writeb(1 << 6, UART3_MCR); omap_writeb(0, UART3_SCR); /* Set Rx trigger to 1 and Tx trigger to 1 */ omap_writeb(0, UART3_TLR); /* Set LCR to 8 bits and 1 stop bit */ omap_writeb(0x03, UART3_LCR); /* Clear RX and TX FIFO and enable FIFO */ /* Use DMA Req for transfers */ omap_writeb((1 << 2) | (1 << 1) | (1 << 3) | (1 << 4) | (1 << 6) | 1, UART3_FCR); omap_writeb(0, UART3_MCR); omap_writeb((1 << 7) | (1 << 6), UART3_SCR); /* Enable UART3 SIR Mode,(Frame-length method to end frames) */ omap_writeb(1, UART3_MDR1); /* Set Status FIFO trig to 1 */ omap_writeb(0, UART3_MDR2); /* Enables RXIR input */ /* and disable TX underrun */ /* SEND_SIP pulse */ // omap_writeb((1 << 7) | (1 << 6) | (1 << 4), UART3_ACREG); omap_writeb((1 << 6) | (1 << 4), UART3_ACREG); /* Enable EOF Interrupt only */ omap_writeb((1 << 7) | (1 << 5), UART3_IER); /* Set Maximum Received Frame size to 2048 bytes */ omap_writeb(0x00, UART3_RXFLL); omap_writeb(0x08, UART3_RXFLH); omap_readb(UART3_RESUME); __ECHO_OUT; return 0; }
static void isp1301_work(struct work_struct *work) { struct isp1301 *isp = container_of(work, struct isp1301, work); int stop; /* implicit lock: we're the only task using this device */ isp->working = 1; do { stop = test_bit(WORK_STOP, &isp->todo); #ifdef CONFIG_USB_OTG /* transfer state from otg engine to isp1301 */ if (test_and_clear_bit(WORK_UPDATE_ISP, &isp->todo)) { otg_update_isp(isp); put_device(&isp->client->dev); } #endif /* transfer state from isp1301 to otg engine */ if (test_and_clear_bit(WORK_UPDATE_OTG, &isp->todo)) { u8 stat = isp1301_clear_latch(isp); isp_update_otg(isp, stat); put_device(&isp->client->dev); } if (test_and_clear_bit(WORK_HOST_RESUME, &isp->todo)) { u32 otg_ctrl; /* * skip A_WAIT_VRISE; hc transitions invisibly * skip A_WAIT_BCON; same. */ switch (isp->otg.state) { case OTG_STATE_A_WAIT_BCON: case OTG_STATE_A_WAIT_VRISE: isp->otg.state = OTG_STATE_A_HOST; pr_debug(" --> a_host\n"); otg_ctrl = omap_readl(OTG_CTRL); otg_ctrl |= OTG_A_BUSREQ; otg_ctrl &= ~(OTG_BUSDROP|OTG_B_BUSREQ) & OTG_CTRL_MASK; omap_writel(otg_ctrl, OTG_CTRL); break; case OTG_STATE_B_WAIT_ACON: isp->otg.state = OTG_STATE_B_HOST; pr_debug(" --> b_host (acon)\n"); break; case OTG_STATE_B_HOST: case OTG_STATE_B_IDLE: case OTG_STATE_A_IDLE: break; default: pr_debug(" host resume in %s\n", state_name(isp)); } host_resume(isp); // mdelay(10); put_device(&isp->client->dev); } if (test_and_clear_bit(WORK_TIMER, &isp->todo)) { #ifdef VERBOSE dump_regs(isp, "timer"); if (!stop) mod_timer(&isp->timer, jiffies + TIMER_JIFFIES); #endif put_device(&isp->client->dev); } if (isp->todo) dev_vdbg(&isp->client->dev, "work done, todo = 0x%lx\n", isp->todo); if (stop) { dev_dbg(&isp->client->dev, "stop\n"); break; } } while (isp->todo); isp->working = 0; }
static u32 omap2_read_32k_sync_counter(void) { return omap_readl(OMAP2_32KSYNCT_BASE + 0x0010); }
static int omap3_enter_idle(struct cpuidle_device *dev, struct cpuidle_state *state) { struct omap3_processor_cx *cx; u8 cur_per_state, cur_neon_state, pre_neon_state, pre_per_state; struct timespec ts_preidle, ts_postidle, ts_idle; u32 fclken_core, iclken_core, fclken_per, iclken_per; u32 sdrcpwr_val, sdrc_power_register = 0x0; int wakeup_latency; int core_sleep_flg = 0; u32 per_ctx_saved = 0; int ret = -1; #ifdef CONFIG_ENABLE_SWLATENCY_MEASURE int idle_status = 0; #endif local_irq_disable(); local_fiq_disable(); if (need_resched()) { local_irq_enable(); local_fiq_enable(); return 0; } #ifdef CONFIG_ENABLE_SWLATENCY_MEASURE sw_latency_arr[swlat_arr_wrptr].sleep_start = omap_32k_sync_timer_read(); #endif PM_PREPWSTST_MPU = 0xFF; PM_PREPWSTST_CORE = 0xFF; PM_PREPWSTST_NEON = 0xFF; PM_PREPWSTST_PER = 0xFF; cx = cpuidle_get_statedata(state); target_state.mpu_state = cx->mpu_state; target_state.core_state = cx->core_state; /* take a time marker for residency */ getnstimeofday(&ts_preidle); if (cx->type == OMAP3_STATE_C0) { omap_sram_idle(); goto return_sleep_time; } if (cx->type > OMAP3_STATE_C1) sched_clock_idle_sleep_event(); /* about to enter deep idle */ correct_target_state(); wakeup_latency = cx->wakeup_latency; if (target_state.core_state != cx->core_state) { /* Currently, this can happen only for core_off */ /* Adjust wakeup latency to that of core_cswr state */ /* Hard coded now and needs to be made more generic */ /* omap3_power_states[4] is CSWR for core */ wakeup_latency = omap3_power_states[4].wakeup_latency; } /* Reprogram next wake up tick to adjust for wake latency */ if (wakeup_latency > 1000) { struct tick_device *d = tick_get_device(smp_processor_id()); ktime_t adjust, next, now = ktime_get(); if (ktime_to_ns(ktime_sub(d->evtdev->next_event, now)) > (wakeup_latency * 1000 + NSEC_PER_MSEC)) { adjust = ktime_set(0, (wakeup_latency * 1000)); next = ktime_sub(d->evtdev->next_event, adjust); clockevents_program_event(d->evtdev, next, now); } } /* Check for pending interrupts. If there is an interrupt, return */ if (INTCPS_PENDING_IRQ0 | INTCPS_PENDING_IRQ1 | INTCPS_PENDING_IRQ2) goto return_sleep_time; prcm_get_power_domain_state(DOM_PER, &cur_per_state); prcm_get_power_domain_state(DOM_NEON, &cur_neon_state); fclken_core = CM_FCLKEN1_CORE; iclken_core = CM_ICLKEN1_CORE; fclken_per = CM_FCLKEN_PER; iclken_per = CM_ICLKEN_PER; /* If target state if core_off, save registers * before changing anything */ if (target_state.core_state >= PRCM_CORE_OSWR_MEMRET) { prcm_save_registers(&target_state); omap_uart_save_ctx(0); omap_uart_save_ctx(1); } /* Check for pending interrupts. If there is an interrupt, return */ if (INTCPS_PENDING_IRQ0 | INTCPS_PENDING_IRQ1 | INTCPS_PENDING_IRQ2) goto return_sleep_time; /* Program MPU and NEON to target state */ if (target_state.mpu_state > PRCM_MPU_ACTIVE) { if ((cur_neon_state == PRCM_ON) && (target_state.neon_state != PRCM_ON)) { if (target_state.neon_state == PRCM_OFF) omap3_save_neon_context(); #ifdef CONFIG_HW_SUP_TRANS /* Facilitating SWSUP RET, from HWSUP mode */ prcm_set_clock_domain_state(DOM_NEON, PRCM_NO_AUTO, PRCM_FALSE); prcm_set_power_domain_state(DOM_NEON, PRCM_ON, PRCM_FORCE); #endif prcm_force_power_domain_state(DOM_NEON, target_state.neon_state); } #ifdef CONFIG_MPU_OFF /* Populate scrathpad restore address */ *(scratchpad_restore_addr) = restore_pointer_address; #endif if (target_state.core_state > PRCM_CORE_CSWR_MEMRET) { ret = omap3_save_secure_ram_context( target_state.core_state); if (ret) printk(KERN_ERR "omap3_save_secure_ram_context" "failed in idle %x\n", ret); if (core_off_notification != NULL) core_off_notification(PRCM_TRUE); } prcm_set_mpu_domain_state(target_state.mpu_state); } /* Check for pending interrupts. If there is an interrupt, return */ if (INTCPS_PENDING_IRQ0 | INTCPS_PENDING_IRQ1 | INTCPS_PENDING_IRQ2) goto restore; /* Program CORE and PER to target state */ if (target_state.core_state > PRCM_CORE_ACTIVE) { /* Log core sleep attmept */ core_sleep_flg = 1; #ifdef CONFIG_OMAP_SMARTREFLEX disable_smartreflex(SR1_ID); disable_smartreflex(SR2_ID); #endif /* Workaround for Silicon Errata 1.64 */ if (is_sil_rev_equal_to(OMAP3430_REV_ES1_0)) { if (CM_CLKOUT_CTRL & 0x80) CM_CLKOUT_CTRL &= ~(0x80); } prcm_set_core_domain_state(target_state.core_state); /* Enable Autoidle for GPT1 explicitly - Errata 1.4 */ CM_AUTOIDLE_WKUP |= 0x1; /* Disable UART-1,2 */ CM_FCLKEN1_CORE &= ~0x6000; /* Disable HSUSB OTG ICLK explicitly*/ CM_ICLKEN1_CORE &= ~0x10; /* Enabling IO_PAD capabilities */ PM_WKEN_WKUP |= 0x100; if (cur_per_state == PRCM_ON && cx->type >= OMAP3_STATE_C3 && !(CM_FCLKEN_PER & PER_FCLK_MASK)) { /* In ES3.1, Enable IO Daisy chain */ if (is_sil_rev_greater_than(OMAP3430_REV_ES3_0)) { PM_WKEN_WKUP |= 0x10000; /* Wait for daisy chain to be ready */ while ((PM_WKST_WKUP & 0x10000) == 0x0) ; /* clear the status */ PM_WKST_WKUP &= ~0x10000; } omap3_save_per_context(); prcm_set_power_domain_state(DOM_PER, PRCM_OFF, PRCM_AUTO); per_ctx_saved = 1; CM_FCLKEN_PER = 0; CM_ICLKEN_PER = 0; } } /* Check for pending interrupts. If there is an interrupt, return */ if (INTCPS_PENDING_IRQ0 | INTCPS_PENDING_IRQ1 | INTCPS_PENDING_IRQ2) goto restore; if (target_state.core_state == PRCM_CORE_OFF) { if (!is_device_type_gp() && is_sil_rev_greater_than(OMAP3430_REV_ES2_1)) { /* es3 series bug */ sdrc_power_register = sdrc_read_reg(SDRC_POWER); sdrcpwr_val = sdrc_power_register & ~(SDRC_PWR_AUTOCOUNT_MASK | SDRC_PWR_CLKCTRL_MASK); lock_scratchpad_sem(); sdrcpwr_val |= 0x120; save_to_scratchpad(SCRATHPAD_SDRCPWR_OFFSET, sdrcpwr_val); unlock_scratchpad_sem(); } } #ifdef CONFIG_ENABLE_SWLATENCY_MEASURE sw_latency_arr[swlat_arr_wrptr].sleep_end = omap_32k_sync_timer_read(); idle_status++; #endif omap_sram_idle(); if (target_state.core_state == PRCM_CORE_OFF) { if (!is_device_type_gp() && is_sil_rev_greater_than(OMAP3430_REV_ES2_1)) sdrc_write_reg(sdrc_power_register, SDRC_POWER); } restore: /* In case of ES3.1, disable IO daisy chain */ if (is_sil_rev_greater_than(OMAP3430_REV_ES3_0) && per_ctx_saved) PM_WKEN_WKUP &= ~(0x10000); /* Disabling IO_PAD capabilities */ if (core_sleep_flg) PM_WKEN_WKUP &= ~(0x100); /* Disabling IO_PAD capabilities */ PM_WKEN_WKUP &= ~(0x100); #ifdef OMAP3_START_RNG /*Capture the PM_PREPWSTST_CORE to be used later * for starting the RNG (Random Number Generator)*/ prepwst_core_rng = PM_PREPWSTST_CORE; #endif CM_FCLKEN1_CORE = fclken_core; CM_ICLKEN1_CORE = iclken_core; if (target_state.mpu_state > PRCM_MPU_ACTIVE) { #ifdef CONFIG_MPU_OFF /* On ES 2.0, if scrathpad is populated with valid * pointer, warm reset does not work * So populate scrathpad restore address only in * cpuidle and suspend calls */ *(scratchpad_restore_addr) = 0x0; #endif prcm_set_mpu_domain_state(PRCM_MPU_ACTIVE); if ((cur_neon_state == PRCM_ON) && (target_state.mpu_state > PRCM_MPU_INACTIVE)) { prcm_force_power_domain_state(DOM_NEON, cur_neon_state); prcm_get_pre_power_domain_state(DOM_NEON, &pre_neon_state); if (pre_neon_state == PRCM_OFF) omap3_restore_neon_context(); #ifdef CONFIG_HW_SUP_TRANS prcm_set_power_domain_state(DOM_NEON, PRCM_ON, PRCM_AUTO); #endif } } /* Continue core restoration part, only if Core-Sleep is attempted */ if ((target_state.core_state > PRCM_CORE_ACTIVE) && core_sleep_flg) { prcm_set_core_domain_state(PRCM_CORE_ACTIVE); #ifdef CONFIG_OMAP_SMARTREFLEX enable_smartreflex(SR1_ID); enable_smartreflex(SR2_ID); #endif if (target_state.core_state >= PRCM_CORE_OSWR_MEMRET) { #ifdef CONFIG_OMAP34XX_OFFMODE context_restore_update(DOM_CORE1); #endif prcm_restore_registers(&target_state); prcm_restore_core_context(target_state.core_state); omap3_restore_core_settings(); } /* Errata 1.4 * if the timer device gets idled which is when we * are cutting the timer ICLK which is when we try * to put Core to RET. * Wait Period = 2 timer interface clock cycles + * 1 timer functional clock cycle * Interface clock = L4 clock. For the computation L4 * clock is assumed at 50MHz (worst case). * Functional clock = 32KHz * Wait Period = 2*10^-6/50 + 1/32768 = 0.000030557 = 30.557uSec * Roundingoff the delay value to a safer 50uSec */ omap_udelay(GPTIMER_WAIT_DELAY); CM_AUTOIDLE_WKUP &= ~(0x1); if (core_off_notification != NULL) core_off_notification(PRCM_FALSE); } if (cur_per_state == PRCM_ON) { CM_FCLKEN_PER = fclken_per; CM_ICLKEN_PER = iclken_per; prcm_get_pre_power_domain_state(DOM_PER, &pre_per_state); if (pre_per_state == PRCM_OFF && per_ctx_saved) { if (enable_debug) per_off++; omap3_restore_per_context(); post_uart_inactivity(); #ifdef CONFIG_OMAP34XX_OFFMODE context_restore_update(DOM_PER); #endif } } pr_debug("MPU state:%x,CORE state:%x\n", PM_PREPWSTST_MPU, PM_PREPWSTST_CORE); store_prepwst(); return_sleep_time: getnstimeofday(&ts_postidle); ts_idle = timespec_sub(ts_postidle, ts_preidle); if (cx->type > OMAP3_STATE_C1) sched_clock_idle_wakeup_event(timespec_to_ns(&ts_idle)); #ifdef CONFIG_ENABLE_SWLATENCY_MEASURE if (idle_status) { sw_latency_arr[swlat_arr_wrptr].wkup_end = omap_32k_sync_timer_read(); sw_latency_arr[swlat_arr_wrptr].wkup_start = wakeup_start_32ksync; sw_latency_arr[swlat_arr_wrptr].cstate = ((PM_PREPWSTST_MPU & 0x3) << 2) | (PM_PREPWSTST_CORE & 0x3) | (omap_readl(0x48306CB0) << 16); swlat_arr_wrptr++; if (swlat_arr_wrptr == SW_LATENCY_ARR_SIZE) swlat_arr_wrptr = 0; } #endif local_irq_enable(); local_fiq_enable(); #ifdef OMAP3_START_RNG if (!is_device_type_gp()) { /*Start RNG after interrupts are enabled * and only when CORE OFF was successful */ if (!(prepwst_core_rng & 0x3)) { ret = omap3_start_rng(); if (ret) printk(KERN_INFO"Failed to generate new" " RN in idle %x\n", ret); prepwst_core_rng = 0xFF; } } #endif return (u32)timespec_to_ns(&ts_idle)/1000; }
static void __init omap_perseus2_init(void) { /* Early, board-dependent init */ /* * Hold GSM Reset until needed */ omap_writew(omap_readw(OMAP7XX_DSP_M_CTL) & ~1, OMAP7XX_DSP_M_CTL); /* * UARTs -> done automagically by 8250 driver */ /* * CSx timings, GPIO Mux ... setup */ /* Flash: CS0 timings setup */ omap_writel(0x0000fff3, OMAP7XX_FLASH_CFG_0); omap_writel(0x00000088, OMAP7XX_FLASH_ACFG_0); /* * Ethernet support through the debug board * CS1 timings setup */ omap_writel(0x0000fff3, OMAP7XX_FLASH_CFG_1); omap_writel(0x00000000, OMAP7XX_FLASH_ACFG_1); /* * Configure MPU_EXT_NIRQ IO in IO_CONF9 register, * It is used as the Ethernet controller interrupt */ omap_writel(omap_readl(OMAP7XX_IO_CONF_9) & 0x1FFFFFFF, OMAP7XX_IO_CONF_9); perseus2_init_smc91x(); if (gpio_request(P2_NAND_RB_GPIO_PIN, "NAND ready") < 0) BUG(); gpio_direction_input(P2_NAND_RB_GPIO_PIN); omap_cfg_reg(L3_1610_FLASH_CS2B_OE); omap_cfg_reg(M8_1610_FLASH_CS2B_WE); /* Mux pins for keypad */ omap_cfg_reg(E2_7XX_KBR0); omap_cfg_reg(J7_7XX_KBR1); omap_cfg_reg(E1_7XX_KBR2); omap_cfg_reg(F3_7XX_KBR3); omap_cfg_reg(D2_7XX_KBR4); omap_cfg_reg(C2_7XX_KBC0); omap_cfg_reg(D3_7XX_KBC1); omap_cfg_reg(E4_7XX_KBC2); omap_cfg_reg(F4_7XX_KBC3); omap_cfg_reg(E3_7XX_KBC4); platform_add_devices(devices, ARRAY_SIZE(devices)); omap_board_config = perseus2_config; omap_board_config_size = ARRAY_SIZE(perseus2_config); omap_serial_init(); omap_register_i2c_bus(1, 100, NULL, 0); }
/** * hp3a_disable_histogram - Disables histogram harware. * * No return value. **/ void hp3a_disable_histogram(void) { g_tc.hist_hw_enable = 0; omap_writel(omap_readl(ISPHIST_PCR) & ~(ISPHIST_PCR_EN), ISPHIST_PCR); }
/* inputs going to ISP1301 */ static void otg_update_isp(struct isp1301 *isp) { u32 otg_ctrl, otg_change; u8 set = OTG1_DM_PULLDOWN, clr = OTG1_DM_PULLUP; otg_ctrl = omap_readl(OTG_CTRL); otg_change = otg_ctrl ^ isp->last_otg_ctrl; isp->last_otg_ctrl = otg_ctrl; otg_ctrl = otg_ctrl & OTG_XCEIV_INPUTS; switch (isp->otg.state) { case OTG_STATE_B_IDLE: case OTG_STATE_B_PERIPHERAL: case OTG_STATE_B_SRP_INIT: if (!(otg_ctrl & OTG_PULLUP)) { // if (otg_ctrl & OTG_B_HNPEN) { if (isp->otg.gadget->b_hnp_enable) { isp->otg.state = OTG_STATE_B_WAIT_ACON; pr_debug(" --> b_wait_acon\n"); } goto pulldown; } pullup: set |= OTG1_DP_PULLUP; clr |= OTG1_DP_PULLDOWN; break; case OTG_STATE_A_SUSPEND: case OTG_STATE_A_PERIPHERAL: if (otg_ctrl & OTG_PULLUP) goto pullup; /* FALLTHROUGH */ // case OTG_STATE_B_WAIT_ACON: default: pulldown: set |= OTG1_DP_PULLDOWN; clr |= OTG1_DP_PULLUP; break; } # define toggle(OTG,ISP) do { \ if (otg_ctrl & OTG) set |= ISP; \ else clr |= ISP; \ } while (0) if (!(isp->otg.host)) otg_ctrl &= ~OTG_DRV_VBUS; switch (isp->otg.state) { case OTG_STATE_A_SUSPEND: if (otg_ctrl & OTG_DRV_VBUS) { set |= OTG1_VBUS_DRV; break; } /* HNP failed for some reason (A_AIDL_BDIS timeout) */ notresponding(isp); /* FALLTHROUGH */ case OTG_STATE_A_VBUS_ERR: isp->otg.state = OTG_STATE_A_WAIT_VFALL; pr_debug(" --> a_wait_vfall\n"); /* FALLTHROUGH */ case OTG_STATE_A_WAIT_VFALL: /* FIXME usbcore thinks port power is still on ... */ clr |= OTG1_VBUS_DRV; break; case OTG_STATE_A_IDLE: if (otg_ctrl & OTG_DRV_VBUS) { isp->otg.state = OTG_STATE_A_WAIT_VRISE; pr_debug(" --> a_wait_vrise\n"); } /* FALLTHROUGH */ default: toggle(OTG_DRV_VBUS, OTG1_VBUS_DRV); } toggle(OTG_PU_VBUS, OTG1_VBUS_CHRG); toggle(OTG_PD_VBUS, OTG1_VBUS_DISCHRG); # undef toggle isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, set); isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, clr); /* HNP switch to host or peripheral; and SRP */ if (otg_change & OTG_PULLUP) { u32 l; switch (isp->otg.state) { case OTG_STATE_B_IDLE: if (clr & OTG1_DP_PULLUP) break; isp->otg.state = OTG_STATE_B_PERIPHERAL; pr_debug(" --> b_peripheral\n"); break; case OTG_STATE_A_SUSPEND: if (clr & OTG1_DP_PULLUP) break; isp->otg.state = OTG_STATE_A_PERIPHERAL; pr_debug(" --> a_peripheral\n"); break; default: break; } l = omap_readl(OTG_CTRL); l |= OTG_PULLUP; omap_writel(l, OTG_CTRL); } check_state(isp, __func__); dump_regs(isp, "otg->isp1301"); }
static u32 __init omap_usb1_init(unsigned nwires) { u32 syscon1 = 0; if (cpu_class_is_omap1() && !cpu_is_omap15xx() && nwires != 6) { u32 l; l = omap_readl(USB_TRANSCEIVER_CTRL); l &= ~CONF_USB1_UNI_R; omap_writel(l, USB_TRANSCEIVER_CTRL); } if (cpu_is_omap24xx()) omap2_usb_devconf_clear(1, USB_BIDIR_TLL); if (nwires == 0) return 0; if (cpu_class_is_omap1()) { omap_cfg_reg(USB1_TXD); omap_cfg_reg(USB1_TXEN); if (nwires != 3) omap_cfg_reg(USB1_RCV); } if (cpu_is_omap15xx()) { omap_cfg_reg(USB1_SEO); omap_cfg_reg(USB1_SPEED); } else if (cpu_is_omap1610() || cpu_is_omap5912()) { omap_cfg_reg(W13_1610_USB1_SE0); omap_cfg_reg(R13_1610_USB1_SPEED); } else if (cpu_is_omap1710()) { omap_cfg_reg(R13_1710_USB1_SE0); } else if (cpu_is_omap24xx()) { } else { pr_debug("usb%d cpu unrecognized\n", 1); return 0; } switch (nwires) { case 2: if (!cpu_is_omap24xx()) goto bad; syscon1 = 1; omap2_usb_devconf_set(1, USB_BIDIR_TLL); break; case 3: syscon1 = 2; if (cpu_is_omap24xx()) omap2_usb_devconf_set(1, USB_BIDIR); break; case 4: syscon1 = 1; if (cpu_is_omap24xx()) omap2_usb_devconf_set(1, USB_BIDIR); break; case 6: if (cpu_is_omap24xx()) goto bad; syscon1 = 3; omap_cfg_reg(USB1_VP); omap_cfg_reg(USB1_VM); if (!cpu_is_omap15xx()) { u32 l; l = omap_readl(USB_TRANSCEIVER_CTRL); l |= CONF_USB1_UNI_R; omap_writel(l, USB_TRANSCEIVER_CTRL); } break; default: bad: printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", 1, nwires); } return syscon1 << 20; }
static irqreturn_t omap_otg_irq(int irq, void *_isp) { u16 otg_irq = omap_readw(OTG_IRQ_SRC); u32 otg_ctrl; int ret = IRQ_NONE; struct isp1301 *isp = _isp; /* update ISP1301 transciever from OTG controller */ if (otg_irq & OPRT_CHG) { omap_writew(OPRT_CHG, OTG_IRQ_SRC); isp1301_defer_work(isp, WORK_UPDATE_ISP); ret = IRQ_HANDLED; /* SRP to become b_peripheral failed */ } else if (otg_irq & B_SRP_TMROUT) { pr_debug("otg: B_SRP_TIMEOUT, %06x\n", omap_readl(OTG_CTRL)); notresponding(isp); /* gadget drivers that care should monitor all kinds of * remote wakeup (SRP, normal) using their own timer * to give "check cable and A-device" messages. */ if (isp->otg.state == OTG_STATE_B_SRP_INIT) b_idle(isp, "srp_timeout"); omap_writew(B_SRP_TMROUT, OTG_IRQ_SRC); ret = IRQ_HANDLED; /* HNP to become b_host failed */ } else if (otg_irq & B_HNP_FAIL) { pr_debug("otg: %s B_HNP_FAIL, %06x\n", state_name(isp), omap_readl(OTG_CTRL)); notresponding(isp); otg_ctrl = omap_readl(OTG_CTRL); otg_ctrl |= OTG_BUSDROP; otg_ctrl &= OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS; omap_writel(otg_ctrl, OTG_CTRL); /* subset of b_peripheral()... */ isp->otg.state = OTG_STATE_B_PERIPHERAL; pr_debug(" --> b_peripheral\n"); omap_writew(B_HNP_FAIL, OTG_IRQ_SRC); ret = IRQ_HANDLED; /* detect SRP from B-device ... */ } else if (otg_irq & A_SRP_DETECT) { pr_debug("otg: %s SRP_DETECT, %06x\n", state_name(isp), omap_readl(OTG_CTRL)); isp1301_defer_work(isp, WORK_UPDATE_OTG); switch (isp->otg.state) { case OTG_STATE_A_IDLE: if (!isp->otg.host) break; isp1301_defer_work(isp, WORK_HOST_RESUME); otg_ctrl = omap_readl(OTG_CTRL); otg_ctrl |= OTG_A_BUSREQ; otg_ctrl &= ~(OTG_BUSDROP|OTG_B_BUSREQ) & ~OTG_XCEIV_INPUTS & OTG_CTRL_MASK; omap_writel(otg_ctrl, OTG_CTRL); break; default: break; } omap_writew(A_SRP_DETECT, OTG_IRQ_SRC); ret = IRQ_HANDLED; /* timer expired: T(a_wait_bcon) and maybe T(a_wait_vrise) * we don't track them separately */ } else if (otg_irq & A_REQ_TMROUT) { otg_ctrl = omap_readl(OTG_CTRL); pr_info("otg: BCON_TMOUT from %s, %06x\n", state_name(isp), otg_ctrl); notresponding(isp); otg_ctrl |= OTG_BUSDROP; otg_ctrl &= ~OTG_A_BUSREQ & OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS; omap_writel(otg_ctrl, OTG_CTRL); isp->otg.state = OTG_STATE_A_WAIT_VFALL; omap_writew(A_REQ_TMROUT, OTG_IRQ_SRC); ret = IRQ_HANDLED; /* A-supplied voltage fell too low; overcurrent */ } else if (otg_irq & A_VBUS_ERR) { otg_ctrl = omap_readl(OTG_CTRL); printk(KERN_ERR "otg: %s, VBUS_ERR %04x ctrl %06x\n", state_name(isp), otg_irq, otg_ctrl); otg_ctrl |= OTG_BUSDROP; otg_ctrl &= ~OTG_A_BUSREQ & OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS; omap_writel(otg_ctrl, OTG_CTRL); isp->otg.state = OTG_STATE_A_VBUS_ERR; omap_writew(A_VBUS_ERR, OTG_IRQ_SRC); ret = IRQ_HANDLED; /* switch driver; the transciever code activates it, * ungating the udc clock or resuming OHCI. */ } else if (otg_irq & DRIVER_SWITCH) { int kick = 0; otg_ctrl = omap_readl(OTG_CTRL); printk(KERN_NOTICE "otg: %s, SWITCH to %s, ctrl %06x\n", state_name(isp), (otg_ctrl & OTG_DRIVER_SEL) ? "gadget" : "host", otg_ctrl); isp1301_defer_work(isp, WORK_UPDATE_ISP); /* role is peripheral */ if (otg_ctrl & OTG_DRIVER_SEL) { switch (isp->otg.state) { case OTG_STATE_A_IDLE: b_idle(isp, __func__); break; default: break; } isp1301_defer_work(isp, WORK_UPDATE_ISP); /* role is host */ } else { if (!(otg_ctrl & OTG_ID)) { otg_ctrl &= OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS; omap_writel(otg_ctrl | OTG_A_BUSREQ, OTG_CTRL); } if (isp->otg.host) { switch (isp->otg.state) { case OTG_STATE_B_WAIT_ACON: isp->otg.state = OTG_STATE_B_HOST; pr_debug(" --> b_host\n"); kick = 1; break; case OTG_STATE_A_WAIT_BCON: isp->otg.state = OTG_STATE_A_HOST; pr_debug(" --> a_host\n"); break; case OTG_STATE_A_PERIPHERAL: isp->otg.state = OTG_STATE_A_WAIT_BCON; pr_debug(" --> a_wait_bcon\n"); break; default: break; } isp1301_defer_work(isp, WORK_HOST_RESUME); } } omap_writew(DRIVER_SWITCH, OTG_IRQ_SRC); ret = IRQ_HANDLED; if (kick) usb_bus_start_enum(isp->otg.host, isp->otg.host->otg_port); } check_state(isp, __func__); return ret; }
static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device) { u32 syscon1 = 0; if (cpu_is_omap24xx()) omap2_usb_devconf_clear(0, USB_BIDIR_TLL); if (nwires == 0) { if (cpu_class_is_omap1() && !cpu_is_omap15xx()) { u32 l; l = omap_readl(USB_TRANSCEIVER_CTRL); l &= ~(3 << 1); omap_writel(l, USB_TRANSCEIVER_CTRL); } return 0; } if (is_device) { if (cpu_is_omap24xx()) omap_cfg_reg(J20_24XX_USB0_PUEN); else omap_cfg_reg(W4_USB_PUEN); } if (!cpu_class_is_omap2() && nwires == 2) { u32 l; if (cpu_is_omap15xx()) { return 0; } l = omap_readl(USB_TRANSCEIVER_CTRL); l &= ~(7 << 4); if (!is_device) l |= (3 << 1); omap_writel(l, USB_TRANSCEIVER_CTRL); return 3 << 16; } if (cpu_is_omap15xx()) { printk(KERN_ERR "no usb0 alt pin config on 15xx\n"); return 0; } if (cpu_is_omap24xx()) { omap_cfg_reg(K18_24XX_USB0_DAT); omap_cfg_reg(K19_24XX_USB0_TXEN); omap_cfg_reg(J14_24XX_USB0_SE0); if (nwires != 3) omap_cfg_reg(J18_24XX_USB0_RCV); } else { omap_cfg_reg(V6_USB0_TXD); omap_cfg_reg(W9_USB0_TXEN); omap_cfg_reg(W5_USB0_SE0); if (nwires != 3) omap_cfg_reg(Y5_USB0_RCV); } if (cpu_class_is_omap1() && nwires != 6) { u32 l; l = omap_readl(USB_TRANSCEIVER_CTRL); l &= ~CONF_USB2_UNI_R; omap_writel(l, USB_TRANSCEIVER_CTRL); } switch (nwires) { case 3: syscon1 = 2; if (cpu_is_omap24xx()) omap2_usb_devconf_set(0, USB_BIDIR); break; case 4: syscon1 = 1; if (cpu_is_omap24xx()) omap2_usb_devconf_set(0, USB_BIDIR); break; case 6: syscon1 = 3; if (cpu_is_omap24xx()) { omap_cfg_reg(J19_24XX_USB0_VP); omap_cfg_reg(K20_24XX_USB0_VM); omap2_usb_devconf_set(0, USB_UNIDIR); } else { u32 l; omap_cfg_reg(AA9_USB0_VP); omap_cfg_reg(R9_USB0_VM); l = omap_readl(USB_TRANSCEIVER_CTRL); l |= CONF_USB2_UNI_R; omap_writel(l, USB_TRANSCEIVER_CTRL); } break; default: printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", 0, nwires); } return syscon1 << 16; }
static void isp_update_otg(struct isp1301 *isp, u8 stat) { u8 isp_stat, isp_bstat; enum usb_otg_state state = isp->otg.state; if (stat & INTR_BDIS_ACON) pr_debug("OTG: BDIS_ACON, %s\n", state_name(isp)); /* start certain state transitions right away */ isp_stat = isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE); if (isp_stat & INTR_ID_GND) { if (isp->otg.default_a) { switch (state) { case OTG_STATE_B_IDLE: a_idle(isp, "idle"); /* FALLTHROUGH */ case OTG_STATE_A_IDLE: enable_vbus_source(isp); /* FALLTHROUGH */ case OTG_STATE_A_WAIT_VRISE: /* we skip over OTG_STATE_A_WAIT_BCON, since * the HC will transition to A_HOST (or * A_SUSPEND!) without our noticing except * when HNP is used. */ if (isp_stat & INTR_VBUS_VLD) isp->otg.state = OTG_STATE_A_HOST; break; case OTG_STATE_A_WAIT_VFALL: if (!(isp_stat & INTR_SESS_VLD)) a_idle(isp, "vfell"); break; default: if (!(isp_stat & INTR_VBUS_VLD)) isp->otg.state = OTG_STATE_A_VBUS_ERR; break; } isp_bstat = isp1301_get_u8(isp, ISP1301_OTG_STATUS); } else { switch (state) { case OTG_STATE_B_PERIPHERAL: case OTG_STATE_B_HOST: case OTG_STATE_B_WAIT_ACON: usb_gadget_vbus_disconnect(isp->otg.gadget); break; default: break; } if (state != OTG_STATE_A_IDLE) a_idle(isp, "id"); if (isp->otg.host && state == OTG_STATE_A_IDLE) isp1301_defer_work(isp, WORK_HOST_RESUME); isp_bstat = 0; } } else { u32 l; /* if user unplugged mini-A end of cable, * don't bypass A_WAIT_VFALL. */ if (isp->otg.default_a) { switch (state) { default: isp->otg.state = OTG_STATE_A_WAIT_VFALL; break; case OTG_STATE_A_WAIT_VFALL: state = OTG_STATE_A_IDLE; /* khubd may take a while to notice and * handle this disconnect, so don't go * to B_IDLE quite yet. */ break; case OTG_STATE_A_IDLE: host_suspend(isp); isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_BDIS_ACON_EN); isp->otg.state = OTG_STATE_B_IDLE; l = omap_readl(OTG_CTRL) & OTG_CTRL_MASK; l &= ~OTG_CTRL_BITS; omap_writel(l, OTG_CTRL); break; case OTG_STATE_B_IDLE: break; } } isp_bstat = isp1301_get_u8(isp, ISP1301_OTG_STATUS); switch (isp->otg.state) { case OTG_STATE_B_PERIPHERAL: case OTG_STATE_B_WAIT_ACON: case OTG_STATE_B_HOST: if (likely(isp_bstat & OTG_B_SESS_VLD)) break; enable_vbus_draw(isp, 0); #ifndef CONFIG_USB_OTG /* UDC driver will clear OTG_BSESSVLD */ isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_DP_PULLDOWN); isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_DP_PULLUP); dump_regs(isp, __func__); #endif /* FALLTHROUGH */ case OTG_STATE_B_SRP_INIT: b_idle(isp, __func__); l = omap_readl(OTG_CTRL) & OTG_XCEIV_OUTPUTS; omap_writel(l, OTG_CTRL); /* FALLTHROUGH */ case OTG_STATE_B_IDLE: if (isp->otg.gadget && (isp_bstat & OTG_B_SESS_VLD)) { #ifdef CONFIG_USB_OTG update_otg1(isp, isp_stat); update_otg2(isp, isp_bstat); #endif b_peripheral(isp); } else if (!(isp_stat & (INTR_VBUS_VLD|INTR_SESS_VLD))) isp_bstat |= OTG_B_SESS_END; break; case OTG_STATE_A_WAIT_VFALL: break; default: pr_debug("otg: unsupported b-device %s\n", state_name(isp)); break; } } if (state != isp->otg.state) pr_debug(" isp, %s -> %s\n", state_string(state), state_name(isp)); #ifdef CONFIG_USB_OTG /* update the OTG controller state to match the isp1301; may * trigger OPRT_CHG irqs for changes going to the isp1301. */ update_otg1(isp, isp_stat); update_otg2(isp, isp_bstat); check_state(isp, __func__); #endif dump_regs(isp, "isp1301->otg"); }
static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device) { u32 syscon1 = 0; if (cpu_is_omap24xx()) omap2_usb_devconf_clear(0, USB_BIDIR_TLL); if (nwires == 0) { if (cpu_class_is_omap1() && !cpu_is_omap15xx()) { u32 l; /* pulldown D+/D- */ l = omap_readl(USB_TRANSCEIVER_CTRL); l &= ~(3 << 1); omap_writel(l, USB_TRANSCEIVER_CTRL); } return 0; } if (is_device) { if (cpu_is_omap24xx()) omap_cfg_reg(J20_24XX_USB0_PUEN); else omap_cfg_reg(W4_USB_PUEN); } /* internal transceiver (unavailable on 17xx, 24xx) */ if (!cpu_class_is_omap2() && nwires == 2) { u32 l; // omap_cfg_reg(P9_USB_DP); // omap_cfg_reg(R8_USB_DM); if (cpu_is_omap15xx()) { /* This works on 1510-Innovator */ return 0; } /* NOTES: * - peripheral should configure VBUS detection! * - only peripherals may use the internal D+/D- pulldowns * - OTG support on this port not yet written */ l = omap_readl(USB_TRANSCEIVER_CTRL); l &= ~(7 << 4); if (!is_device) l |= (3 << 1); omap_writel(l, USB_TRANSCEIVER_CTRL); return 3 << 16; } /* alternate pin config, external transceiver */ if (cpu_is_omap15xx()) { printk(KERN_ERR "no usb0 alt pin config on 15xx\n"); return 0; } if (cpu_is_omap24xx()) { omap_cfg_reg(K18_24XX_USB0_DAT); omap_cfg_reg(K19_24XX_USB0_TXEN); omap_cfg_reg(J14_24XX_USB0_SE0); if (nwires != 3) omap_cfg_reg(J18_24XX_USB0_RCV); } else { omap_cfg_reg(V6_USB0_TXD); omap_cfg_reg(W9_USB0_TXEN); omap_cfg_reg(W5_USB0_SE0); if (nwires != 3) omap_cfg_reg(Y5_USB0_RCV); } /* NOTE: SPEED and SUSP aren't configured here. OTG hosts * may be able to use I2C requests to set those bits along * with VBUS switching and overcurrent detection. */ if (cpu_class_is_omap1() && nwires != 6) { u32 l; l = omap_readl(USB_TRANSCEIVER_CTRL); l &= ~CONF_USB2_UNI_R; omap_writel(l, USB_TRANSCEIVER_CTRL); } switch (nwires) { case 3: syscon1 = 2; if (cpu_is_omap24xx()) omap2_usb_devconf_set(0, USB_BIDIR); break; case 4: syscon1 = 1; if (cpu_is_omap24xx()) omap2_usb_devconf_set(0, USB_BIDIR); break; case 6: syscon1 = 3; if (cpu_is_omap24xx()) { omap_cfg_reg(J19_24XX_USB0_VP); omap_cfg_reg(K20_24XX_USB0_VM); omap2_usb_devconf_set(0, USB_UNIDIR); } else { u32 l; omap_cfg_reg(AA9_USB0_VP); omap_cfg_reg(R9_USB0_VM); l = omap_readl(USB_TRANSCEIVER_CTRL); l |= CONF_USB2_UNI_R; omap_writel(l, USB_TRANSCEIVER_CTRL); } break; default: printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", 0, nwires); } return syscon1 << 16; }
/**************************************************************************************** * hPlatform_hwGetMemoryAddr() **************************************************************************************** DESCRIPTION: ARGUMENTS: RETURN: NOTES: *****************************************************************************************/ void* hPlatform_hwGetMemoryAddr(TI_HANDLE OsContext) { return (void*)OS_API_MEM_ADDR; } void hPlatform_Wlan_Hardware_DeInit(void) { wifi_del_dev(); } #if 0/* needed for first time new host ramp*/ static void dump_omap_registers(void) { printk(KERN_ERR "MMC3 CMD addr 0x%x value is =%x\n", CONTROL_PADCONF_MMC3_CMD, omap_readl( CONTROL_PADCONF_MMC3_CMD )); printk(KERN_ERR "MMC3 CLK addr 0x%x value is =%x\n", CONTROL_PADCONF_MMC3_CLK, omap_readl( CONTROL_PADCONF_MMC3_CLK )); printk(KERN_ERR "MMC3 DAT0 addr 0x%x value is =%x\n", CONTROL_PADCONF_MMC3_DAT0, omap_readl( CONTROL_PADCONF_MMC3_DAT0 )); printk(KERN_ERR "MMC3 DAT2 addr 0x%x value is =%x\n", CONTROL_PADCONF_MMC3_DAT2, omap_readl( CONTROL_PADCONF_MMC3_DAT2 )); printk(KERN_ERR "MMC3 DAT3 addr 0x%x value is =%x\n", CONTROL_PADCONF_MMC3_DAT3, omap_readl( CONTROL_PADCONF_MMC3_DAT3 )); printk(KERN_ERR "WLAN_EN addr 0x%x value is =%x\n", CONTROL_PADCONF_CAM_D1, omap_readl( CONTROL_PADCONF_CAM_D1 )); printk(KERN_ERR "WLAN_IRQ addr 0x%x value is =%x\n", CONTROL_PADCONF_MCBSP1_CLKX, omap_readl( CONTROL_PADCONF_MCBSP1_CLKX )); return; }
static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup) { u32 syscon1 = 0; if (cpu_is_omap24xx()) { omap2_usb2_disable_5pinbitll(); alt_pingroup = 0; } /* NOTE omap1 erratum: must leave USB2_UNI_R set if usb0 in use */ if (alt_pingroup || nwires == 0) return 0; if (cpu_class_is_omap1() && !cpu_is_omap15xx() && nwires != 6) { u32 l; l = omap_readl(USB_TRANSCEIVER_CTRL); l &= ~CONF_USB2_UNI_R; omap_writel(l, USB_TRANSCEIVER_CTRL); } /* external transceiver */ if (cpu_is_omap15xx()) { omap_cfg_reg(USB2_TXD); omap_cfg_reg(USB2_TXEN); omap_cfg_reg(USB2_SEO); if (nwires != 3) omap_cfg_reg(USB2_RCV); /* there is no USB2_SPEED */ } else if (cpu_is_omap16xx()) { omap_cfg_reg(V6_USB2_TXD); omap_cfg_reg(W9_USB2_TXEN); omap_cfg_reg(W5_USB2_SE0); if (nwires != 3) omap_cfg_reg(Y5_USB2_RCV); // FIXME omap_cfg_reg(USB2_SPEED); } else if (cpu_is_omap24xx()) { omap_cfg_reg(Y11_24XX_USB2_DAT); omap_cfg_reg(AA10_24XX_USB2_SE0); if (nwires > 2) omap_cfg_reg(AA12_24XX_USB2_TXEN); if (nwires > 3) omap_cfg_reg(AA6_24XX_USB2_RCV); } else { pr_debug("usb%d cpu unrecognized\n", 1); return 0; } // if (cpu_class_is_omap1()) omap_cfg_reg(USB2_SUSP); switch (nwires) { case 2: if (!cpu_is_omap24xx()) goto bad; /* NOTE: board-specific code must override this setting if * this TLL link is not using DP/DM */ syscon1 = 1; omap2_usb_devconf_set(2, USB_BIDIR_TLL); break; case 3: syscon1 = 2; if (cpu_is_omap24xx()) omap2_usb_devconf_set(2, USB_BIDIR); break; case 4: syscon1 = 1; if (cpu_is_omap24xx()) omap2_usb_devconf_set(2, USB_BIDIR); break; case 5: if (!cpu_is_omap24xx()) goto bad; omap_cfg_reg(AA4_24XX_USB2_TLLSE0); /* NOTE: board-specific code must override this setting if * this TLL link is not using DP/DM. Something must also * set up OTG_SYSCON2.HMC_TLL{ATTACH,SPEED} */ syscon1 = 3; omap2_usb2_enable_5pinunitll(); break; case 6: if (cpu_is_omap24xx()) goto bad; syscon1 = 3; if (cpu_is_omap15xx()) { omap_cfg_reg(USB2_VP); omap_cfg_reg(USB2_VM); } else { u32 l; omap_cfg_reg(AA9_USB2_VP); omap_cfg_reg(R9_USB2_VM); l = omap_readl(USB_TRANSCEIVER_CTRL); l |= CONF_USB2_UNI_R; omap_writel(l, USB_TRANSCEIVER_CTRL); } break; default: bad: printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", 2, nwires); } return syscon1 << 24; }
/** * omap_hsmmc_reset() - Full reset of each HS-MMC controller * * Ensure that each MMC controller is fully reset. Controllers * left in an unknown state (by bootloader) may prevent retention * or OFF-mode. This is especially important in cases where the * MMC driver is not enabled, _or_ built as a module. * * In order for reset to work, interface, functional and debounce * clocks must be enabled. The debounce clock comes from func_32k_clk * and is not under SW control, so we only enable i- and f-clocks. **/ static void __init omap_hsmmc_reset(void) { u32 i, nr_controllers = cpu_is_omap44xx() ? OMAP44XX_NR_MMC : (cpu_is_omap34xx() ? OMAP34XX_NR_MMC : OMAP24XX_NR_MMC); for (i = 0; i < nr_controllers; i++) { u32 v, base = 0; struct clk *iclk, *fclk; struct device *dev = &dummy_pdev.dev; switch (i) { case 0: base = OMAP2_MMC1_BASE; break; case 1: base = OMAP2_MMC2_BASE; break; case 2: base = OMAP3_MMC3_BASE; break; case 3: if (!cpu_is_omap44xx()) return; base = OMAP4_MMC4_BASE; break; case 4: if (!cpu_is_omap44xx()) return; base = OMAP4_MMC5_BASE; break; } if (cpu_is_omap44xx()) base += OMAP4_MMC_REG_OFFSET; dummy_pdev.id = i; dev_set_name(&dummy_pdev.dev, "mmci-omap-hs.%d", i); iclk = clk_get(dev, "ick"); if (iclk && clk_enable(iclk)) iclk = NULL; fclk = clk_get(dev, "fck"); if (fclk && clk_enable(fclk)) fclk = NULL; if (!iclk || !fclk) { printk(KERN_WARNING "%s: Unable to enable clocks for MMC%d, " "cannot reset.\n", __func__, i); break; } omap_writel(MMCHS_SYSCONFIG_SWRESET, base + MMCHS_SYSCONFIG); v = omap_readl(base + MMCHS_SYSSTATUS); while (!(omap_readl(base + MMCHS_SYSSTATUS) & MMCHS_SYSSTATUS_RESETDONE)) cpu_relax(); if (fclk) { clk_disable(fclk); clk_put(fclk); } if (iclk) { clk_disable(iclk); clk_put(iclk); } } }
static void __init omap_1510_usb_init(struct omap_usb_config *config) { unsigned int val; u16 w; omap_usb0_init(config->pins[0], is_usb0_device(config)); omap_usb1_init(config->pins[1]); omap_usb2_init(config->pins[2], 0); val = omap_readl(MOD_CONF_CTRL_0) & ~(0x3f << 1); val |= (config->hmc_mode << 1); omap_writel(val, MOD_CONF_CTRL_0); printk("USB: hmc %d", config->hmc_mode); if (config->pins[0]) printk(", usb0 %d wires%s", config->pins[0], is_usb0_device(config) ? " (dev)" : ""); if (config->pins[1]) printk(", usb1 %d wires", config->pins[1]); if (config->pins[2]) printk(", usb2 %d wires", config->pins[2]); printk("\n"); /* use DPLL for 48 MHz function clock */ pr_debug("APLL %04x DPLL %04x REQ %04x\n", omap_readw(ULPD_APLL_CTRL), omap_readw(ULPD_DPLL_CTRL), omap_readw(ULPD_SOFT_REQ)); w = omap_readw(ULPD_APLL_CTRL); w &= ~APLL_NDPLL_SWITCH; omap_writew(w, ULPD_APLL_CTRL); w = omap_readw(ULPD_DPLL_CTRL); w |= DPLL_IOB | DPLL_PLL_ENABLE; omap_writew(w, ULPD_DPLL_CTRL); w = omap_readw(ULPD_SOFT_REQ); w |= SOFT_UDC_REQ | SOFT_DPLL_REQ; omap_writew(w, ULPD_SOFT_REQ); while (!(omap_readw(ULPD_DPLL_CTRL) & DPLL_LOCK)) cpu_relax(); #ifdef CONFIG_USB_GADGET_OMAP if (config->register_dev) { int status; udc_device.dev.platform_data = config; status = platform_device_register(&udc_device); if (status) pr_debug("can't register UDC device, %d\n", status); /* udc driver gates 48MHz by D+ pullup */ } #endif #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) if (config->register_host) { int status; ohci_device.dev.platform_data = config; status = platform_device_register(&ohci_device); if (status) pr_debug("can't register OHCI device, %d\n", status); /* hcd explicitly gates 48MHz */ } #endif }
/** * omap3_enter_idle - Programs OMAP3 to enter the specified state * @dev: cpuidle device * @state: The target state to be programmed * * Called from the CPUidle framework to program the device to the * specified target state selected by the governor. */ static int omap3_enter_idle(struct cpuidle_device *dev, struct cpuidle_state *state) { struct omap3_processor_cx *cx = cpuidle_get_statedata(state); struct timespec ts_preidle, ts_postidle, ts_idle; u32 mpu_state = cx->mpu_state, core_state = cx->core_state, cam_state = 0, dss_state = 0, per_state = 0; /* modified for mp3 current -- begin */ u32 mpu_prev,core_prev =0 ; current_cx_state = *cx; int requested=cx->type; static int cam_deny = 0; u32 wkdep_per_value = 0; wkdep_per_value = omap_readl(0x483070C8); /* modified for mp3 current -- end*/ /* Used to keep track of the total time in idle */ getnstimeofday(&ts_preidle); local_irq_disable(); local_fiq_disable(); pwrdm_set_next_pwrst(mpu_pd, mpu_state); pwrdm_set_next_pwrst(core_pd, core_state); if (omap_irq_pending() || need_resched()) goto return_sleep_time; /* Keep CAM domain active during ISP usecases */ if(( front_cam_in_use || back_cam_in_use || (stream_on)) ){ pwrdm_for_each_clkdm(cam_pd, _cpuidle_deny_idle); cam_deny = 1 ; } /* if (cx->type == OMAP3_STATE_C1) { pwrdm_for_each_clkdm(mpu_pd, _cpuidle_deny_idle); pwrdm_for_each_clkdm(core_pd, _cpuidle_deny_idle); } */ if (dss_suspend_flag && audio_on) { omap_writel(wkdep_per_value & ~(1<<1) ,0x483070C8 );//PM_WKDEP_PER } /* Execute ARM wfi */ omap_sram_idle(); /* if (cx->type == OMAP3_STATE_C1) { pwrdm_for_each_clkdm(mpu_pd, _cpuidle_allow_idle); pwrdm_for_each_clkdm(core_pd, _cpuidle_allow_idle); } */ /* Keep CAM domain active during ISP usecases */ if(cam_deny){ pwrdm_for_each_clkdm(cam_pd, _cpuidle_allow_idle); cam_deny = 0; } if(!dss_suspend_flag){ omap_writel(wkdep_per_value, 0x483070C8); //PM_WKDEP_PER } core_state = pwrdm_read_prev_pwrst(core_pd); mpu_state = pwrdm_read_prev_pwrst(mpu_pd); cam_state = pwrdm_read_prev_pwrst(cam_pd); dss_state = pwrdm_read_prev_pwrst(dss_pd); per_state = pwrdm_read_prev_pwrst(per_pd); //printk(KERN_INFO "requested C%d, actual core=%d, mpu=%d cam = %d dss = %d per = %d \n", requested, core_state, mpu_state,cam_state); return_sleep_time: getnstimeofday(&ts_postidle); ts_idle = timespec_sub(ts_postidle, ts_preidle); /* modified for mp3 current -- begin */ mpu_prev = omap_readl(0x483069E8); mpu_prev = mpu_prev & 0x3 ; core_prev = omap_readl(0x48306AE8); core_prev = core_prev & 0x3 ; /* modified for mp3 current -- end */ local_irq_enable(); local_fiq_enable(); return ts_idle.tv_nsec / NSEC_PER_USEC + ts_idle.tv_sec * USEC_PER_SEC; }
static cycle_t notrace omap_32k_read(void) { return omap_readl(TIMER_32K_SYNCHRONIZED); }
static int __devinit omap_temp_sensor_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct omap_temp_sensor_pdata *pdata = pdev->dev.platform_data; struct omap_temp_sensor *temp_sensor; struct resource *mem; int ret = 0; if (!pdata) { dev_err(dev, "%s: platform data missing\n", __func__); return -EINVAL; } temp_sensor = kzalloc(sizeof(struct omap_temp_sensor), GFP_KERNEL); if (!temp_sensor) return -ENOMEM; spin_lock_init(&temp_sensor->lock); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem) { dev_err(dev, "%s:no mem resource\n", __func__); dump_stack(); ret = -EINVAL; goto plat_res_err; } temp_sensor->phy_base = pdata->offset; temp_sensor->pdev = pdev; temp_sensor->dev = dev; pm_runtime_enable(dev); pm_runtime_irq_safe(dev); /* * check if the efuse has a non-zero value if not * it is an untrimmed sample and the temperatures * may not be accurate */ if (omap_readl(OMAP4_CTRL_MODULE_CORE + OMAP4_CTRL_MODULE_CORE_STD_FUSE_OPP_BGAP)) temp_sensor->is_efuse_valid = 1; temp_sensor->clock = clk_get(&temp_sensor->pdev->dev, "fck"); if (IS_ERR(temp_sensor->clock)) { ret = PTR_ERR(temp_sensor->clock); pr_err("%s:Unable to get fclk: %d\n", __func__, ret); ret = -EINVAL; goto clk_get_err; } platform_set_drvdata(pdev, temp_sensor); ret = omap_temp_sensor_enable(temp_sensor); if (ret) { dev_err(dev, "%s:Cannot enable temp sensor\n", __func__); goto sensor_enable_err; } omap_enable_continuous_mode(temp_sensor); /* Wait till the first conversion is done wait for at least 1ms */ mdelay(2); /* Read the temperature once due to hw issue*/ omap_read_current_temp(temp_sensor); /* Initialize Polling work queue*/ INIT_DELAYED_WORK(&temp_sensor->temp_poll_work, temp_poll_work_fn); schedule_delayed_work(&temp_sensor->temp_poll_work, msecs_to_jiffies(POLL_DELAY_MS)); ret = sysfs_create_group(&pdev->dev.kobj, &omap_temp_sensor_group); if (ret) { dev_err(&pdev->dev, "could not create sysfs files\n"); goto sensor_enable_err; } ret = sysfs_create_group(&pdev->dev.kobj, &omap_temp_section1_group); if (ret) dev_err(&pdev->dev, "could not create section sysfs files\n"); ret = sysfs_create_group(&pdev->dev.kobj, &omap_temp_section2_group); if (ret) dev_err(&pdev->dev, "could not create section sysfs files\n"); ret = sysfs_create_group(&pdev->dev.kobj, &omap_temp_section3_group); if (ret) dev_err(&pdev->dev, "could not create section sysfs files\n"); ret = sysfs_create_group(&pdev->dev.kobj, &omap_temp_section4_group); if (ret) dev_err(&pdev->dev, "could not create section sysfs files\n"); ret = sysfs_create_group(&pdev->dev.kobj, &omap_temp_section5_group); if (ret) dev_err(&pdev->dev, "could not create section sysfs files\n"); dev_info(dev, "%s probed", pdata->name); temp_sensor_pm = temp_sensor; return 0; sensor_enable_err: clk_put(temp_sensor->clock); clk_get_err: pm_runtime_disable(dev); plat_res_err: kfree(temp_sensor); return ret; }
/* * Let's power down on idle, but only if we are really * idle, because once we start down the path of * going idle we continue to do idle even if we get * a clock tick interrupt . . */ void omap_pm_idle(void) { extern __u32 arm_idlect1_mask; __u32 use_idlect1 = arm_idlect1_mask; int do_sleep = 0; local_irq_disable(); local_fiq_disable(); if (need_resched()) { local_fiq_enable(); local_irq_enable(); return; } /* * Since an interrupt may set up a timer, we don't want to * reprogram the hardware timer with interrupts enabled. * Re-enable interrupts only after returning from idle. */ timer_dyn_reprogram(); #ifdef CONFIG_OMAP_MPU_TIMER #warning Enable 32kHz OS timer in order to allow sleep states in idle use_idlect1 = use_idlect1 & ~(1 << 9); #else while (enable_dyn_sleep) { #ifdef CONFIG_CBUS_TAHVO_USB extern int vbus_active; /* Clock requirements? */ if (vbus_active) break; #endif do_sleep = 1; break; } #endif #ifdef CONFIG_OMAP_DM_TIMER use_idlect1 = omap_dm_timer_modify_idlect_mask(use_idlect1); #endif if (omap_dma_running()) use_idlect1 &= ~(1 << 6); /* We should be able to remove the do_sleep variable and multiple * tests above as soon as drivers, timer and DMA code have been fixed. * Even the sleep block count should become obsolete. */ if ((use_idlect1 != ~0) || !do_sleep) { __u32 saved_idlect1 = omap_readl(ARM_IDLECT1); if (cpu_is_omap15xx()) use_idlect1 &= OMAP1510_BIG_SLEEP_REQUEST; else use_idlect1 &= OMAP1610_IDLECT1_SLEEP_VAL; omap_writel(use_idlect1, ARM_IDLECT1); __asm__ volatile ("mcr p15, 0, r0, c7, c0, 4"); omap_writel(saved_idlect1, ARM_IDLECT1); local_fiq_enable(); local_irq_enable(); return; }
static inline unsigned int irq_bank_readl(int bank, int offset) { return omap_readl(irq_banks[bank].base_reg + offset); }