diff --git a/arch/arm/mach-omap2/clockdomains44xx_data.c b/arch/arm/mach-omap2/clockdomains44xx_data.c index 9299ac2..41d2260 100644 --- a/arch/arm/mach-omap2/clockdomains44xx_data.c +++ b/arch/arm/mach-omap2/clockdomains44xx_data.c @@ -390,7 +390,7 @@ static struct clockdomain emu_sys_44xx_clkdm = { .prcm_partition = OMAP4430_PRM_PARTITION, .cm_inst = OMAP4430_PRM_EMU_CM_INST, .clkdm_offs = OMAP4430_PRM_EMU_CM_EMU_CDOFFS, - .flags = CLKDM_CAN_HWSUP, + .flags = CLKDM_CAN_SWSUP, }; static struct clockdomain l3_dma_44xx_clkdm = { diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 283d11e..91477f8 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -17,12 +17,14 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include @@ -445,14 +447,130 @@ static struct platform_device omap_pmu_device = { .num_resources = 1, }; -static void omap_init_pmu(void) +static struct arm_pmu_platdata omap4_pmu_data; +static struct omap_device_pm_latency omap_pmu_latency[] = { + [0] = { + .deactivate_func = omap_device_idle_hwmods, + .activate_func = omap_device_enable_hwmods, + .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, + }, +}; + +static struct cti omap4_cti[2]; +static struct platform_device *pmu_dev; + +static void omap4_enable_cti(int irq) { - if (cpu_is_omap24xx()) + pm_runtime_get_sync(&pmu_dev->dev); + if (irq == OMAP44XX_IRQ_CTI0) + cti_enable(&omap4_cti[0]); + else if (irq == OMAP44XX_IRQ_CTI1) + cti_enable(&omap4_cti[1]); +} + +static void omap4_disable_cti(int irq) +{ + if (irq == OMAP44XX_IRQ_CTI0) + cti_disable(&omap4_cti[0]); + else if (irq == OMAP44XX_IRQ_CTI1) + cti_disable(&omap4_cti[1]); + pm_runtime_put(&pmu_dev->dev); +} + +static irqreturn_t omap4_pmu_handler(int irq, void *dev, irq_handler_t handler) +{ + if (irq == OMAP44XX_IRQ_CTI0) + cti_irq_ack(&omap4_cti[0]); + else if (irq == OMAP44XX_IRQ_CTI1) + cti_irq_ack(&omap4_cti[1]); + + return handler(irq, dev); +} + +static void __init omap4_configure_pmu_irq(void) +{ + void __iomem *base0; + void __iomem *base1; + + base0 = ioremap(OMAP44XX_CTI0_BASE, SZ_4K); + base1 = ioremap(OMAP44XX_CTI1_BASE, SZ_4K); + if (!base0 && !base1) { + pr_err("ioremap for OMAP4 CTI failed\n"); + return; + } + + /*configure CTI0 for pmu irq routing*/ + cti_init(&omap4_cti[0], base0, OMAP44XX_IRQ_CTI0, 6); + cti_unlock(&omap4_cti[0]); + cti_map_trigger(&omap4_cti[0], 1, 6, 2); + + /*configure CTI1 for pmu irq routing*/ + cti_init(&omap4_cti[1], base1, OMAP44XX_IRQ_CTI1, 6); + cti_unlock(&omap4_cti[1]); + cti_map_trigger(&omap4_cti[1], 1, 6, 2); +} + +static struct platform_device* __init omap4_init_pmu(void) +{ + int id = -1; + const char *hw; + struct platform_device *pd; + struct omap_hwmod* oh[3]; + char *dev_name = "arm-pmu"; + + hw = "l3_main_3"; + oh[0] = omap_hwmod_lookup(hw); + if (!oh[0]) { + pr_err("Could not look up %s hwmod\n", hw); + return NULL; + } + hw = "l3_instr"; + oh[1] = omap_hwmod_lookup(hw); + if (!oh[1]) { + pr_err("Could not look up %s hwmod\n", hw); + return NULL; + } + hw = "debugss"; + oh[2] = omap_hwmod_lookup(hw); + if (!oh[2]) { + pr_err("Could not look up %s hwmod\n", hw); + return NULL; + } + + omap4_pmu_data.handle_irq = omap4_pmu_handler; + omap4_pmu_data.enable_irq = omap4_enable_cti; + omap4_pmu_data.disable_irq = omap4_disable_cti; + + pd = omap_device_build_ss(dev_name, id, oh, 3, &omap4_pmu_data, + sizeof(omap4_pmu_data), + omap_pmu_latency, + ARRAY_SIZE(omap_pmu_latency), 0); + WARN(IS_ERR(pd), "Can't build omap_device for %s.\n", + dev_name); + return pd; +} +static void __init omap_init_pmu(void) +{ + if (cpu_is_omap24xx()) { omap_pmu_device.resource = &omap2_pmu_resource; - else if (cpu_is_omap34xx()) + } else if (cpu_is_omap34xx()) { omap_pmu_device.resource = &omap3_pmu_resource; - else + } else if (cpu_is_omap44xx()) { + struct platform_device *pd; + + pd = omap4_init_pmu(); + if (!pd) + return; + + pmu_dev= pd; + pm_runtime_enable(&pd->dev); + pm_runtime_get_sync(&pd->dev); + omap4_configure_pmu_irq(); + pm_runtime_put(&pd->dev); + return; + } else { return; + } platform_device_register(&omap_pmu_device); } diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index ef0524c..0b7f528 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -48,6 +48,7 @@ /* Backward references (IPs with Bus Master capability) */ static struct omap_hwmod omap44xx_aess_hwmod; +static struct omap_hwmod omap44xx_debugss_hwmod; static struct omap_hwmod omap44xx_dma_system_hwmod; static struct omap_hwmod omap44xx_dmm_hwmod; static struct omap_hwmod omap44xx_dsp_hwmod; @@ -340,6 +341,14 @@ static struct omap_hwmod omap44xx_l3_main_1_hwmod = { }; /* l3_main_2 */ +/* debugss -> l3_main_2 */ +static struct omap_hwmod_ocp_if omap44xx_debugss__l3_main_2 = { + .master = &omap44xx_debugss_hwmod, + .slave = &omap44xx_l3_main_2_hwmod, + .clk = "dbgclk_mux_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + /* dma_system -> l3_main_2 */ static struct omap_hwmod_ocp_if omap44xx_dma_system__l3_main_2 = { .master = &omap44xx_dma_system_hwmod, @@ -689,7 +698,6 @@ static struct omap_hwmod omap44xx_mpu_private_hwmod = { * ctrl_module_pad_core * ctrl_module_pad_wkup * ctrl_module_wkup - * debugss * efuse_ctrl_cust * efuse_ctrl_std * elm @@ -911,6 +919,168 @@ static struct omap_hwmod omap44xx_counter_32k_hwmod = { }; /* + * 'debugss' class + * debug and emulation sub system + */ + +static struct omap_hwmod_class_sysconfig omap44xx_debugss_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap44xx_debugss_hwmod_class = { + .name = "debugss", + .sysc = &omap44xx_debugss_sysc, +}; + +/* debugss */ +static struct omap_hwmod_irq_info omap44xx_debugss_irqs[] = { + { .name = "cti0", .irq = 1 + OMAP44XX_IRQ_GIC_START }, + { .name = "cti1", .irq = 2 + OMAP44XX_IRQ_GIC_START }, + { .irq = -1 } +}; + +/* debugss master ports */ +static struct omap_hwmod_ocp_if *omap44xx_debugss_masters[] = { + &omap44xx_debugss__l3_main_2, +}; + +static struct omap_hwmod_addr_space omap44xx_debugss_addrs[] = { + { + .name = "mipi_stm_add_sp_0", + .pa_start = 0x54000000, + .pa_end = 0x540fffff, + }, + { + .name = "mipi_stm_add_sp_1", + .pa_start = 0x54100000, + .pa_end = 0x5413ffff, + }, + { + .name = "mpu_c0_debug", + .pa_start = 0x54140000, + .pa_end = 0x54141fff, + }, + { + .name = "mpu_c1_debug", + .pa_start = 0x54142000, + .pa_end = 0x54143fff, + }, + { + .name = "cti0_mpu", + .pa_start = 0x54148000, + .pa_end = 0x54148fff, + }, + { + .name = "cti1_mpu", + .pa_start = 0x54149000, + .pa_end = 0x54149fff, + }, + { + .name = "ptm0_mpu", + .pa_start = 0x5414c000, + .pa_end = 0x5414cfff, + }, + { + .name = "ptm1_mpu", + .pa_start = 0x5414d000, + .pa_end = 0x5414dfff, + }, + { + .name = "tf_mpu", + .pa_start = 0x54158000, + .pa_end = 0x54158fff, + }, + { + .name = "dap_pc_mpu", + .pa_start = 0x54159000, + .pa_end = 0x54159fff, + }, + { + .name = "apb_bridge_a_ctrl_time_out", + .pa_start = 0x5415f000, + .pa_end = 0x5415ffff, + }, + { + .name = "drm", + .pa_start = 0x54160000, + .pa_end = 0x54160fff, + }, + { + .name = "mipi_stm", + .pa_start = 0x54161000, + .pa_end = 0x54161fff, + .flags = ADDR_TYPE_RT + }, + { + .name = "csetb", + .pa_start = 0x54162000, + .pa_end = 0x54162fff, + }, + { + .name = "cstpiu", + .pa_start = 0x54163000, + .pa_end = 0x54163fff, + }, + { + .name = "cstf1", + .pa_start = 0x54164000, + .pa_end = 0x54164fff, + }, + { + .name = "cstf2", + .pa_start = 0x54165000, + .pa_end = 0x54165fff, + }, + { + .name = "l4_cfg_emu_conf_regs", + .pa_start = 0x54167000, + .pa_end = 0x54167fff, + }, + { + .name = "l3_instr_emu_conf_regs", + .pa_start = 0x54180000, + .pa_end = 0x54180fff, + }, + { } +}; + +/* l3_instr -> debugss */ +static struct omap_hwmod_ocp_if omap44xx_l3_instr__debugss = { + .master = &omap44xx_l3_instr_hwmod, + .slave = &omap44xx_debugss_hwmod, + .clk = "l3_div_ck", + .addr = omap44xx_debugss_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* debugss slave ports */ +static struct omap_hwmod_ocp_if *omap44xx_debugss_slaves[] = { + &omap44xx_l3_instr__debugss, +}; + +static struct omap_hwmod omap44xx_debugss_hwmod = { + .name = "debugss", + .class = &omap44xx_debugss_hwmod_class, + .clkdm_name = "emu_sys_clkdm", + .mpu_irqs = omap44xx_debugss_irqs, + .main_clk = "trace_clk_div_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_EMU_DEBUGSS_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_EMU_DEBUGSS_CONTEXT_OFFSET, + }, + }, + .slaves = omap44xx_debugss_slaves, + .slaves_cnt = ARRAY_SIZE(omap44xx_debugss_slaves), + .masters = omap44xx_debugss_masters, + .masters_cnt = ARRAY_SIZE(omap44xx_debugss_masters), +}; + +/* * 'dma' class * dma controller for data exchange between memory to memory (i.e. internal or * external memory) and gp peripherals to memory or memory to gp peripherals @@ -3907,8 +4077,6 @@ static struct omap_hwmod_class omap44xx_mpu_hwmod_class = { /* mpu */ static struct omap_hwmod_irq_info omap44xx_mpu_irqs[] = { { .name = "pl310", .irq = 0 + OMAP44XX_IRQ_GIC_START }, - { .name = "cti0", .irq = 1 + OMAP44XX_IRQ_GIC_START }, - { .name = "cti1", .irq = 2 + OMAP44XX_IRQ_GIC_START }, { .irq = -1 } }; @@ -5514,6 +5682,9 @@ static __initdata struct omap_hwmod *omap44xx_hwmods[] = { /* counter class */ /* &omap44xx_counter_32k_hwmod, */ + /* debugss class */ + &omap44xx_debugss_hwmod, + /* dma class */ &omap44xx_dma_system_hwmod, diff --git a/arch/arm/plat-omap/include/plat/omap44xx.h b/arch/arm/plat-omap/include/plat/omap44xx.h index c0d478e..0b04969 100644 --- a/arch/arm/plat-omap/include/plat/omap44xx.h +++ b/arch/arm/plat-omap/include/plat/omap44xx.h @@ -58,5 +58,8 @@ #define OMAP44XX_HSUSB_OHCI_BASE (L4_44XX_BASE + 0x64800) #define OMAP44XX_HSUSB_EHCI_BASE (L4_44XX_BASE + 0x64C00) +#define OMAP44XX_CTI0_BASE 0x54148000 +#define OMAP44XX_CTI1_BASE 0x54149000 + #endif /* __ASM_ARCH_OMAP44XX_H */