Skip to contentSkip to conversation

OMAP: MCBSP: hwmod database for 2xxx devices

RFC PATCH In review Kishon Vijay Abraham I 10 participants 36 messages Oct 5, 2010 – Dec 7, 2010 1 message not in the archive

Subsystems (5)
lore
Share & tools
lore
#0 lore raw

RFC PATCH 1/7 OMAP: MCBSP: hwmod database for 2xxx devices

From: Charulatha V <[email protected]>

---
 arch/arm/mach-omap2/omap_hwmod_2420_data.c |  125 +++++++++++
 arch/arm/mach-omap2/omap_hwmod_2430_data.c |  313 ++++++++++++++++++++++++++++
 2 files changed, 438 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/omap_hwmod_2420_data.c +125 -0
index adf6e36..289ef86 100644
@@ -36,6 +36,8 @@ static struct omap_hwmod omap2420_iva_hwmod;
 static struct omap_hwmod omap2420_l3_main_hwmod;
 static struct omap_hwmod omap2420_l4_core_hwmod;
 static struct omap_hwmod omap2420_wd_timer2_hwmod;
+static struct omap_hwmod omap2420_mcbsp1_hwmod;
+static struct omap_hwmod omap2420_mcbsp2_hwmod;
 
 /* L3 -> L4_CORE interface */
 static struct omap_hwmod_ocp_if omap2420_l3_main__l4_core = {
@@ -418,6 +420,127 @@ static struct omap_hwmod omap2420_uart3_hwmod = {
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
 };
 
+/*
+ * 'mcbsp' class
+ * multi channel buffered serial port controller
+ */
+
+static struct omap_hwmod_class omap2420_mcbsp_hwmod_class = {
+	.name = "mcbsp",
+};
+
+/* mcbsp1 */
+static struct omap_hwmod_irq_info omap2420_mcbsp1_irqs[] = {
+	{ .name = "tx", .irq = 59 },
+	{ .name = "rx", .irq = 60 },
+};
+
+static struct omap_hwmod_dma_info omap2420_mcbsp1_sdma_chs[] = {
+	{ .name = "rx", .dma_req = 31 },
+	{ .name = "tx", .dma_req = 30 },
+};
+
+static struct omap_hwmod_addr_space omap2420_mcbsp1_addrs[] = {
+	{
+		.pa_start	= 0x48074000,
+		.pa_end		= 0x480740ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+/* l4_core -> mcbsp1 */
+static struct omap_hwmod_ocp_if omap2420_l4_core__mcbsp1 = {
+	.master		= &omap2420_l4_core_hwmod,
+	.slave		= &omap2420_mcbsp1_hwmod,
+	.clk		= "mcbsp1_ick",
+	.addr		= omap2420_mcbsp1_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap2420_mcbsp1_addrs),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mcbsp1 slave ports */
+static struct omap_hwmod_ocp_if *omap2420_mcbsp1_slaves[] = {
+	&omap2420_l4_core__mcbsp1,
+};
+
+static struct omap_hwmod omap2420_mcbsp1_hwmod = {
+	.name		= "mcbsp1",
+	.class		= &omap2420_mcbsp_hwmod_class,
+	.mpu_irqs	= omap2420_mcbsp1_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap2420_mcbsp1_irqs),
+	.sdma_reqs	= omap2420_mcbsp1_sdma_chs,
+	.sdma_reqs_cnt	= ARRAY_SIZE(omap2420_mcbsp1_sdma_chs),
+	.main_clk	= "mcbsp1_fck",
+	.prcm		= {
+		.omap2 = {
+			.prcm_reg_id = 1,
+			.module_bit = OMAP24XX_EN_MCBSP1_SHIFT,
+			.module_offs = CORE_MOD,
+			.idlest_reg_id = 1,
+			.idlest_idle_bit = OMAP24XX_EN_MCBSP1_SHIFT,
+		},
+	},
+	.slaves		= omap2420_mcbsp1_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap2420_mcbsp1_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+/* mcbsp2 */
+static struct omap_hwmod_irq_info omap2420_mcbsp2_irqs[] = {
+	{ .name = "tx", .irq = 62 },
+	{ .name = "rx", .irq = 63 },
+};
+
+static struct omap_hwmod_dma_info omap2420_mcbsp2_sdma_chs[] = {
+	{ .name = "rx", .dma_req = 33 },
+	{ .name = "tx", .dma_req = 32 },
+};
+
+static struct omap_hwmod_addr_space omap2420_mcbsp2_addrs[] = {
+	{
+		.pa_start	= 0x48076000,
+		.pa_end		= 0x480760ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+/* l4_core -> mcbsp2 */
+static struct omap_hwmod_ocp_if omap2420_l4_core__mcbsp2 = {
+	.master		= &omap2420_l4_core_hwmod,
+	.slave		= &omap2420_mcbsp2_hwmod,
+	.clk		= "mcbsp2_ick",
+	.addr		= omap2420_mcbsp2_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap2420_mcbsp2_addrs),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mcbsp2 slave ports */
+static struct omap_hwmod_ocp_if *omap2420_mcbsp2_slaves[] = {
+	&omap2420_l4_core__mcbsp2,
+};
+
+static struct omap_hwmod omap2420_mcbsp2_hwmod = {
+	.name		= "mcbsp2",
+	.class		= &omap2420_mcbsp_hwmod_class,
+	.mpu_irqs	= omap2420_mcbsp2_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap2420_mcbsp2_irqs),
+	.sdma_reqs	= omap2420_mcbsp2_sdma_chs,
+	.sdma_reqs_cnt	= ARRAY_SIZE(omap2420_mcbsp2_sdma_chs),
+	.main_clk	= "mcbsp2_fck",
+	.prcm		= {
+		.omap2 = {
+			.prcm_reg_id = 1,
+			.module_bit = OMAP24XX_EN_MCBSP2_SHIFT,
+			.module_offs = CORE_MOD,
+			.idlest_reg_id = 1,
+			.idlest_idle_bit = OMAP24XX_EN_MCBSP2_SHIFT,
+		},
+	},
+	.slaves		= omap2420_mcbsp2_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap2420_mcbsp2_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
 static __initdata struct omap_hwmod *omap2420_hwmods[] = {
 	&omap2420_l3_main_hwmod,
 	&omap2420_l4_core_hwmod,
@@ -428,6 +551,8 @@ static __initdata struct omap_hwmod *omap2420_hwmods[] = {
 	&omap2420_uart1_hwmod,
 	&omap2420_uart2_hwmod,
 	&omap2420_uart3_hwmod,
+	&omap2420_mcbsp1_hwmod,
+	&omap2420_mcbsp2_hwmod,
 	NULL,
 };
 
arch/arm/mach-omap2/omap_hwmod_2430_data.c +313 -0

331 lines not on this page · raw message

Signature · 1 line
1.7.0.4
#1 lore raw

RFC PATCH 2/7 OMAP: MCBSP: hwmod database for 3xxx devices

From: Charulatha V <[email protected]>

---
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |  426 ++++++++++++++++++++++++++++
 1 files changed, 426 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +426 -0
index cb97ecf..c399783 100644
@@ -39,6 +39,13 @@ static struct omap_hwmod omap3xxx_l3_main_hwmod;
 static struct omap_hwmod omap3xxx_l4_core_hwmod;
 static struct omap_hwmod omap3xxx_l4_per_hwmod;
 static struct omap_hwmod omap3xxx_wd_timer2_hwmod;
+static struct omap_hwmod omap3xxx_mcbsp1_hwmod;
+static struct omap_hwmod omap3xxx_mcbsp2_hwmod;
+static struct omap_hwmod omap3xxx_mcbsp3_hwmod;
+static struct omap_hwmod omap3xxx_mcbsp4_hwmod;
+static struct omap_hwmod omap3xxx_mcbsp5_hwmod;
+static struct omap_hwmod omap3xxx_mcbsp2_sidetone_hwmod;
+static struct omap_hwmod omap3xxx_mcbsp3_sidetone_hwmod;
 
 /* L3 -> L4_CORE interface */
 static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_core = {
@@ -509,6 +516,418 @@ static struct omap_hwmod omap3xxx_uart4_hwmod = {
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3630ES1),
 };
 
+/*
+ * 'mcbsp' class
+ * multi channel buffered serial port controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap3xxx_mcbsp_sysc = {
+	.sysc_offs	= 0x008c,
+	.sysc_flags	= (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
+			   SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SOFTRESET),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+	.sysc_fields	= &omap_hwmod_sysc_type1,
+	.clockact	= 0x2,
+};
+
+static struct omap_hwmod_class omap3xxx_mcbsp_hwmod_class = {
+	.name = "mcbsp",
+	.sysc = &omap3xxx_mcbsp_sysc,
+};
+
+/* mcbsp1 */
+static struct omap_hwmod_irq_info omap3xxx_mcbsp1_irqs[] = {
+	{ .name = "irq", .irq = 16 },
+	{ .name = "tx", .irq = 59 },
+	{ .name = "rx", .irq = 60 },
+};
+
+static struct omap_hwmod_dma_info omap3xxx_mcbsp1_sdma_chs[] = {
+	{ .name = "rx", .dma_req = 32 },
+	{ .name = "tx", .dma_req = 31 },
+};
+
+static struct omap_hwmod_addr_space omap3xxx_mcbsp1_addrs[] = {
+	{
+		.pa_start	= 0x48074000,
+		.pa_end		= 0x480740ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+/* l4_core -> mcbsp1 */
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__mcbsp1 = {
+	.master		= &omap3xxx_l4_core_hwmod,
+	.slave		= &omap3xxx_mcbsp1_hwmod,
+	.clk		= "mcbsp1_ick",
+	.addr		= omap3xxx_mcbsp1_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap3xxx_mcbsp1_addrs),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mcbsp1 slave ports */
+static struct omap_hwmod_ocp_if *omap3xxx_mcbsp1_slaves[] = {
+	&omap3xxx_l4_core__mcbsp1,
+};
+
+static struct omap_hwmod omap3xxx_mcbsp1_hwmod = {
+	.name		= "mcbsp1",
+	.class		= &omap3xxx_mcbsp_hwmod_class,
+	.mpu_irqs	= omap3xxx_mcbsp1_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap3xxx_mcbsp1_irqs),
+	.sdma_reqs	= omap3xxx_mcbsp1_sdma_chs,
+	.sdma_reqs_cnt	= ARRAY_SIZE(omap3xxx_mcbsp1_sdma_chs),
+	.main_clk	= "mcbsp1_fck",
+	.prcm		= {
+		.omap2 = {
+			.prcm_reg_id = 1,
+			.module_bit = OMAP3430_EN_MCBSP1_SHIFT,
+			.module_offs = CORE_MOD,
+			.idlest_reg_id = 1,
+			.idlest_idle_bit = OMAP3430_EN_MCBSP1_SHIFT,
+		},
+	},
+	.slaves		= omap3xxx_mcbsp1_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap3xxx_mcbsp1_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* mcbsp2 */
+static struct omap_hwmod_irq_info omap3xxx_mcbsp2_irqs[] = {
+	{ .name = "irq", .irq = 17 },
+	{ .name = "tx", .irq = 62 },
+	{ .name = "rx", .irq = 63 },
+};
+
+static struct omap_hwmod_dma_info omap3xxx_mcbsp2_sdma_chs[] = {
+	{ .name = "rx", .dma_req = 34 },
+	{ .name = "tx", .dma_req = 33 },
+};
+
+static struct omap_hwmod_addr_space omap3xxx_mcbsp2_addrs[] = {
+	{
+		.pa_start	= 0x49022000,
+		.pa_end		= 0x490220ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+/* l4_per -> mcbsp2 */
+static struct omap_hwmod_ocp_if omap3xxx_l4_per__mcbsp2 = {
+	.master		= &omap3xxx_l4_per_hwmod,
+	.slave		= &omap3xxx_mcbsp2_hwmod,
+	.clk		= "mcbsp2_ick",
+	.addr		= omap3xxx_mcbsp2_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap3xxx_mcbsp2_addrs),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mcbsp2 slave ports */
+static struct omap_hwmod_ocp_if *omap3xxx_mcbsp2_slaves[] = {
+	&omap3xxx_l4_per__mcbsp2,
+};
+
+static struct omap_hwmod omap3xxx_mcbsp2_hwmod = {
+	.name		= "mcbsp2",
+	.class		= &omap3xxx_mcbsp_hwmod_class,
+	.mpu_irqs	= omap3xxx_mcbsp2_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap3xxx_mcbsp2_irqs),
+	.sdma_reqs	= omap3xxx_mcbsp2_sdma_chs,
+	.sdma_reqs_cnt	= ARRAY_SIZE(omap3xxx_mcbsp2_sdma_chs),
+	.main_clk	= "mcbsp2_fck",
+	.prcm		= {
+		.omap2 = {
+			.prcm_reg_id = 1,
+			.module_bit = OMAP3430_EN_MCBSP2_SHIFT,
+			.module_offs = OMAP3430_PER_MOD,
+			.idlest_reg_id = 1,
+			.idlest_idle_bit = OMAP3430_EN_MCBSP2_SHIFT,
+		},
+	},
+	.slaves		= omap3xxx_mcbsp2_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap3xxx_mcbsp2_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* mcbsp3 */
+static struct omap_hwmod_irq_info omap3xxx_mcbsp3_irqs[] = {
+	{ .name = "irq", .irq = 22 },
+	{ .name = "tx", .irq = 89 },
+	{ .name = "rx", .irq = 90 },
+};
+
+static struct omap_hwmod_dma_info omap3xxx_mcbsp3_sdma_chs[] = {
+	{ .name = "rx", .dma_req = 18 },
+	{ .name = "tx", .dma_req = 17 },
+};
+
+static struct omap_hwmod_addr_space omap3xxx_mcbsp3_addrs[] = {
+	{
+		.pa_start	= 0x49024000,
+		.pa_end		= 0x490240ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+/* l4_per -> mcbsp3 */
+static struct omap_hwmod_ocp_if omap3xxx_l4_per__mcbsp3 = {
+	.master		= &omap3xxx_l4_per_hwmod,
+	.slave		= &omap3xxx_mcbsp3_hwmod,
+	.clk		= "mcbsp3_ick",
+	.addr		= omap3xxx_mcbsp3_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap3xxx_mcbsp3_addrs),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mcbsp3 slave ports */
+static struct omap_hwmod_ocp_if *omap3xxx_mcbsp3_slaves[] = {
+	&omap3xxx_l4_per__mcbsp3,
+};
+
+static struct omap_hwmod omap3xxx_mcbsp3_hwmod = {
+	.name		= "mcbsp3",
+	.class		= &omap3xxx_mcbsp_hwmod_class,
+	.mpu_irqs	= omap3xxx_mcbsp3_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap3xxx_mcbsp3_irqs),
+	.sdma_reqs	= omap3xxx_mcbsp3_sdma_chs,
+	.sdma_reqs_cnt	= ARRAY_SIZE(omap3xxx_mcbsp3_sdma_chs),
+	.main_clk	= "mcbsp3_fck",
+	.prcm		= {
+		.omap2 = {
+			.prcm_reg_id = 1,
+			.module_bit = OMAP3430_EN_MCBSP3_SHIFT,
+			.module_offs = OMAP3430_PER_MOD,
+			.idlest_reg_id = 1,
+			.idlest_idle_bit = OMAP3430_EN_MCBSP3_SHIFT,
+		},
+	},
+	.slaves		= omap3xxx_mcbsp3_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap3xxx_mcbsp3_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* mcbsp4 */
+static struct omap_hwmod_irq_info omap3xxx_mcbsp4_irqs[] = {
+	{ .name = "irq", .irq = 23 },
+	{ .name = "tx", .irq = 54 },
+	{ .name = "rx", .irq = 55 },
+};
+
+static struct omap_hwmod_dma_info omap3xxx_mcbsp4_sdma_chs[] = {
+	{ .name = "rx", .dma_req = 20 },
+	{ .name = "tx", .dma_req = 19 },
+};
+
+static struct omap_hwmod_addr_space omap3xxx_mcbsp4_addrs[] = {
+	{
+		.pa_start	= 0x49026000,
+		.pa_end		= 0x490260ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+/* l4_per -> mcbsp4 */
+static struct omap_hwmod_ocp_if omap3xxx_l4_per__mcbsp4 = {
+	.master		= &omap3xxx_l4_per_hwmod,
+	.slave		= &omap3xxx_mcbsp4_hwmod,
+	.clk		= "mcbsp4_ick",
+	.addr		= omap3xxx_mcbsp4_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap3xxx_mcbsp4_addrs),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mcbsp4 slave ports */
+static struct omap_hwmod_ocp_if *omap3xxx_mcbsp4_slaves[] = {
+	&omap3xxx_l4_per__mcbsp4,
+};
+
+static struct omap_hwmod omap3xxx_mcbsp4_hwmod = {
+	.name		= "mcbsp4",
+	.class		= &omap3xxx_mcbsp_hwmod_class,
+	.mpu_irqs	= omap3xxx_mcbsp4_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap3xxx_mcbsp4_irqs),
+	.sdma_reqs	= omap3xxx_mcbsp4_sdma_chs,
+	.sdma_reqs_cnt	= ARRAY_SIZE(omap3xxx_mcbsp4_sdma_chs),
+	.main_clk	= "mcbsp4_fck",
+	.prcm		= {
+		.omap2 = {
+			.prcm_reg_id = 1,
+			.module_bit = OMAP3430_EN_MCBSP4_SHIFT,
+			.module_offs = OMAP3430_PER_MOD,
+			.idlest_reg_id = 1,
+			.idlest_idle_bit = OMAP3430_EN_MCBSP4_SHIFT,
+		},
+	},
+	.slaves		= omap3xxx_mcbsp4_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap3xxx_mcbsp4_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* mcbsp5 */
+static struct omap_hwmod_irq_info omap3xxx_mcbsp5_irqs[] = {
+	{ .name = "irq", .irq = 27 },
+	{ .name = "tx", .irq = 81 },
+	{ .name = "rx", .irq = 82 },
+};
+
+static struct omap_hwmod_dma_info omap3xxx_mcbsp5_sdma_chs[] = {
+	{ .name = "rx", .dma_req = 22 },
+	{ .name = "tx", .dma_req = 21 },
+};
+
+static struct omap_hwmod_addr_space omap3xxx_mcbsp5_addrs[] = {
+	{
+		.pa_start	= 0x48096000,
+		.pa_end		= 0x480960ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+/* l4_core -> mcbsp5 */
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__mcbsp5 = {
+	.master		= &omap3xxx_l4_core_hwmod,
+	.slave		= &omap3xxx_mcbsp5_hwmod,
+	.clk		= "mcbsp5_ick",
+	.addr		= omap3xxx_mcbsp5_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap3xxx_mcbsp5_addrs),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mcbsp5 slave ports */
+static struct omap_hwmod_ocp_if *omap3xxx_mcbsp5_slaves[] = {
+	&omap3xxx_l4_core__mcbsp5,
+};
+
+static struct omap_hwmod omap3xxx_mcbsp5_hwmod = {
+	.name		= "mcbsp5",
+	.class		= &omap3xxx_mcbsp_hwmod_class,
+	.mpu_irqs	= omap3xxx_mcbsp5_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap3xxx_mcbsp5_irqs),
+	.sdma_reqs	= omap3xxx_mcbsp5_sdma_chs,
+	.sdma_reqs_cnt	= ARRAY_SIZE(omap3xxx_mcbsp5_sdma_chs),
+	.main_clk	= "mcbsp5_fck",
+	.prcm		= {
+		.omap2 = {
+			.prcm_reg_id = 1,
+			.module_bit = OMAP3430_EN_MCBSP5_SHIFT,
+			.module_offs = CORE_MOD,
+			.idlest_reg_id = 1,
+			.idlest_idle_bit = OMAP3430_EN_MCBSP5_SHIFT,
+		},
+	},
+	.slaves		= omap3xxx_mcbsp5_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap3xxx_mcbsp5_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+/* 'mcbsp sidetone' class */
+
+static struct omap_hwmod_class_sysconfig omap3xxx_mcbsp_sidetone_sysc = {
+	.sysc_offs	= 0x0010,
+	.sysc_flags	= SYSC_HAS_AUTOIDLE,
+	.sysc_fields	= &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap3xxx_mcbsp_sidetone_hwmod_class = {
+	.name = "mcbsp_sidetone",
+	.sysc = &omap3xxx_mcbsp_sidetone_sysc,
+};
+
+/* mcbsp2_sidetone */
+static struct omap_hwmod_irq_info omap3xxx_mcbsp2_sidetone_irqs[] = {
+	{ .name = "irq", .irq = 4 },
+};
+
+static struct omap_hwmod_addr_space omap3xxx_mcbsp2_sidetone_addrs[] = {
+	{
+		.pa_start	= 0x49028000,
+		.pa_end		= 0x490280ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+/* l4_per -> mcbsp2_sidetone */
+static struct omap_hwmod_ocp_if omap3xxx_l4_per__mcbsp2_sidetone = {
+	.master		= &omap3xxx_l4_per_hwmod,
+	.slave		= &omap3xxx_mcbsp2_sidetone_hwmod,
+	.clk		= "mcbsp2_ick",
+	.addr		= omap3xxx_mcbsp2_sidetone_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap3xxx_mcbsp2_sidetone_addrs),
+	.user		= OCP_USER_MPU,
+};
+
+/* mcbsp2_sidetone slave ports */
+static struct omap_hwmod_ocp_if *omap3xxx_mcbsp2_sidetone_slaves[] = {
+	&omap3xxx_l4_per__mcbsp2_sidetone,
+};
+
+static struct omap_hwmod omap3xxx_mcbsp2_sidetone_hwmod = {
+	.name		= "mcbsp2_sidetone",
+	.class		= &omap3xxx_mcbsp_sidetone_hwmod_class,
+	.mpu_irqs	= omap3xxx_mcbsp2_sidetone_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap3xxx_mcbsp2_sidetone_irqs),
+	.main_clk	= "mcbsp2_fck",
+	.prcm		= {
+		.omap2 = {
+			.prcm_reg_id = 1,
+			 .module_bit = OMAP3430_EN_MCBSP2_SHIFT,
+			.module_offs = OMAP3430_PER_MOD,
+			.idlest_reg_id = 1,
+			.idlest_idle_bit = OMAP3430_EN_MCBSP2_SHIFT,
+		},
+	},
+	.slaves		= omap3xxx_mcbsp2_sidetone_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap3xxx_mcbsp2_sidetone_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* mcbsp3_sidetone */
+static struct omap_hwmod_irq_info omap3xxx_mcbsp3_sidetone_irqs[] = {
+	{ .name = "irq", .irq = 5 },
+};
+
+static struct omap_hwmod_addr_space omap3xxx_mcbsp3_sidetone_addrs[] = {
+	{
+		.pa_start	= 0x4902A000,
+		.pa_end		= 0x4902A0ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+/* l4_per -> mcbsp3_sidetone */
+static struct omap_hwmod_ocp_if omap3xxx_l4_per__mcbsp3_sidetone = {
+	.master		= &omap3xxx_l4_per_hwmod,
+	.slave		= &omap3xxx_mcbsp3_sidetone_hwmod,
+	.clk		= "mcbsp3_ick",
+	.addr		= omap3xxx_mcbsp3_sidetone_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap3xxx_mcbsp3_sidetone_addrs),
+	.user		= OCP_USER_MPU,
+};
+
+/* mcbsp3_sidetone slave ports */
+static struct omap_hwmod_ocp_if *omap3xxx_mcbsp3_sidetone_slaves[] = {
+	&omap3xxx_l4_per__mcbsp3_sidetone,
+};
+
+static struct omap_hwmod omap3xxx_mcbsp3_sidetone_hwmod = {
+	.name		= "mcbsp3_sidetone",
+	.class		= &omap3xxx_mcbsp_sidetone_hwmod_class,
+	.mpu_irqs	= omap3xxx_mcbsp3_sidetone_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap3xxx_mcbsp3_sidetone_irqs),
+	.main_clk	= "mcbsp3_fck",
+	.prcm		= {
+		.omap2 = {
+			.prcm_reg_id = 1,
+			.module_bit = OMAP3430_EN_MCBSP3_SHIFT,
+			.module_offs = OMAP3430_PER_MOD,
+			.idlest_reg_id = 1,
+			.idlest_idle_bit = OMAP3430_EN_MCBSP3_SHIFT,
+		},
+	},
+	.slaves		= omap3xxx_mcbsp3_sidetone_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap3xxx_mcbsp3_sidetone_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
 static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
 	&omap3xxx_l3_main_hwmod,
 	&omap3xxx_l4_core_hwmod,
@@ -521,6 +940,13 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
 	&omap3xxx_uart2_hwmod,
 	&omap3xxx_uart3_hwmod,
 	&omap3xxx_uart4_hwmod,
+	&omap3xxx_mcbsp1_hwmod,
+	&omap3xxx_mcbsp2_hwmod,
+	&omap3xxx_mcbsp3_hwmod,
+	&omap3xxx_mcbsp4_hwmod,
+	&omap3xxx_mcbsp5_hwmod,
+	&omap3xxx_mcbsp2_sidetone_hwmod,
+	&omap3xxx_mcbsp3_sidetone_hwmod,
 	NULL,
 };
 
Signature · 1 line
1.7.0.4
#2 lore raw

RFC PATCH 3/7 OMAP: MCBSP: hwmod database for 4xxx devices

In reply to Kishon Vijay Abraham I

From: Benoit Cousson <[email protected]>

MCBSP hwmod data values are auto-generated. The order of omap44xx_mcbsp3_slaves contents are changed since the driver uses the base address of omap44xx_l4_abe__mcbsp3_dma.

---
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c |  293 ++++++++++++++++++++++++++++
 1 files changed, 293 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/omap_hwmod_44xx_data.c +293 -0
index 7274db4..1467840 100644
@@ -811,6 +811,294 @@ static struct omap_hwmod omap44xx_uart4_hwmod = {
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
 };
 
+/*
+ * 'mcbsp' class
+ * multi channel buffered serial port controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_mcbsp_sysc = {
+	.sysc_offs	= 0x008c,
+	.sysc_flags	= (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_ENAWAKEUP |
+			   SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+	.sysc_fields	= &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap44xx_mcbsp_hwmod_class = {
+	.name = "mcbsp",
+	.sysc = &omap44xx_mcbsp_sysc,
+};
+
+/* mcbsp1 */
+static struct omap_hwmod omap44xx_mcbsp1_hwmod;
+static struct omap_hwmod_irq_info omap44xx_mcbsp1_irqs[] = {
+	{ .name = "tx", .irq = 17 + OMAP44XX_IRQ_GIC_START },
+	{ .name = "rx", .irq = 0 },
+};
+
+static struct omap_hwmod_dma_info omap44xx_mcbsp1_sdma_reqs[] = {
+	{ .name = "tx", .dma_req = 32 + OMAP44XX_DMA_REQ_START },
+	{ .name = "rx", .dma_req = 33 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_mcbsp1_addrs[] = {
+	{
+		.pa_start	= 0x40122000,
+		.pa_end		= 0x401220ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+/* l4_abe -> mcbsp1 */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp1 = {
+	.master		= &omap44xx_l4_abe_hwmod,
+	.slave		= &omap44xx_mcbsp1_hwmod,
+	.clk		= "ocp_abe_iclk",
+	.addr		= omap44xx_mcbsp1_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap44xx_mcbsp1_addrs),
+	.user		= OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space omap44xx_mcbsp1_dma_addrs[] = {
+	{
+		.pa_start	= 0x49022000,
+		.pa_end		= 0x490220ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+/* l4_abe -> mcbsp1 (dma) */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp1_dma = {
+	.master		= &omap44xx_l4_abe_hwmod,
+	.slave		= &omap44xx_mcbsp1_hwmod,
+	.clk		= "ocp_abe_iclk",
+	.addr		= omap44xx_mcbsp1_dma_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap44xx_mcbsp1_dma_addrs),
+	.user		= OCP_USER_SDMA,
+};
+
+/* mcbsp1 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_mcbsp1_slaves[] = {
+	&omap44xx_l4_abe__mcbsp1_dma,
+	&omap44xx_l4_abe__mcbsp1,
+};
+
+static struct omap_hwmod omap44xx_mcbsp1_hwmod = {
+	.name		= "mcbsp1",
+	.class		= &omap44xx_mcbsp_hwmod_class,
+	.mpu_irqs	= omap44xx_mcbsp1_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap44xx_mcbsp1_irqs),
+	.sdma_reqs	= omap44xx_mcbsp1_sdma_reqs,
+	.sdma_reqs_cnt	= ARRAY_SIZE(omap44xx_mcbsp1_sdma_reqs),
+	.main_clk	= "mcbsp1_fck",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_reg = OMAP4430_CM1_ABE_MCBSP1_CLKCTRL,
+		},
+	},
+	.slaves		= omap44xx_mcbsp1_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap44xx_mcbsp1_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* mcbsp2 */
+static struct omap_hwmod omap44xx_mcbsp2_hwmod;
+static struct omap_hwmod_irq_info omap44xx_mcbsp2_irqs[] = {
+	{ .name = "tx", .irq = 22 + OMAP44XX_IRQ_GIC_START },
+	{ .name = "rx", .irq = 0 },
+};
+
+static struct omap_hwmod_dma_info omap44xx_mcbsp2_sdma_reqs[] = {
+	{ .name = "tx", .dma_req = 16 + OMAP44XX_DMA_REQ_START },
+	{ .name = "rx", .dma_req = 17 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_mcbsp2_addrs[] = {
+	{
+		.pa_start	= 0x40124000,
+		.pa_end		= 0x401240ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+/* l4_abe -> mcbsp2 */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp2 = {
+	.master		= &omap44xx_l4_abe_hwmod,
+	.slave		= &omap44xx_mcbsp2_hwmod,
+	.clk		= "ocp_abe_iclk",
+	.addr		= omap44xx_mcbsp2_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap44xx_mcbsp2_addrs),
+	.user		= OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space omap44xx_mcbsp2_dma_addrs[] = {
+	{
+		.pa_start	= 0x49024000,
+		.pa_end		= 0x490240ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+/* l4_abe -> mcbsp2 (dma) */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp2_dma = {
+	.master		= &omap44xx_l4_abe_hwmod,
+	.slave		= &omap44xx_mcbsp2_hwmod,
+	.clk		= "ocp_abe_iclk",
+	.addr		= omap44xx_mcbsp2_dma_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap44xx_mcbsp2_dma_addrs),
+	.user		= OCP_USER_SDMA,
+};
+
+/* mcbsp2 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_mcbsp2_slaves[] = {
+	&omap44xx_l4_abe__mcbsp2_dma,
+	&omap44xx_l4_abe__mcbsp2,
+};
+
+static struct omap_hwmod omap44xx_mcbsp2_hwmod = {
+	.name		= "mcbsp2",
+	.class		= &omap44xx_mcbsp_hwmod_class,
+	.mpu_irqs	= omap44xx_mcbsp2_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap44xx_mcbsp2_irqs),
+	.sdma_reqs	= omap44xx_mcbsp2_sdma_reqs,
+	.sdma_reqs_cnt	= ARRAY_SIZE(omap44xx_mcbsp2_sdma_reqs),
+	.main_clk	= "mcbsp2_fck",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_reg = OMAP4430_CM1_ABE_MCBSP2_CLKCTRL,
+		},
+	},
+	.slaves		= omap44xx_mcbsp2_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap44xx_mcbsp2_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* mcbsp3 */
+static struct omap_hwmod omap44xx_mcbsp3_hwmod;
+static struct omap_hwmod_irq_info omap44xx_mcbsp3_irqs[] = {
+	{ .name = "tx", .irq = 23 + OMAP44XX_IRQ_GIC_START },
+	{ .name = "rx", .irq = 0 },
+};
+
+static struct omap_hwmod_dma_info omap44xx_mcbsp3_sdma_reqs[] = {
+	{ .name = "tx", .dma_req = 18 + OMAP44XX_DMA_REQ_START },
+	{ .name = "rx", .dma_req = 19 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_mcbsp3_addrs[] = {
+	{
+		.pa_start	= 0x40126000,
+		.pa_end		= 0x401260ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+/* l4_abe -> mcbsp3 */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp3 = {
+	.master		= &omap44xx_l4_abe_hwmod,
+	.slave		= &omap44xx_mcbsp3_hwmod,
+	.clk		= "ocp_abe_iclk",
+	.addr		= omap44xx_mcbsp3_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap44xx_mcbsp3_addrs),
+	.user		= OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space omap44xx_mcbsp3_dma_addrs[] = {
+	{
+		.pa_start	= 0x49026000,
+		.pa_end		= 0x490260ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+/* l4_abe -> mcbsp3 (dma) */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp3_dma = {
+	.master		= &omap44xx_l4_abe_hwmod,
+	.slave		= &omap44xx_mcbsp3_hwmod,
+	.clk		= "ocp_abe_iclk",
+	.addr		= omap44xx_mcbsp3_dma_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap44xx_mcbsp3_dma_addrs),
+	.user		= OCP_USER_SDMA,
+};
+
+/* mcbsp3 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_mcbsp3_slaves[] = {
+	&omap44xx_l4_abe__mcbsp3_dma,
+	&omap44xx_l4_abe__mcbsp3,
+};
+
+static struct omap_hwmod omap44xx_mcbsp3_hwmod = {
+	.name		= "mcbsp3",
+	.class		= &omap44xx_mcbsp_hwmod_class,
+	.mpu_irqs	= omap44xx_mcbsp3_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap44xx_mcbsp3_irqs),
+	.sdma_reqs	= omap44xx_mcbsp3_sdma_reqs,
+	.sdma_reqs_cnt	= ARRAY_SIZE(omap44xx_mcbsp3_sdma_reqs),
+	.main_clk	= "mcbsp3_fck",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_reg = OMAP4430_CM1_ABE_MCBSP3_CLKCTRL,
+		},
+	},
+	.slaves		= omap44xx_mcbsp3_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap44xx_mcbsp3_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* mcbsp4 */
+static struct omap_hwmod omap44xx_mcbsp4_hwmod;
+static struct omap_hwmod_irq_info omap44xx_mcbsp4_irqs[] = {
+	{ .name = "tx", .irq = 16 + OMAP44XX_IRQ_GIC_START },
+	{ .name = "rx", .irq = 0 },
+};
+
+static struct omap_hwmod_dma_info omap44xx_mcbsp4_sdma_reqs[] = {
+	{ .name = "tx", .dma_req = 30 + OMAP44XX_DMA_REQ_START },
+	{ .name = "rx", .dma_req = 31 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_mcbsp4_addrs[] = {
+	{
+		.pa_start	= 0x48096000,
+		.pa_end		= 0x480960ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+/* l4_per -> mcbsp4 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__mcbsp4 = {
+	.master		= &omap44xx_l4_per_hwmod,
+	.slave		= &omap44xx_mcbsp4_hwmod,
+	.clk		= "l4_div_ck",
+	.addr		= omap44xx_mcbsp4_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap44xx_mcbsp4_addrs),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mcbsp4 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_mcbsp4_slaves[] = {
+	&omap44xx_l4_per__mcbsp4,
+};
+
+static struct omap_hwmod omap44xx_mcbsp4_hwmod = {
+	.name		= "mcbsp4",
+	.class		= &omap44xx_mcbsp_hwmod_class,
+	.mpu_irqs	= omap44xx_mcbsp4_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap44xx_mcbsp4_irqs),
+	.sdma_reqs	= omap44xx_mcbsp4_sdma_reqs,
+	.sdma_reqs_cnt	= ARRAY_SIZE(omap44xx_mcbsp4_sdma_reqs),
+	.main_clk	= "mcbsp4_fck",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_reg = OMAP4430_CM_L4PER_MCBSP4_CLKCTRL,
+		},
+	},
+	.slaves		= omap44xx_mcbsp4_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap44xx_mcbsp4_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+
 static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
 	/* dmm class */
 	&omap44xx_dmm_hwmod,
@@ -840,6 +1128,11 @@ static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
 	&omap44xx_uart2_hwmod,
 	&omap44xx_uart3_hwmod,
 	&omap44xx_uart4_hwmod,
+	/* mcbsp class */
+	&omap44xx_mcbsp1_hwmod,
+	&omap44xx_mcbsp2_hwmod,
+	&omap44xx_mcbsp3_hwmod,
+	&omap44xx_mcbsp4_hwmod,
 	NULL,
 };
 
Signature · 1 line
1.7.0.4
#3 lore raw

Re: [PATCH 3/7] [RFC] OMAP: MCBSP: hwmod database for 4xxx devices

Hi Kishon,

Quoted 5 lines · KISHON VIJAY

From: Benoit Cousson<[email protected]>

MCBSP hwmod data values are auto-generated. The order of omap44xx_mcbsp3_slaves contents are changed since the driver uses the base address of omap44xx_l4_abe__mcbsp3_dma.

You should not do that... in theory.
In your case I do understand why, but we should find a better way to handle that. Ideally you should not rely on the order to get the proper resource. For some reason the memory areas are not named today, but this can be fixed if needed.

The other concern or question is don't we have to use direct access whenever possible? The second mapping is only needed for the SDMA access, not for the registers accesses.

So in your case, you will have to use two base address, for previous OMAPs, both will be the same, but in the case of OMAP4, you will use the direct one for all the register settings and the DMA one for DMA access.

Benoit

Quoted 320 lines
---
  arch/arm/mach-omap2/omap_hwmod_44xx_data.c |  293 ++++++++++++++++++++++++++++
  1 files changed, 293 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/omap_hwmod_44xx_data.c +293 -0
index 7274db4..1467840 100644
@@ -811,6 +811,294 @@ static struct omap_hwmod omap44xx_uart4_hwmod = {
  	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
  };
 
+/*
+ * 'mcbsp' class
+ * multi channel buffered serial port controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_mcbsp_sysc = {
+	.sysc_offs	= 0x008c,
+	.sysc_flags	= (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_ENAWAKEUP |
+			   SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+	.sysc_fields	=&omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap44xx_mcbsp_hwmod_class = {
+	.name = "mcbsp",
+	.sysc =&omap44xx_mcbsp_sysc,
+};
+
+/* mcbsp1 */
+static struct omap_hwmod omap44xx_mcbsp1_hwmod;
+static struct omap_hwmod_irq_info omap44xx_mcbsp1_irqs[] = {
+	{ .name = "tx", .irq = 17 + OMAP44XX_IRQ_GIC_START },
+	{ .name = "rx", .irq = 0 },
+};
+
+static struct omap_hwmod_dma_info omap44xx_mcbsp1_sdma_reqs[] = {
+	{ .name = "tx", .dma_req = 32 + OMAP44XX_DMA_REQ_START },
+	{ .name = "rx", .dma_req = 33 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_mcbsp1_addrs[] = {
+	{
+		.pa_start	= 0x40122000,
+		.pa_end		= 0x401220ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+/* l4_abe ->  mcbsp1 */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp1 = {
+	.master		=&omap44xx_l4_abe_hwmod,
+	.slave		=&omap44xx_mcbsp1_hwmod,
+	.clk		= "ocp_abe_iclk",
+	.addr		= omap44xx_mcbsp1_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap44xx_mcbsp1_addrs),
+	.user		= OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space omap44xx_mcbsp1_dma_addrs[] = {
+	{
+		.pa_start	= 0x49022000,
+		.pa_end		= 0x490220ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+/* l4_abe ->  mcbsp1 (dma) */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp1_dma = {
+	.master		=&omap44xx_l4_abe_hwmod,
+	.slave		=&omap44xx_mcbsp1_hwmod,
+	.clk		= "ocp_abe_iclk",
+	.addr		= omap44xx_mcbsp1_dma_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap44xx_mcbsp1_dma_addrs),
+	.user		= OCP_USER_SDMA,
+};
+
+/* mcbsp1 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_mcbsp1_slaves[] = {
+	&omap44xx_l4_abe__mcbsp1_dma,
+	&omap44xx_l4_abe__mcbsp1,
+};
+
+static struct omap_hwmod omap44xx_mcbsp1_hwmod = {
+	.name		= "mcbsp1",
+	.class		=&omap44xx_mcbsp_hwmod_class,
+	.mpu_irqs	= omap44xx_mcbsp1_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap44xx_mcbsp1_irqs),
+	.sdma_reqs	= omap44xx_mcbsp1_sdma_reqs,
+	.sdma_reqs_cnt	= ARRAY_SIZE(omap44xx_mcbsp1_sdma_reqs),
+	.main_clk	= "mcbsp1_fck",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_reg = OMAP4430_CM1_ABE_MCBSP1_CLKCTRL,
+		},
+	},
+	.slaves		= omap44xx_mcbsp1_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap44xx_mcbsp1_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* mcbsp2 */
+static struct omap_hwmod omap44xx_mcbsp2_hwmod;
+static struct omap_hwmod_irq_info omap44xx_mcbsp2_irqs[] = {
+	{ .name = "tx", .irq = 22 + OMAP44XX_IRQ_GIC_START },
+	{ .name = "rx", .irq = 0 },
+};
+
+static struct omap_hwmod_dma_info omap44xx_mcbsp2_sdma_reqs[] = {
+	{ .name = "tx", .dma_req = 16 + OMAP44XX_DMA_REQ_START },
+	{ .name = "rx", .dma_req = 17 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_mcbsp2_addrs[] = {
+	{
+		.pa_start	= 0x40124000,
+		.pa_end		= 0x401240ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+/* l4_abe ->  mcbsp2 */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp2 = {
+	.master		=&omap44xx_l4_abe_hwmod,
+	.slave		=&omap44xx_mcbsp2_hwmod,
+	.clk		= "ocp_abe_iclk",
+	.addr		= omap44xx_mcbsp2_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap44xx_mcbsp2_addrs),
+	.user		= OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space omap44xx_mcbsp2_dma_addrs[] = {
+	{
+		.pa_start	= 0x49024000,
+		.pa_end		= 0x490240ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+/* l4_abe ->  mcbsp2 (dma) */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp2_dma = {
+	.master		=&omap44xx_l4_abe_hwmod,
+	.slave		=&omap44xx_mcbsp2_hwmod,
+	.clk		= "ocp_abe_iclk",
+	.addr		= omap44xx_mcbsp2_dma_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap44xx_mcbsp2_dma_addrs),
+	.user		= OCP_USER_SDMA,
+};
+
+/* mcbsp2 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_mcbsp2_slaves[] = {
+	&omap44xx_l4_abe__mcbsp2_dma,
+	&omap44xx_l4_abe__mcbsp2,
+};
+
+static struct omap_hwmod omap44xx_mcbsp2_hwmod = {
+	.name		= "mcbsp2",
+	.class		=&omap44xx_mcbsp_hwmod_class,
+	.mpu_irqs	= omap44xx_mcbsp2_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap44xx_mcbsp2_irqs),
+	.sdma_reqs	= omap44xx_mcbsp2_sdma_reqs,
+	.sdma_reqs_cnt	= ARRAY_SIZE(omap44xx_mcbsp2_sdma_reqs),
+	.main_clk	= "mcbsp2_fck",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_reg = OMAP4430_CM1_ABE_MCBSP2_CLKCTRL,
+		},
+	},
+	.slaves		= omap44xx_mcbsp2_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap44xx_mcbsp2_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* mcbsp3 */
+static struct omap_hwmod omap44xx_mcbsp3_hwmod;
+static struct omap_hwmod_irq_info omap44xx_mcbsp3_irqs[] = {
+	{ .name = "tx", .irq = 23 + OMAP44XX_IRQ_GIC_START },
+	{ .name = "rx", .irq = 0 },
+};
+
+static struct omap_hwmod_dma_info omap44xx_mcbsp3_sdma_reqs[] = {
+	{ .name = "tx", .dma_req = 18 + OMAP44XX_DMA_REQ_START },
+	{ .name = "rx", .dma_req = 19 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_mcbsp3_addrs[] = {
+	{
+		.pa_start	= 0x40126000,
+		.pa_end		= 0x401260ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+/* l4_abe ->  mcbsp3 */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp3 = {
+	.master		=&omap44xx_l4_abe_hwmod,
+	.slave		=&omap44xx_mcbsp3_hwmod,
+	.clk		= "ocp_abe_iclk",
+	.addr		= omap44xx_mcbsp3_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap44xx_mcbsp3_addrs),
+	.user		= OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space omap44xx_mcbsp3_dma_addrs[] = {
+	{
+		.pa_start	= 0x49026000,
+		.pa_end		= 0x490260ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+/* l4_abe ->  mcbsp3 (dma) */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp3_dma = {
+	.master		=&omap44xx_l4_abe_hwmod,
+	.slave		=&omap44xx_mcbsp3_hwmod,
+	.clk		= "ocp_abe_iclk",
+	.addr		= omap44xx_mcbsp3_dma_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap44xx_mcbsp3_dma_addrs),
+	.user		= OCP_USER_SDMA,
+};
+
+/* mcbsp3 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_mcbsp3_slaves[] = {
+	&omap44xx_l4_abe__mcbsp3_dma,
+	&omap44xx_l4_abe__mcbsp3,
+};
+
+static struct omap_hwmod omap44xx_mcbsp3_hwmod = {
+	.name		= "mcbsp3",
+	.class		=&omap44xx_mcbsp_hwmod_class,
+	.mpu_irqs	= omap44xx_mcbsp3_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap44xx_mcbsp3_irqs),
+	.sdma_reqs	= omap44xx_mcbsp3_sdma_reqs,
+	.sdma_reqs_cnt	= ARRAY_SIZE(omap44xx_mcbsp3_sdma_reqs),
+	.main_clk	= "mcbsp3_fck",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_reg = OMAP4430_CM1_ABE_MCBSP3_CLKCTRL,
+		},
+	},
+	.slaves		= omap44xx_mcbsp3_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap44xx_mcbsp3_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* mcbsp4 */
+static struct omap_hwmod omap44xx_mcbsp4_hwmod;
+static struct omap_hwmod_irq_info omap44xx_mcbsp4_irqs[] = {
+	{ .name = "tx", .irq = 16 + OMAP44XX_IRQ_GIC_START },
+	{ .name = "rx", .irq = 0 },
+};
+
+static struct omap_hwmod_dma_info omap44xx_mcbsp4_sdma_reqs[] = {
+	{ .name = "tx", .dma_req = 30 + OMAP44XX_DMA_REQ_START },
+	{ .name = "rx", .dma_req = 31 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_mcbsp4_addrs[] = {
+	{
+		.pa_start	= 0x48096000,
+		.pa_end		= 0x480960ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+/* l4_per ->  mcbsp4 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__mcbsp4 = {
+	.master		=&omap44xx_l4_per_hwmod,
+	.slave		=&omap44xx_mcbsp4_hwmod,
+	.clk		= "l4_div_ck",
+	.addr		= omap44xx_mcbsp4_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap44xx_mcbsp4_addrs),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mcbsp4 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_mcbsp4_slaves[] = {
+	&omap44xx_l4_per__mcbsp4,
+};
+
+static struct omap_hwmod omap44xx_mcbsp4_hwmod = {
+	.name		= "mcbsp4",
+	.class		=&omap44xx_mcbsp_hwmod_class,
+	.mpu_irqs	= omap44xx_mcbsp4_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap44xx_mcbsp4_irqs),
+	.sdma_reqs	= omap44xx_mcbsp4_sdma_reqs,
+	.sdma_reqs_cnt	= ARRAY_SIZE(omap44xx_mcbsp4_sdma_reqs),
+	.main_clk	= "mcbsp4_fck",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_reg = OMAP4430_CM_L4PER_MCBSP4_CLKCTRL,
+		},
+	},
+	.slaves		= omap44xx_mcbsp4_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap44xx_mcbsp4_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+
  static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
  	/* dmm class */
  	&omap44xx_dmm_hwmod,
@@ -840,6 +1128,11 @@ static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
  	&omap44xx_uart2_hwmod,
  	&omap44xx_uart3_hwmod,
  	&omap44xx_uart4_hwmod,
+	/* mcbsp class */
+	&omap44xx_mcbsp1_hwmod,
+	&omap44xx_mcbsp2_hwmod,
+	&omap44xx_mcbsp3_hwmod,
+	&omap44xx_mcbsp4_hwmod,
  	NULL,
  };
 
#4 lore raw

Re: [PATCH 3/7] [RFC] OMAP: MCBSP: hwmod database for 4xxx devices

Quoted 9 lines · Benoit

Hi Kishon,

Quoted 5 lines · KISHON VIJAY

From: Benoit Cousson<[email protected]>

MCBSP hwmod data values are auto-generated. The order of omap44xx_mcbsp3_slaves contents are changed since the driver uses the base address of omap44xx_l4_abe__mcbsp3_dma.

Quoted 5 lines

You should not do that... in theory.
In your case I do understand why, but we should find a better way to handle that. Ideally you should not rely on the order to get the proper resource. For some reason the memory areas are not named today, but this can be fixed if needed.

[Kishon]: Yeah. Even I felt naming the memory areas would be the best
way to solve this problem.

Quoted 4 lines

The other concern or question is don't we have to use direct access whenever possible? The second mapping is only needed for the SDMA access, not for the registers accesses.

[Kishon]: The SDMA can access the MCBSP register only through L3
interconnect whereas MPU can access the register either through its
internal bus or through L3 interconnect. So if we use *_dma address for MPU, the access will be through L3 interconnect. Using *_dma address will be sub-optimal since it has to go through L3 interconnect instead
of the internal bus.
We decided to use *_dma address so that we get rid of cpu checks
(since it's there only for OMAP4 and MCBSP1,2&3; MCBSP4 has 1 base
address)

Quoted 4 lines

So in your case, you will have to use two base address, for previous OMAPs, both will be the same, but in the case of OMAP4, you will use the direct one for all the register settings and the DMA one for DMA access.

[Kishon]: Yeah. Using duplicate base address for previous OMAP is a
good idea to get rid of the cpu checks (when we use both MPU address and DMA address).

Quoted 324 lines

Benoit

Quoted 320 lines
---
   arch/arm/mach-omap2/omap_hwmod_44xx_data.c |  293 ++++++++++++++++++++++++++++
   1 files changed, 293 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/omap_hwmod_44xx_data.c +293 -0
index 7274db4..1467840 100644
@@ -811,6 +811,294 @@ static struct omap_hwmod omap44xx_uart4_hwmod = {
   	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
   };
 
+/*
+ * 'mcbsp' class
+ * multi channel buffered serial port controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_mcbsp_sysc = {
+	.sysc_offs	= 0x008c,
+	.sysc_flags	= (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_ENAWAKEUP |
+			   SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+	.sysc_fields	=&omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap44xx_mcbsp_hwmod_class = {
+	.name = "mcbsp",
+	.sysc =&omap44xx_mcbsp_sysc,
+};
+
+/* mcbsp1 */
+static struct omap_hwmod omap44xx_mcbsp1_hwmod;
+static struct omap_hwmod_irq_info omap44xx_mcbsp1_irqs[] = {
+	{ .name = "tx", .irq = 17 + OMAP44XX_IRQ_GIC_START },
+	{ .name = "rx", .irq = 0 },
+};
+
+static struct omap_hwmod_dma_info omap44xx_mcbsp1_sdma_reqs[] = {
+	{ .name = "tx", .dma_req = 32 + OMAP44XX_DMA_REQ_START },
+	{ .name = "rx", .dma_req = 33 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_mcbsp1_addrs[] = {
+	{
+		.pa_start	= 0x40122000,
+		.pa_end		= 0x401220ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+/* l4_abe ->   mcbsp1 */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp1 = {
+	.master		=&omap44xx_l4_abe_hwmod,
+	.slave		=&omap44xx_mcbsp1_hwmod,
+	.clk		= "ocp_abe_iclk",
+	.addr		= omap44xx_mcbsp1_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap44xx_mcbsp1_addrs),
+	.user		= OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space omap44xx_mcbsp1_dma_addrs[] = {
+	{
+		.pa_start	= 0x49022000,
+		.pa_end		= 0x490220ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+/* l4_abe ->   mcbsp1 (dma) */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp1_dma = {
+	.master		=&omap44xx_l4_abe_hwmod,
+	.slave		=&omap44xx_mcbsp1_hwmod,
+	.clk		= "ocp_abe_iclk",
+	.addr		= omap44xx_mcbsp1_dma_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap44xx_mcbsp1_dma_addrs),
+	.user		= OCP_USER_SDMA,
+};
+
+/* mcbsp1 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_mcbsp1_slaves[] = {
+	&omap44xx_l4_abe__mcbsp1_dma,
+	&omap44xx_l4_abe__mcbsp1,
+};
+
+static struct omap_hwmod omap44xx_mcbsp1_hwmod = {
+	.name		= "mcbsp1",
+	.class		=&omap44xx_mcbsp_hwmod_class,
+	.mpu_irqs	= omap44xx_mcbsp1_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap44xx_mcbsp1_irqs),
+	.sdma_reqs	= omap44xx_mcbsp1_sdma_reqs,
+	.sdma_reqs_cnt	= ARRAY_SIZE(omap44xx_mcbsp1_sdma_reqs),
+	.main_clk	= "mcbsp1_fck",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_reg = OMAP4430_CM1_ABE_MCBSP1_CLKCTRL,
+		},
+	},
+	.slaves		= omap44xx_mcbsp1_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap44xx_mcbsp1_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* mcbsp2 */
+static struct omap_hwmod omap44xx_mcbsp2_hwmod;
+static struct omap_hwmod_irq_info omap44xx_mcbsp2_irqs[] = {
+	{ .name = "tx", .irq = 22 + OMAP44XX_IRQ_GIC_START },
+	{ .name = "rx", .irq = 0 },
+};
+
+static struct omap_hwmod_dma_info omap44xx_mcbsp2_sdma_reqs[] = {
+	{ .name = "tx", .dma_req = 16 + OMAP44XX_DMA_REQ_START },
+	{ .name = "rx", .dma_req = 17 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_mcbsp2_addrs[] = {
+	{
+		.pa_start	= 0x40124000,
+		.pa_end		= 0x401240ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+/* l4_abe ->   mcbsp2 */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp2 = {
+	.master		=&omap44xx_l4_abe_hwmod,
+	.slave		=&omap44xx_mcbsp2_hwmod,
+	.clk		= "ocp_abe_iclk",
+	.addr		= omap44xx_mcbsp2_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap44xx_mcbsp2_addrs),
+	.user		= OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space omap44xx_mcbsp2_dma_addrs[] = {
+	{
+		.pa_start	= 0x49024000,
+		.pa_end		= 0x490240ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+/* l4_abe ->   mcbsp2 (dma) */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp2_dma = {
+	.master		=&omap44xx_l4_abe_hwmod,
+	.slave		=&omap44xx_mcbsp2_hwmod,
+	.clk		= "ocp_abe_iclk",
+	.addr		= omap44xx_mcbsp2_dma_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap44xx_mcbsp2_dma_addrs),
+	.user		= OCP_USER_SDMA,
+};
+
+/* mcbsp2 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_mcbsp2_slaves[] = {
+	&omap44xx_l4_abe__mcbsp2_dma,
+	&omap44xx_l4_abe__mcbsp2,
+};
+
+static struct omap_hwmod omap44xx_mcbsp2_hwmod = {
+	.name		= "mcbsp2",
+	.class		=&omap44xx_mcbsp_hwmod_class,
+	.mpu_irqs	= omap44xx_mcbsp2_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap44xx_mcbsp2_irqs),
+	.sdma_reqs	= omap44xx_mcbsp2_sdma_reqs,
+	.sdma_reqs_cnt	= ARRAY_SIZE(omap44xx_mcbsp2_sdma_reqs),
+	.main_clk	= "mcbsp2_fck",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_reg = OMAP4430_CM1_ABE_MCBSP2_CLKCTRL,
+		},
+	},
+	.slaves		= omap44xx_mcbsp2_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap44xx_mcbsp2_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* mcbsp3 */
+static struct omap_hwmod omap44xx_mcbsp3_hwmod;
+static struct omap_hwmod_irq_info omap44xx_mcbsp3_irqs[] = {
+	{ .name = "tx", .irq = 23 + OMAP44XX_IRQ_GIC_START },
+	{ .name = "rx", .irq = 0 },
+};
+
+static struct omap_hwmod_dma_info omap44xx_mcbsp3_sdma_reqs[] = {
+	{ .name = "tx", .dma_req = 18 + OMAP44XX_DMA_REQ_START },
+	{ .name = "rx", .dma_req = 19 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_mcbsp3_addrs[] = {
+	{
+		.pa_start	= 0x40126000,
+		.pa_end		= 0x401260ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+/* l4_abe ->   mcbsp3 */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp3 = {
+	.master		=&omap44xx_l4_abe_hwmod,
+	.slave		=&omap44xx_mcbsp3_hwmod,
+	.clk		= "ocp_abe_iclk",
+	.addr		= omap44xx_mcbsp3_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap44xx_mcbsp3_addrs),
+	.user		= OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space omap44xx_mcbsp3_dma_addrs[] = {
+	{
+		.pa_start	= 0x49026000,
+		.pa_end		= 0x490260ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+/* l4_abe ->   mcbsp3 (dma) */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp3_dma = {
+	.master		=&omap44xx_l4_abe_hwmod,
+	.slave		=&omap44xx_mcbsp3_hwmod,
+	.clk		= "ocp_abe_iclk",
+	.addr		= omap44xx_mcbsp3_dma_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap44xx_mcbsp3_dma_addrs),
+	.user		= OCP_USER_SDMA,
+};
+
+/* mcbsp3 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_mcbsp3_slaves[] = {
+	&omap44xx_l4_abe__mcbsp3_dma,
+	&omap44xx_l4_abe__mcbsp3,
+};
+
+static struct omap_hwmod omap44xx_mcbsp3_hwmod = {
+	.name		= "mcbsp3",
+	.class		=&omap44xx_mcbsp_hwmod_class,
+	.mpu_irqs	= omap44xx_mcbsp3_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap44xx_mcbsp3_irqs),
+	.sdma_reqs	= omap44xx_mcbsp3_sdma_reqs,
+	.sdma_reqs_cnt	= ARRAY_SIZE(omap44xx_mcbsp3_sdma_reqs),
+	.main_clk	= "mcbsp3_fck",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_reg = OMAP4430_CM1_ABE_MCBSP3_CLKCTRL,
+		},
+	},
+	.slaves		= omap44xx_mcbsp3_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap44xx_mcbsp3_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* mcbsp4 */
+static struct omap_hwmod omap44xx_mcbsp4_hwmod;
+static struct omap_hwmod_irq_info omap44xx_mcbsp4_irqs[] = {
+	{ .name = "tx", .irq = 16 + OMAP44XX_IRQ_GIC_START },
+	{ .name = "rx", .irq = 0 },
+};
+
+static struct omap_hwmod_dma_info omap44xx_mcbsp4_sdma_reqs[] = {
+	{ .name = "tx", .dma_req = 30 + OMAP44XX_DMA_REQ_START },
+	{ .name = "rx", .dma_req = 31 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_mcbsp4_addrs[] = {
+	{
+		.pa_start	= 0x48096000,
+		.pa_end		= 0x480960ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+/* l4_per ->   mcbsp4 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__mcbsp4 = {
+	.master		=&omap44xx_l4_per_hwmod,
+	.slave		=&omap44xx_mcbsp4_hwmod,
+	.clk		= "l4_div_ck",
+	.addr		= omap44xx_mcbsp4_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap44xx_mcbsp4_addrs),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mcbsp4 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_mcbsp4_slaves[] = {
+	&omap44xx_l4_per__mcbsp4,
+};
+
+static struct omap_hwmod omap44xx_mcbsp4_hwmod = {
+	.name		= "mcbsp4",
+	.class		=&omap44xx_mcbsp_hwmod_class,
+	.mpu_irqs	= omap44xx_mcbsp4_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap44xx_mcbsp4_irqs),
+	.sdma_reqs	= omap44xx_mcbsp4_sdma_reqs,
+	.sdma_reqs_cnt	= ARRAY_SIZE(omap44xx_mcbsp4_sdma_reqs),
+	.main_clk	= "mcbsp4_fck",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_reg = OMAP4430_CM_L4PER_MCBSP4_CLKCTRL,
+		},
+	},
+	.slaves		= omap44xx_mcbsp4_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap44xx_mcbsp4_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+
   static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
   	/* dmm class */
   	&omap44xx_dmm_hwmod,
@@ -840,6 +1128,11 @@ static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
   	&omap44xx_uart2_hwmod,
   	&omap44xx_uart3_hwmod,
   	&omap44xx_uart4_hwmod,
+	/* mcbsp class */
+	&omap44xx_mcbsp1_hwmod,
+	&omap44xx_mcbsp2_hwmod,
+	&omap44xx_mcbsp3_hwmod,
+	&omap44xx_mcbsp4_hwmod,
   	NULL,
   };
 
#5 lore raw

RFC PATCH 4/7 OMAP: hwmod implementation for MCBSP

In reply to Kishon Vijay Abraham I
---
 arch/arm/mach-omap2/mcbsp.c             |  251 +++++++++----------------------
 arch/arm/plat-omap/include/plat/mcbsp.h |    6 +-
 arch/arm/plat-omap/mcbsp.c              |  189 +++++++++++-------------
 3 files changed, 159 insertions(+), 287 deletions(-)
arch/arm/mach-omap2/mcbsp.c +73 -178
index eba9fa1..25c6703 100644
@@ -22,9 +22,13 @@
 #include <plat/dma.h>
 #include <plat/cpu.h>
 #include <plat/mcbsp.h>
+#include <plat/omap_hwmod.h>
+#include <plat/omap_device.h>
 
 #include "control.h"
 
+static struct omap_hwmod *oh_st_device[] = {NULL, NULL};
+static int no_of_st;
 
 /* McBSP internal signal muxing functions */
 
@@ -101,199 +105,90 @@ int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id)
 }
 EXPORT_SYMBOL(omap2_mcbsp_set_clks_src);
 
-
-/* Platform data */
-
-#ifdef CONFIG_ARCH_OMAP2420
-static struct omap_mcbsp_platform_data omap2420_mcbsp_pdata[] = {
-	{
-		.phys_base	= OMAP24XX_MCBSP1_BASE,
-		.dma_rx_sync	= OMAP24XX_DMA_MCBSP1_RX,
-		.dma_tx_sync	= OMAP24XX_DMA_MCBSP1_TX,
-		.rx_irq		= INT_24XX_MCBSP1_IRQ_RX,
-		.tx_irq		= INT_24XX_MCBSP1_IRQ_TX,
-	},
+struct omap_device_pm_latency omap2_mcbsp_latency[] = {
 	{
-		.phys_base	= OMAP24XX_MCBSP2_BASE,
-		.dma_rx_sync	= OMAP24XX_DMA_MCBSP2_RX,
-		.dma_tx_sync	= OMAP24XX_DMA_MCBSP2_TX,
-		.rx_irq		= INT_24XX_MCBSP2_IRQ_RX,
-		.tx_irq		= INT_24XX_MCBSP2_IRQ_TX,
+		.deactivate_func = omap_device_idle_hwmods,
+		.activate_func   = omap_device_enable_hwmods,
+		.flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
 	},
 };
-#define OMAP2420_MCBSP_PDATA_SZ		ARRAY_SIZE(omap2420_mcbsp_pdata)
-#define OMAP2420_MCBSP_REG_NUM		(OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
-#else
-#define omap2420_mcbsp_pdata		NULL
-#define OMAP2420_MCBSP_PDATA_SZ		0
-#define OMAP2420_MCBSP_REG_NUM		0
-#endif
 
-#ifdef CONFIG_ARCH_OMAP2430
-static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = {
-	{
-		.phys_base	= OMAP24XX_MCBSP1_BASE,
-		.dma_rx_sync	= OMAP24XX_DMA_MCBSP1_RX,
-		.dma_tx_sync	= OMAP24XX_DMA_MCBSP1_TX,
-		.rx_irq		= INT_24XX_MCBSP1_IRQ_RX,
-		.tx_irq		= INT_24XX_MCBSP1_IRQ_TX,
-	},
-	{
-		.phys_base	= OMAP24XX_MCBSP2_BASE,
-		.dma_rx_sync	= OMAP24XX_DMA_MCBSP2_RX,
-		.dma_tx_sync	= OMAP24XX_DMA_MCBSP2_TX,
-		.rx_irq		= INT_24XX_MCBSP2_IRQ_RX,
-		.tx_irq		= INT_24XX_MCBSP2_IRQ_TX,
-	},
-	{
-		.phys_base	= OMAP2430_MCBSP3_BASE,
-		.dma_rx_sync	= OMAP24XX_DMA_MCBSP3_RX,
-		.dma_tx_sync	= OMAP24XX_DMA_MCBSP3_TX,
-		.rx_irq		= INT_24XX_MCBSP3_IRQ_RX,
-		.tx_irq		= INT_24XX_MCBSP3_IRQ_TX,
-	},
-	{
-		.phys_base	= OMAP2430_MCBSP4_BASE,
-		.dma_rx_sync	= OMAP24XX_DMA_MCBSP4_RX,
-		.dma_tx_sync	= OMAP24XX_DMA_MCBSP4_TX,
-		.rx_irq		= INT_24XX_MCBSP4_IRQ_RX,
-		.tx_irq		= INT_24XX_MCBSP4_IRQ_TX,
-	},
-	{
-		.phys_base	= OMAP2430_MCBSP5_BASE,
-		.dma_rx_sync	= OMAP24XX_DMA_MCBSP5_RX,
-		.dma_tx_sync	= OMAP24XX_DMA_MCBSP5_TX,
-		.rx_irq		= INT_24XX_MCBSP5_IRQ_RX,
-		.tx_irq		= INT_24XX_MCBSP5_IRQ_TX,
-	},
-};
-#define OMAP2430_MCBSP_PDATA_SZ		ARRAY_SIZE(omap2430_mcbsp_pdata)
-#define OMAP2430_MCBSP_REG_NUM		(OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
-#else
-#define omap2430_mcbsp_pdata		NULL
-#define OMAP2430_MCBSP_PDATA_SZ		0
-#define OMAP2430_MCBSP_REG_NUM		0
-#endif
+static int omap_init_mcbsp(struct omap_hwmod *oh, void *user)
+{
+	int id, count = 1, i;
+	char *name = "omap-mcbsp";
+	char dev_name[16];
+	struct omap_hwmod *oh_device[2];
+	struct omap_mcbsp_platform_data *pdata;
+	struct omap_device *od;
+
+	if (!oh) {
+		pr_err("%s:NULL hwmod pointer (oh)\n", __func__);
+		return -EINVAL;
+	}
 
-#ifdef CONFIG_ARCH_OMAP3
-static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
-	{
-		.phys_base	= OMAP34XX_MCBSP1_BASE,
-		.dma_rx_sync	= OMAP24XX_DMA_MCBSP1_RX,
-		.dma_tx_sync	= OMAP24XX_DMA_MCBSP1_TX,
-		.rx_irq		= INT_24XX_MCBSP1_IRQ_RX,
-		.tx_irq		= INT_24XX_MCBSP1_IRQ_TX,
-		.buffer_size	= 0x80, /* The FIFO has 128 locations */
-	},
-	{
-		.phys_base	= OMAP34XX_MCBSP2_BASE,
-		.phys_base_st	= OMAP34XX_MCBSP2_ST_BASE,
-		.dma_rx_sync	= OMAP24XX_DMA_MCBSP2_RX,
-		.dma_tx_sync	= OMAP24XX_DMA_MCBSP2_TX,
-		.rx_irq		= INT_24XX_MCBSP2_IRQ_RX,
-		.tx_irq		= INT_24XX_MCBSP2_IRQ_TX,
-		.buffer_size	= 0x500, /* The FIFO has 1024 + 256 locations */
-	},
-	{
-		.phys_base	= OMAP34XX_MCBSP3_BASE,
-		.phys_base_st	= OMAP34XX_MCBSP3_ST_BASE,
-		.dma_rx_sync	= OMAP24XX_DMA_MCBSP3_RX,
-		.dma_tx_sync	= OMAP24XX_DMA_MCBSP3_TX,
-		.rx_irq		= INT_24XX_MCBSP3_IRQ_RX,
-		.tx_irq		= INT_24XX_MCBSP3_IRQ_TX,
-		.buffer_size	= 0x80, /* The FIFO has 128 locations */
-	},
-	{
-		.phys_base	= OMAP34XX_MCBSP4_BASE,
-		.dma_rx_sync	= OMAP24XX_DMA_MCBSP4_RX,
-		.dma_tx_sync	= OMAP24XX_DMA_MCBSP4_TX,
-		.rx_irq		= INT_24XX_MCBSP4_IRQ_RX,
-		.tx_irq		= INT_24XX_MCBSP4_IRQ_TX,
-		.buffer_size	= 0x80, /* The FIFO has 128 locations */
-	},
-	{
-		.phys_base	= OMAP34XX_MCBSP5_BASE,
-		.dma_rx_sync	= OMAP24XX_DMA_MCBSP5_RX,
-		.dma_tx_sync	= OMAP24XX_DMA_MCBSP5_TX,
-		.rx_irq		= INT_24XX_MCBSP5_IRQ_RX,
-		.tx_irq		= INT_24XX_MCBSP5_IRQ_TX,
-		.buffer_size	= 0x80, /* The FIFO has 128 locations */
-	},
-};
-#define OMAP34XX_MCBSP_PDATA_SZ		ARRAY_SIZE(omap34xx_mcbsp_pdata)
-#define OMAP34XX_MCBSP_REG_NUM		(OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
-#else
-#define omap34xx_mcbsp_pdata		NULL
-#define OMAP34XX_MCBSP_PDATA_SZ		0
-#define OMAP34XX_MCBSP_REG_NUM		0
-#endif
+	pdata = kzalloc(sizeof(struct omap_mcbsp_platform_data), GFP_KERNEL);
+	if (!pdata) {
+		pr_err("%s: No memory for mcbsp\n", __func__);
+		return -ENOMEM;
+	}
 
-static struct omap_mcbsp_platform_data omap44xx_mcbsp_pdata[] = {
-	{
-		.phys_base      = OMAP44XX_MCBSP1_BASE,
-		.dma_rx_sync    = OMAP44XX_DMA_MCBSP1_RX,
-		.dma_tx_sync    = OMAP44XX_DMA_MCBSP1_TX,
-		.tx_irq         = OMAP44XX_IRQ_MCBSP1,
-	},
-	{
-		.phys_base      = OMAP44XX_MCBSP2_BASE,
-		.dma_rx_sync    = OMAP44XX_DMA_MCBSP2_RX,
-		.dma_tx_sync    = OMAP44XX_DMA_MCBSP2_TX,
-		.tx_irq         = OMAP44XX_IRQ_MCBSP2,
-		/* XXX .ops ? */
-	},
-	{
-		.phys_base      = OMAP44XX_MCBSP3_BASE,
-		.dma_rx_sync    = OMAP44XX_DMA_MCBSP3_RX,
-		.dma_tx_sync    = OMAP44XX_DMA_MCBSP3_TX,
-		.tx_irq         = OMAP44XX_IRQ_MCBSP3,
-		/* XXX .ops ? */
-	},
-	{
-		.phys_base      = OMAP44XX_MCBSP4_BASE,
-		.dma_rx_sync    = OMAP44XX_DMA_MCBSP4_RX,
-		.dma_tx_sync    = OMAP44XX_DMA_MCBSP4_TX,
-		.tx_irq         = OMAP44XX_IRQ_MCBSP4,
-		/* XXX .ops ? */
-	},
-};
-#define OMAP44XX_MCBSP_PDATA_SZ		ARRAY_SIZE(omap44xx_mcbsp_pdata)
-#define OMAP44XX_MCBSP_REG_NUM		(OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
+	if (cpu_is_omap34xx()) {
+		pdata->dma_op_mode = MCBSP_DMA_MODE_ELEMENT;
+		if (id == 2)
+			pdata->buffer_size = 0x500;
+		else
+			pdata->buffer_size = 0x80;
+	} else {
+		pdata->dma_op_mode = -EINVAL;
+		pdata->buffer_size = 0;
+	}
 
-static int __init omap2_mcbsp_init(void)
+	sscanf(oh->name, "mcbsp%d", &id);
+	sprintf(dev_name, "mcbsp%d_sidetone", id);
+	oh_device[0] = oh;
+
+	for (i = 0; i < no_of_st ; i++) {
+		if (!strcmp(dev_name, oh_st_device[i]->name)) {
+			oh_device[1] = oh_st_device[i];
+			count++;
+		}
+	}
+
+	od = omap_device_build_ss(name, id, oh_device, count, pdata,
+				sizeof(*pdata), omap2_mcbsp_latency,
+				ARRAY_SIZE(omap2_mcbsp_latency), false);
+	if (IS_ERR(od))  {
+		pr_err("%s: Cant build omap_device for %s:%s.\n", __func__,
+					name, oh->name);
+		kfree(pdata);
+		return PTR_ERR(od);
+	}
+	omap_mcbsp_count++;
+	return 0;
+}
+
+static int omap_mcbsp_st(struct omap_hwmod *oh, void *user)
 {
-	if (cpu_is_omap2420()) {
-		omap_mcbsp_count = OMAP2420_MCBSP_PDATA_SZ;
-		omap_mcbsp_cache_size = OMAP2420_MCBSP_REG_NUM * sizeof(u16);
-	} else if (cpu_is_omap2430()) {
-		omap_mcbsp_count = OMAP2430_MCBSP_PDATA_SZ;
-		omap_mcbsp_cache_size = OMAP2430_MCBSP_REG_NUM * sizeof(u32);
-	} else if (cpu_is_omap34xx()) {
-		omap_mcbsp_count = OMAP34XX_MCBSP_PDATA_SZ;
-		omap_mcbsp_cache_size = OMAP34XX_MCBSP_REG_NUM * sizeof(u32);
-	} else if (cpu_is_omap44xx()) {
-		omap_mcbsp_count = OMAP44XX_MCBSP_PDATA_SZ;
-		omap_mcbsp_cache_size = OMAP44XX_MCBSP_REG_NUM * sizeof(u32);
+	if (!oh) {
+		pr_err("%s:NULL hwmod pointer (oh)\n", __func__);
+		return -EINVAL;
 	}
+	oh_st_device[no_of_st++] = oh;
+	return 0;
+}
+
+static int __init omap2_mcbsp_init(void)
+{
+	omap_hwmod_for_each_by_class("mcbsp_sidetone", omap_mcbsp_st,
+					NULL);
+	omap_hwmod_for_each_by_class("mcbsp", omap_init_mcbsp, NULL);
 
 	mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *),
 								GFP_KERNEL);
 	if (!mcbsp_ptr)
 		return -ENOMEM;
 
-	if (cpu_is_omap2420())
-		omap_mcbsp_register_board_cfg(omap2420_mcbsp_pdata,
-						OMAP2420_MCBSP_PDATA_SZ);
-	if (cpu_is_omap2430())
-		omap_mcbsp_register_board_cfg(omap2430_mcbsp_pdata,
-						OMAP2430_MCBSP_PDATA_SZ);
-	if (cpu_is_omap34xx())
-		omap_mcbsp_register_board_cfg(omap34xx_mcbsp_pdata,
-						OMAP34XX_MCBSP_PDATA_SZ);
-	if (cpu_is_omap44xx())
-		omap_mcbsp_register_board_cfg(omap44xx_mcbsp_pdata,
-						OMAP44XX_MCBSP_PDATA_SZ);
-
 	return omap_mcbsp_init();
 }
 arch_initcall(omap2_mcbsp_init);
arch/arm/plat-omap/include/plat/mcbsp.h +1 -5
index 4da6f94..1ff283c 100644
@@ -418,11 +418,9 @@ struct omap_mcbsp_platform_data {
 	u8 dma_rx_sync, dma_tx_sync;
 	u16 rx_irq, tx_irq;
 	struct omap_mcbsp_ops *ops;
-#ifdef CONFIG_ARCH_OMAP3
-	/* Sidetone block for McBSP 2 and 3 */
 	unsigned long phys_base_st;
 	u16 buffer_size;
-#endif
+	int dma_op_mode;
 };
 
 struct omap_mcbsp_st_data {
@@ -466,12 +464,10 @@ struct omap_mcbsp {
 	struct omap_mcbsp_platform_data *pdata;
 	struct clk *iclk;
 	struct clk *fclk;
-#ifdef CONFIG_ARCH_OMAP3
 	struct omap_mcbsp_st_data *st_data;
 	int dma_op_mode;
 	u16 max_tx_thres;
 	u16 max_rx_thres;
-#endif
 	void *reg_cache;
 };
 extern struct omap_mcbsp **mcbsp_ptr;
arch/arm/plat-omap/mcbsp.c +85 -104

248 lines not on this page · raw message

Signature · 1 line
1.7.0.4
#6 lore raw

Re: [PATCH 4/7] [RFC] OMAP: hwmod implementation for MCBSP

Quoted 10 lines · On Tuesday 05 October 2010 19:37:39 ext Kishon Vijay Abraham I wrote:
---
 arch/arm/mach-omap2/mcbsp.c             |  251
+++++++++---------------------- arch/arm/plat-omap/include/plat/mcbsp.h | 
  6 +-
 arch/arm/plat-omap/mcbsp.c              |  189 +++++++++++-------------
 3 files changed, 159 insertions(+), 287 deletions(-)

So the plan is to kill OMAP1 support in McBSP (audio)? We do have OMAP1 users, so IMHO dropping OMAP1 is not acceptable.

Signature · 5 lines
Péter
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#7 lore raw

RE: [PATCH 4/7] [RFC] OMAP: hwmod implementation for MCBSP

Quoted 18 lines

-----Original Message-----
From: Peter Ujfalusi [mailto:[email protected]]
Sent: Wednesday, October 06, 2010 11:32 AM
To: ABRAHAM, KISHON VIJAY
Cc: [email protected]; Kamat, Nishant; Varadarajan, Charulatha; Datta, Shubhrajyoti; Basak, Partha
Subject: Re: [PATCH 4/7] [RFC] OMAP: hwmod implementation for MCBSP

Quoted 7 lines · On Tuesday 05 October 2010 19:37:39 ext Kishon Vijay Abraham I wrote:
---
 arch/arm/mach-omap2/mcbsp.c             |  251

+++++++++----------------------

Quoted 8 lines

arch/arm/plat-omap/include/plat/mcbsp.h |

Quoted 2 lines

6 +-

 arch/arm/plat-omap/mcbsp.c              |  189 

+++++++++++-------------

Quoted 1 line
 3 files changed, 159 insertions(+), 287 deletions(-)

So the plan is to kill OMAP1 support in McBSP (audio)? We do have OMAP1 users, so IMHO dropping OMAP1 is not acceptable.

This patch series would not break OMAP1 as they do not touch the omap_mcbsp_register_board_cfg() in mach-omap1.

Usage of hwmod is applicable only for OMAP2plus cpus and it modifies the way in which the platform device is built & registered. It makes use of centralised database to fetch the addresses, irq, dma info etc., for OMAP2plus. OMAP1 cpus will still continue to have the old way of doing platform device registeration.

pm_runtime APIs are already inplace to take care of enabling clocks in case of OMAP1.

Hope this clarifies.

Quoted 4 lines
Signature · 3 lines
-- 
Péter
--

To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#8 lore raw

Re: [PATCH 4/7] [RFC] OMAP: hwmod implementation for MCBSP

Quoted 2 lines · Charulatha

This patch series would not break OMAP1 as they do not touch the omap_mcbsp_register_board_cfg() in mach-omap1.

But the plat-omap/mcbsp will not going to be able to prope on OMAP1, or did I missed something?

Snip:
@@ -1775,25 +1685,50 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)

        mcbsp->dma_tx_lch = -1;
        mcbsp->dma_rx_lch = -1;
-       mcbsp->phys_base = pdata->phys_base;
-       mcbsp->io_base = ioremap(pdata->phys_base, SZ_4K);
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {

+ dev_err(&pdev->dev, "%s:mcbsp%d has invalid memory resource\n",
+ __func__, pdev->id);
+ ret = -ENOMEM;
+ goto exit;

+       }
+       mcbsp->phys_base = res->start;
+       mcbsp->io_base = ioremap(res->start, resource_size(res));
        if (!mcbsp->io_base) {
                ret = -ENOMEM;
                goto err_ioremap;
        }

+ omap_mcbsp_cache_size = resource_size(res);
+

        /* Default I/O is IRQ based */
        mcbsp->io_type = OMAP_MCBSP_IRQ_IO;
-       mcbsp->tx_irq = pdata->tx_irq;
-       mcbsp->rx_irq = pdata->rx_irq;
-       mcbsp->dma_rx_sync = pdata->dma_rx_sync;
-       mcbsp->dma_tx_sync = pdata->dma_tx_sync;
+       mcbsp->tx_irq = platform_get_irq_byname(pdev, "tx");
+       mcbsp->rx_irq = platform_get_irq_byname(pdev, "rx");

+
+ res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx");
+ if (!res) {
+ dev_err(&pdev->dev, "%s:mcbsp%d has invalid DMA channel\n",
+ __func__, pdev->id);
+ ret = -ENODEV;
+ goto err_res;
+ }
+ mcbsp->dma_rx_sync = res->start;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx");
+ if (!res) {
+ dev_err(&pdev->dev, "%s:mcbsp%d has invalid DMA channel\n",
+ __func__, pdev->id);
+ ret = -ENODEV;
+ goto err_res;
+ }
+ mcbsp->dma_tx_sync = res->start;

I don't think that on OMAP1 the platform_get_resource_byname function will find the needed resources...

Quoted 11 lines

Usage of hwmod is applicable only for OMAP2plus cpus and it modifies the way in which the platform device is built & registered. It makes use of centralised database to fetch the addresses, irq, dma info etc., for OMAP2plus. OMAP1 cpus will still continue to have the old way of doing platform device registeration.

pm_runtime APIs are already inplace to take care of enabling clocks in case of OMAP1.

Hope this clarifies.

Signature · 5 lines
Péter
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#9 lore raw

RE: [PATCH 4/7] [RFC] OMAP: hwmod implementation for MCBSP

Quoted 10 lines

-----Original Message-----
From: Peter Ujfalusi [mailto:[email protected]]
Sent: Wednesday, October 06, 2010 12:28 PM
To: Varadarajan, Charulatha
Cc: ABRAHAM, KISHON VIJAY; [email protected]; Kamat, Nishant; Datta, Shubhrajyoti; Basak, Partha
Subject: Re: [PATCH 4/7] [RFC] OMAP: hwmod implementation for MCBSP

Quoted 8 lines
Quoted 2 lines · Charulatha

This patch series would not break OMAP1 as they do not touch the omap_mcbsp_register_board_cfg() in mach-omap1.

But the plat-omap/mcbsp will not going to be able to prope on OMAP1, or did I
missed something?

I agree.

Quoted 57 lines

Snip:

arch/arm/plat-omap/mcbsp.c +31 -6
@@ -1775,25 +1685,50 @@ static int __devinit omap_mcbsp_probe(struct 
 platform_device *pdev)
        mcbsp->dma_tx_lch = -1;
        mcbsp->dma_rx_lch = -1;
 
-       mcbsp->phys_base = pdata->phys_base;
-       mcbsp->io_base = ioremap(pdata->phys_base, SZ_4K);
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               dev_err(&pdev->dev, "%s:mcbsp%d has invalid 
 memory resource\n",
+                                       __func__, pdev->id);
+               ret = -ENOMEM;
+               goto exit;
+       }
+       mcbsp->phys_base = res->start;
+       mcbsp->io_base = ioremap(res->start, resource_size(res));
        if (!mcbsp->io_base) {
                ret = -ENOMEM;
                goto err_ioremap;
        }
 
+       omap_mcbsp_cache_size = resource_size(res);
+
        /* Default I/O is IRQ based */
        mcbsp->io_type = OMAP_MCBSP_IRQ_IO;
-       mcbsp->tx_irq = pdata->tx_irq;
-       mcbsp->rx_irq = pdata->rx_irq;
-       mcbsp->dma_rx_sync = pdata->dma_rx_sync;
-       mcbsp->dma_tx_sync = pdata->dma_tx_sync;
+       mcbsp->tx_irq = platform_get_irq_byname(pdev, "tx");
+       mcbsp->rx_irq = platform_get_irq_byname(pdev, "rx");
+
+       res = platform_get_resource_byname(pdev, 
 IORESOURCE_DMA, "rx");
+       if (!res) {
+               dev_err(&pdev->dev, "%s:mcbsp%d has invalid 
 DMA channel\n",
+                                       __func__, pdev->id);
+               ret = -ENODEV;
+               goto err_res;
+       }
+       mcbsp->dma_rx_sync = res->start;
+
+       res = platform_get_resource_byname(pdev, 
 IORESOURCE_DMA, "tx");
+       if (!res) {
+               dev_err(&pdev->dev, "%s:mcbsp%d has invalid 
 DMA channel\n",
+                                       __func__, pdev->id);
+               ret = -ENODEV;
+               goto err_res;
+       }
+       mcbsp->dma_tx_sync = res->start;
 
Quoted 3 lines

I don't think that on OMAP1 the platform_get_resource_byname function will find
the needed resources...

Agreed. This series should have taken care of this for OMAP1.

Quoted 6 lines
Quoted 5 lines

Usage of hwmod is applicable only for OMAP2plus cpus and it modifies the way in which the platform device is built & registered. It makes use of centralised database to fetch the addresses, irq,

dma info etc.,

Quoted 12 lines
Quoted 4 lines

for OMAP2plus. OMAP1 cpus will still continue to have the old way of doing platform device registeration.

pm_runtime APIs are already inplace to take care of

enabling clocks in

Quoted 3 lines

case of OMAP1.

Hope this clarifies.

Signature · 2 lines
Péter
--

To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#10 lore raw

Re: [PATCH 4/7] [RFC] OMAP: hwmod implementation for MCBSP

In reply to Kishon Vijay Abraham I
Quoted 224 lines · Kishon Vijay Abraham I
---
  arch/arm/mach-omap2/mcbsp.c             |  251 +++++++++----------------------
  arch/arm/plat-omap/include/plat/mcbsp.h |    6 +-
  arch/arm/plat-omap/mcbsp.c              |  189 +++++++++++-------------
  3 files changed, 159 insertions(+), 287 deletions(-)
arch/arm/mach-omap2/mcbsp.c +36 -153
index eba9fa1..25c6703 100644
@@ -22,9 +22,13 @@
  #include<plat/dma.h>
  #include<plat/cpu.h>
  #include<plat/mcbsp.h>
+#include<plat/omap_hwmod.h>
+#include<plat/omap_device.h>
 
  #include "control.h"
 
+static struct omap_hwmod *oh_st_device[] = {NULL, NULL};
+static int no_of_st;
 
  /* McBSP internal signal muxing functions */
 
@@ -101,199 +105,90 @@ int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id)
  }
  EXPORT_SYMBOL(omap2_mcbsp_set_clks_src);
 
-
-/* Platform data */
-
-#ifdef CONFIG_ARCH_OMAP2420
-static struct omap_mcbsp_platform_data omap2420_mcbsp_pdata[] = {
-       {
-               .phys_base      = OMAP24XX_MCBSP1_BASE,
-               .dma_rx_sync    = OMAP24XX_DMA_MCBSP1_RX,
-               .dma_tx_sync    = OMAP24XX_DMA_MCBSP1_TX,
-               .rx_irq         = INT_24XX_MCBSP1_IRQ_RX,
-               .tx_irq         = INT_24XX_MCBSP1_IRQ_TX,
-       },
+struct omap_device_pm_latency omap2_mcbsp_latency[] = {
         {
-               .phys_base      = OMAP24XX_MCBSP2_BASE,
-               .dma_rx_sync    = OMAP24XX_DMA_MCBSP2_RX,
-               .dma_tx_sync    = OMAP24XX_DMA_MCBSP2_TX,
-               .rx_irq         = INT_24XX_MCBSP2_IRQ_RX,
-               .tx_irq         = INT_24XX_MCBSP2_IRQ_TX,
+               .deactivate_func = omap_device_idle_hwmods,
+               .activate_func   = omap_device_enable_hwmods,
+               .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
         },
  };
-#define OMAP2420_MCBSP_PDATA_SZ                ARRAY_SIZE(omap2420_mcbsp_pdata)
-#define OMAP2420_MCBSP_REG_NUM         (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
-#else
-#define omap2420_mcbsp_pdata           NULL
-#define OMAP2420_MCBSP_PDATA_SZ                0
-#define OMAP2420_MCBSP_REG_NUM         0
-#endif
 
-#ifdef CONFIG_ARCH_OMAP2430
-static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = {
-       {
-               .phys_base      = OMAP24XX_MCBSP1_BASE,
-               .dma_rx_sync    = OMAP24XX_DMA_MCBSP1_RX,
-               .dma_tx_sync    = OMAP24XX_DMA_MCBSP1_TX,
-               .rx_irq         = INT_24XX_MCBSP1_IRQ_RX,
-               .tx_irq         = INT_24XX_MCBSP1_IRQ_TX,
-       },
-       {
-               .phys_base      = OMAP24XX_MCBSP2_BASE,
-               .dma_rx_sync    = OMAP24XX_DMA_MCBSP2_RX,
-               .dma_tx_sync    = OMAP24XX_DMA_MCBSP2_TX,
-               .rx_irq         = INT_24XX_MCBSP2_IRQ_RX,
-               .tx_irq         = INT_24XX_MCBSP2_IRQ_TX,
-       },
-       {
-               .phys_base      = OMAP2430_MCBSP3_BASE,
-               .dma_rx_sync    = OMAP24XX_DMA_MCBSP3_RX,
-               .dma_tx_sync    = OMAP24XX_DMA_MCBSP3_TX,
-               .rx_irq         = INT_24XX_MCBSP3_IRQ_RX,
-               .tx_irq         = INT_24XX_MCBSP3_IRQ_TX,
-       },
-       {
-               .phys_base      = OMAP2430_MCBSP4_BASE,
-               .dma_rx_sync    = OMAP24XX_DMA_MCBSP4_RX,
-               .dma_tx_sync    = OMAP24XX_DMA_MCBSP4_TX,
-               .rx_irq         = INT_24XX_MCBSP4_IRQ_RX,
-               .tx_irq         = INT_24XX_MCBSP4_IRQ_TX,
-       },
-       {
-               .phys_base      = OMAP2430_MCBSP5_BASE,
-               .dma_rx_sync    = OMAP24XX_DMA_MCBSP5_RX,
-               .dma_tx_sync    = OMAP24XX_DMA_MCBSP5_TX,
-               .rx_irq         = INT_24XX_MCBSP5_IRQ_RX,
-               .tx_irq         = INT_24XX_MCBSP5_IRQ_TX,
-       },
-};
-#define OMAP2430_MCBSP_PDATA_SZ                ARRAY_SIZE(omap2430_mcbsp_pdata)
-#define OMAP2430_MCBSP_REG_NUM         (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
-#else
-#define omap2430_mcbsp_pdata           NULL
-#define OMAP2430_MCBSP_PDATA_SZ                0
-#define OMAP2430_MCBSP_REG_NUM         0
-#endif
+static int omap_init_mcbsp(struct omap_hwmod *oh, void *user)
+{
+       int id, count = 1, i;
+       char *name = "omap-mcbsp";
+       char dev_name[16];
+       struct omap_hwmod *oh_device[2];
+       struct omap_mcbsp_platform_data *pdata;
+       struct omap_device *od;
+
+       if (!oh) {
+               pr_err("%s:NULL hwmod pointer (oh)\n", __func__);
+               return -EINVAL;
+       }
 
-#ifdef CONFIG_ARCH_OMAP3
-static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
-       {
-               .phys_base      = OMAP34XX_MCBSP1_BASE,
-               .dma_rx_sync    = OMAP24XX_DMA_MCBSP1_RX,
-               .dma_tx_sync    = OMAP24XX_DMA_MCBSP1_TX,
-               .rx_irq         = INT_24XX_MCBSP1_IRQ_RX,
-               .tx_irq         = INT_24XX_MCBSP1_IRQ_TX,
-               .buffer_size    = 0x80, /* The FIFO has 128 locations */
-       },
-       {
-               .phys_base      = OMAP34XX_MCBSP2_BASE,
-               .phys_base_st   = OMAP34XX_MCBSP2_ST_BASE,
-               .dma_rx_sync    = OMAP24XX_DMA_MCBSP2_RX,
-               .dma_tx_sync    = OMAP24XX_DMA_MCBSP2_TX,
-               .rx_irq         = INT_24XX_MCBSP2_IRQ_RX,
-               .tx_irq         = INT_24XX_MCBSP2_IRQ_TX,
-               .buffer_size    = 0x500, /* The FIFO has 1024 + 256 locations */
-       },
-       {
-               .phys_base      = OMAP34XX_MCBSP3_BASE,
-               .phys_base_st   = OMAP34XX_MCBSP3_ST_BASE,
-               .dma_rx_sync    = OMAP24XX_DMA_MCBSP3_RX,
-               .dma_tx_sync    = OMAP24XX_DMA_MCBSP3_TX,
-               .rx_irq         = INT_24XX_MCBSP3_IRQ_RX,
-               .tx_irq         = INT_24XX_MCBSP3_IRQ_TX,
-               .buffer_size    = 0x80, /* The FIFO has 128 locations */
-       },
-       {
-               .phys_base      = OMAP34XX_MCBSP4_BASE,
-               .dma_rx_sync    = OMAP24XX_DMA_MCBSP4_RX,
-               .dma_tx_sync    = OMAP24XX_DMA_MCBSP4_TX,
-               .rx_irq         = INT_24XX_MCBSP4_IRQ_RX,
-               .tx_irq         = INT_24XX_MCBSP4_IRQ_TX,
-               .buffer_size    = 0x80, /* The FIFO has 128 locations */
-       },
-       {
-               .phys_base      = OMAP34XX_MCBSP5_BASE,
-               .dma_rx_sync    = OMAP24XX_DMA_MCBSP5_RX,
-               .dma_tx_sync    = OMAP24XX_DMA_MCBSP5_TX,
-               .rx_irq         = INT_24XX_MCBSP5_IRQ_RX,
-               .tx_irq         = INT_24XX_MCBSP5_IRQ_TX,
-               .buffer_size    = 0x80, /* The FIFO has 128 locations */
-       },
-};
-#define OMAP34XX_MCBSP_PDATA_SZ                ARRAY_SIZE(omap34xx_mcbsp_pdata)
-#define OMAP34XX_MCBSP_REG_NUM         (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
-#else
-#define omap34xx_mcbsp_pdata           NULL
-#define OMAP34XX_MCBSP_PDATA_SZ                0
-#define OMAP34XX_MCBSP_REG_NUM         0
-#endif
+       pdata = kzalloc(sizeof(struct omap_mcbsp_platform_data), GFP_KERNEL);
+       if (!pdata) {
+               pr_err("%s: No memory for mcbsp\n", __func__);
+               return -ENOMEM;
+       }
 
-static struct omap_mcbsp_platform_data omap44xx_mcbsp_pdata[] = {
-       {
-               .phys_base      = OMAP44XX_MCBSP1_BASE,
-               .dma_rx_sync    = OMAP44XX_DMA_MCBSP1_RX,
-               .dma_tx_sync    = OMAP44XX_DMA_MCBSP1_TX,
-               .tx_irq         = OMAP44XX_IRQ_MCBSP1,
-       },
-       {
-               .phys_base      = OMAP44XX_MCBSP2_BASE,
-               .dma_rx_sync    = OMAP44XX_DMA_MCBSP2_RX,
-               .dma_tx_sync    = OMAP44XX_DMA_MCBSP2_TX,
-               .tx_irq         = OMAP44XX_IRQ_MCBSP2,
-               /* XXX .ops ? */
-       },
-       {
-               .phys_base      = OMAP44XX_MCBSP3_BASE,
-               .dma_rx_sync    = OMAP44XX_DMA_MCBSP3_RX,
-               .dma_tx_sync    = OMAP44XX_DMA_MCBSP3_TX,
-               .tx_irq         = OMAP44XX_IRQ_MCBSP3,
-               /* XXX .ops ? */
-       },
-       {
-               .phys_base      = OMAP44XX_MCBSP4_BASE,
-               .dma_rx_sync    = OMAP44XX_DMA_MCBSP4_RX,
-               .dma_tx_sync    = OMAP44XX_DMA_MCBSP4_TX,
-               .tx_irq         = OMAP44XX_IRQ_MCBSP4,
-               /* XXX .ops ? */
-       },
-};
-#define OMAP44XX_MCBSP_PDATA_SZ                ARRAY_SIZE(omap44xx_mcbsp_pdata)
-#define OMAP44XX_MCBSP_REG_NUM         (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
+       if (cpu_is_omap34xx()) {
+               pdata->dma_op_mode = MCBSP_DMA_MODE_ELEMENT;
+               if (id == 2)
+                       pdata->buffer_size = 0x500;
+               else
+                       pdata->buffer_size = 0x80;
+       } else {
+               pdata->dma_op_mode = -EINVAL;
+               pdata->buffer_size = 0;
+       }
 
-static int __init omap2_mcbsp_init(void)

arch/arm/mach-omap2/mcbsp.c int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id) · line 156

Quoted 10 lines
arch/arm/mach-omap2/mcbsp.c +10 -0
+       sscanf(oh->name, "mcbsp%d",&id);
+       sprintf(dev_name, "mcbsp%d_sidetone", id);
+       oh_device[0] = oh;
+
+       for (i = 0; i<  no_of_st ; i++) {
+               if (!strcmp(dev_name, oh_st_device[i]->name)) {
+                       oh_device[1] = oh_st_device[i];
+                       count++;
+               }
+       }

Pfuu, it took me a while to follow how all that stuff was working :-)

Since the sidetone block is tightly coupled to the mcbsp, you should simply add this information directly as a attribute of the mcbsp2 & 3 hwmod dev_attr.

You will then easily detect which one does have a sidetone connected to it and avoid all this code.

+static struct omap_mcbsp_dev_attr omap34xx_mcbsp2_dev_attr = {
+ .sidetone = "mcbsp2_sidetone",
+};

+static struct omap_hwmod omap34xx_mcbsp2_hwmod = {
...
+ .dev_attr = &omap34xx_mcbsp2_dev_attr,
...

Regards,
Benoit

Quoted 359 lines
arch/arm/mach-omap2/mcbsp.c +27 -25
+
+       od = omap_device_build_ss(name, id, oh_device, count, pdata,
+                               sizeof(*pdata), omap2_mcbsp_latency,
+                               ARRAY_SIZE(omap2_mcbsp_latency), false);
+       if (IS_ERR(od))  {
+               pr_err("%s: Cant build omap_device for %s:%s.\n", __func__,
+                                       name, oh->name);
+               kfree(pdata);
+               return PTR_ERR(od);
+       }
+       omap_mcbsp_count++;
+       return 0;
+}
+
+static int omap_mcbsp_st(struct omap_hwmod *oh, void *user)
  {
-       if (cpu_is_omap2420()) {
-               omap_mcbsp_count = OMAP2420_MCBSP_PDATA_SZ;
-               omap_mcbsp_cache_size = OMAP2420_MCBSP_REG_NUM * sizeof(u16);
-       } else if (cpu_is_omap2430()) {
-               omap_mcbsp_count = OMAP2430_MCBSP_PDATA_SZ;
-               omap_mcbsp_cache_size = OMAP2430_MCBSP_REG_NUM * sizeof(u32);
-       } else if (cpu_is_omap34xx()) {
-               omap_mcbsp_count = OMAP34XX_MCBSP_PDATA_SZ;
-               omap_mcbsp_cache_size = OMAP34XX_MCBSP_REG_NUM * sizeof(u32);
-       } else if (cpu_is_omap44xx()) {
-               omap_mcbsp_count = OMAP44XX_MCBSP_PDATA_SZ;
-               omap_mcbsp_cache_size = OMAP44XX_MCBSP_REG_NUM * sizeof(u32);
+       if (!oh) {
+               pr_err("%s:NULL hwmod pointer (oh)\n", __func__);
+               return -EINVAL;
         }
+       oh_st_device[no_of_st++] = oh;
+       return 0;
+}
+
+static int __init omap2_mcbsp_init(void)
+{
+       omap_hwmod_for_each_by_class("mcbsp_sidetone", omap_mcbsp_st,
+                                       NULL);
+       omap_hwmod_for_each_by_class("mcbsp", omap_init_mcbsp, NULL);
 
         mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *),
                                                                 GFP_KERNEL);
         if (!mcbsp_ptr)
                 return -ENOMEM;
 
-       if (cpu_is_omap2420())
-               omap_mcbsp_register_board_cfg(omap2420_mcbsp_pdata,
-                                               OMAP2420_MCBSP_PDATA_SZ);
-       if (cpu_is_omap2430())
-               omap_mcbsp_register_board_cfg(omap2430_mcbsp_pdata,
-                                               OMAP2430_MCBSP_PDATA_SZ);
-       if (cpu_is_omap34xx())
-               omap_mcbsp_register_board_cfg(omap34xx_mcbsp_pdata,
-                                               OMAP34XX_MCBSP_PDATA_SZ);
-       if (cpu_is_omap44xx())
-               omap_mcbsp_register_board_cfg(omap44xx_mcbsp_pdata,
-                                               OMAP44XX_MCBSP_PDATA_SZ);
-
         return omap_mcbsp_init();
  }
  arch_initcall(omap2_mcbsp_init);
arch/arm/plat-omap/include/plat/mcbsp.h +1 -5
index 4da6f94..1ff283c 100644
@@ -418,11 +418,9 @@ struct omap_mcbsp_platform_data {
         u8 dma_rx_sync, dma_tx_sync;
         u16 rx_irq, tx_irq;
         struct omap_mcbsp_ops *ops;
-#ifdef CONFIG_ARCH_OMAP3
-       /* Sidetone block for McBSP 2 and 3 */
         unsigned long phys_base_st;
         u16 buffer_size;
-#endif
+       int dma_op_mode;
  };
 
  struct omap_mcbsp_st_data {
@@ -466,12 +464,10 @@ struct omap_mcbsp {
         struct omap_mcbsp_platform_data *pdata;
         struct clk *iclk;
         struct clk *fclk;
-#ifdef CONFIG_ARCH_OMAP3
         struct omap_mcbsp_st_data *st_data;
         int dma_op_mode;
         u16 max_tx_thres;
         u16 max_rx_thres;
-#endif
         void *reg_cache;
  };
  extern struct omap_mcbsp **mcbsp_ptr;
arch/arm/plat-omap/mcbsp.c +85 -105
index eac4b97..c7c6a83 100644
@@ -27,6 +27,8 @@
 
  #include<plat/dma.h>
  #include<plat/mcbsp.h>
+#include<plat/omap_hwmod.h>
+#include<plat/omap_device.h>
 
  #include "../mach-omap2/cm-regbits-34xx.h"
 
@@ -1466,7 +1468,6 @@ void omap_mcbsp_set_spi_mode(unsigned int id,
  }
  EXPORT_SYMBOL(omap_mcbsp_set_spi_mode);
 
-#ifdef CONFIG_ARCH_OMAP3
  #define max_thres(m)                   (mcbsp->pdata->buffer_size)
  #define valid_threshold(m, val)                ((val)<= max_thres(m))
  #define THRESHOLD_PROP_BUILDER(prop)                                   \
@@ -1645,98 +1646,6 @@ static const struct attribute_group sidetone_attr_group = {
         .attrs = (struct attribute **)sidetone_attrs,
  };
 
-static int __devinit omap_st_add(struct omap_mcbsp *mcbsp)
-{
-       struct omap_mcbsp_platform_data *pdata = mcbsp->pdata;
-       struct omap_mcbsp_st_data *st_data;
-       int err;
-
-       st_data = kzalloc(sizeof(*mcbsp->st_data), GFP_KERNEL);
-       if (!st_data) {
-               err = -ENOMEM;
-               goto err1;
-       }
-
-       st_data->io_base_st = ioremap(pdata->phys_base_st, SZ_4K);
-       if (!st_data->io_base_st) {
-               err = -ENOMEM;
-               goto err2;
-       }
-
-       err = sysfs_create_group(&mcbsp->dev->kobj,&sidetone_attr_group);
-       if (err)
-               goto err3;
-
-       mcbsp->st_data = st_data;
-       return 0;
-
-err3:
-       iounmap(st_data->io_base_st);
-err2:
-       kfree(st_data);
-err1:
-       return err;
-
-}
-
-static void __devexit omap_st_remove(struct omap_mcbsp *mcbsp)
-{
-       struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
-
-       if (st_data) {
-               sysfs_remove_group(&mcbsp->dev->kobj,&sidetone_attr_group);
-               iounmap(st_data->io_base_st);
-               kfree(st_data);
-       }
-}
-
-static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp)
-{
-       mcbsp->dma_op_mode = MCBSP_DMA_MODE_ELEMENT;
-       if (cpu_is_omap34xx()) {
-               /*
-                * Initially configure the maximum thresholds to a safe value.
-                * The McBSP FIFO usage with these values should not go under
-                * 16 locations.
-                * If the whole FIFO without safety buffer is used, than there
-                * is a possibility that the DMA will be not able to push the
-                * new data on time, causing channel shifts in runtime.
-                */
-               mcbsp->max_tx_thres = max_thres(mcbsp) - 0x10;
-               mcbsp->max_rx_thres = max_thres(mcbsp) - 0x10;
-               /*
-                * REVISIT: Set dmap_op_mode to THRESHOLD as default
-                * for mcbsp2 instances.
-                */
-               if (omap_additional_add(mcbsp->dev))
-                       dev_warn(mcbsp->dev,
-                               "Unable to create additional controls\n");
-
-               if (mcbsp->id == 2 || mcbsp->id == 3)
-                       if (omap_st_add(mcbsp))
-                               dev_warn(mcbsp->dev,
-                                "Unable to create sidetone controls\n");
-
-       } else {
-               mcbsp->max_tx_thres = -EINVAL;
-               mcbsp->max_rx_thres = -EINVAL;
-       }
-}
-
-static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp)
-{
-       if (cpu_is_omap34xx()) {
-               omap_additional_remove(mcbsp->dev);
-
-               if (mcbsp->id == 2 || mcbsp->id == 3)
-                       omap_st_remove(mcbsp);
-       }
-}
-#else
-static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp) {}
-static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp) {}
-#endif /* CONFIG_ARCH_OMAP3 */
-
  /*
   * McBSP1 and McBSP3 are directly mapped on 1610 and 1510.
   * 730 has only 2 McBSP, and both of them are MPU peripherals.
@@ -1746,6 +1655,7 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
         struct omap_mcbsp_platform_data *pdata = pdev->dev.platform_data;
         struct omap_mcbsp *mcbsp;
         int id = pdev->id - 1;
+       struct resource *res;
         int ret = 0;
 
         if (!pdata) {
@@ -1775,25 +1685,50 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
         mcbsp->dma_tx_lch = -1;
         mcbsp->dma_rx_lch = -1;
 
-       mcbsp->phys_base = pdata->phys_base;
-       mcbsp->io_base = ioremap(pdata->phys_base, SZ_4K);
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               dev_err(&pdev->dev, "%s:mcbsp%d has invalid memory resource\n",
+                                       __func__, pdev->id);
+               ret = -ENOMEM;
+               goto exit;
+       }
+       mcbsp->phys_base = res->start;
+       mcbsp->io_base = ioremap(res->start, resource_size(res));
         if (!mcbsp->io_base) {
                 ret = -ENOMEM;
                 goto err_ioremap;
         }
 
+       omap_mcbsp_cache_size = resource_size(res);
+
         /* Default I/O is IRQ based */
         mcbsp->io_type = OMAP_MCBSP_IRQ_IO;
-       mcbsp->tx_irq = pdata->tx_irq;
-       mcbsp->rx_irq = pdata->rx_irq;
-       mcbsp->dma_rx_sync = pdata->dma_rx_sync;
-       mcbsp->dma_tx_sync = pdata->dma_tx_sync;
+       mcbsp->tx_irq = platform_get_irq_byname(pdev, "tx");
+       mcbsp->rx_irq = platform_get_irq_byname(pdev, "rx");
+
+       res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx");
+       if (!res) {
+               dev_err(&pdev->dev, "%s:mcbsp%d has invalid DMA channel\n",
+                                       __func__, pdev->id);
+               ret = -ENODEV;
+               goto err_res;
+       }
+       mcbsp->dma_rx_sync = res->start;
+
+       res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx");
+       if (!res) {
+               dev_err(&pdev->dev, "%s:mcbsp%d has invalid DMA channel\n",
+                                       __func__, pdev->id);
+               ret = -ENODEV;
+               goto err_res;
+       }
+       mcbsp->dma_tx_sync = res->start;
 
         mcbsp->iclk = clk_get(&pdev->dev, "ick");
         if (IS_ERR(mcbsp->iclk)) {
                 ret = PTR_ERR(mcbsp->iclk);
                 dev_err(&pdev->dev, "unable to get ick: %d\n", ret);
-               goto err_iclk;
+               goto err_res;
         }
 
         mcbsp->fclk = clk_get(&pdev->dev, "fck");
@@ -1808,14 +1743,53 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
         mcbsp_ptr[id] = mcbsp;
         platform_set_drvdata(pdev, mcbsp);
 
-       /* Initialize mcbsp properties for OMAP34XX if needed / applicable */
-       omap34xx_device_init(mcbsp);
+       omap_additional_add(mcbsp->dev);
+       if (pdata->dma_op_mode != -EINVAL) {
+               /*
+                * Initially configure the maximum thresholds to a safe value.
+                * The McBSP FIFO usage with these values should not go under
+                * 16 locations.
+                * If the whole FIFO without safety buffer is used, than there
+                * is a possibility that the DMA will be not able to push the
+                * new data on time, causing channel shifts in runtime.
+                */
+               mcbsp->max_tx_thres = max_thres(mcbsp) - 0x10 ;
+               mcbsp->max_rx_thres = max_thres(mcbsp) - 0x10 ;
+       }
+
+       if (cpu_is_omap34xx()) {
+               res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+               if (res) {
+                       mcbsp->st_data = kzalloc(sizeof(*mcbsp->st_data),
+                                               GFP_KERNEL);
+                       if (!mcbsp->st_data) {
+                               ret = -ENOMEM;
+                               goto err_st_data;
+                       }
+                       mcbsp->st_data->io_base_st = ioremap(res->start,
+                                               resource_size(res));
+                       if (!mcbsp->st_data->io_base_st) {
+                               ret = -ENOMEM;
+                               goto err_io_st;
+                       }
+                       ret = sysfs_create_group(&mcbsp->dev->kobj,
+&sidetone_attr_group);
+                       if (ret)
+                               goto err_sysfs;
+               }
+       }
 
         return 0;
 
+err_sysfs:
+       iounmap(mcbsp->st_data->io_base_st);
+err_io_st:
+       kfree(mcbsp->st_data);
+err_st_data:
+       clk_put(mcbsp->fclk);
  err_fclk:
         clk_put(mcbsp->iclk);
-err_iclk:
+err_res:
         iounmap(mcbsp->io_base);
  err_ioremap:
         kfree(mcbsp);
@@ -1834,7 +1808,14 @@ static int __devexit omap_mcbsp_remove(struct platform_device *pdev)
                                 mcbsp->pdata->ops->free)
                         mcbsp->pdata->ops->free(mcbsp->id);
 
-               omap34xx_device_exit(mcbsp);
+               omap_additional_remove(mcbsp->dev);
+
+               if (mcbsp->st_data) {
+                       sysfs_remove_group(&mcbsp->dev->kobj,
+&sidetone_attr_group);
+                       iounmap(mcbsp->st_data->io_base_st);
+                       kfree(mcbsp->st_data);
+               }
 
                 clk_disable(mcbsp->fclk);
                 clk_disable(mcbsp->iclk);
--

1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#11 lore raw

Re: [PATCH 4/7] [RFC] OMAP: hwmod implementation for MCBSP

Quoted 224 lines · Benoit
Quoted 223 lines · Kishon Vijay Abraham I
---
   arch/arm/mach-omap2/mcbsp.c             |  251 +++++++++----------------------
   arch/arm/plat-omap/include/plat/mcbsp.h |    6 +-
   arch/arm/plat-omap/mcbsp.c              |  189 +++++++++++-------------
   3 files changed, 159 insertions(+), 287 deletions(-)
arch/arm/mach-omap2/mcbsp.c +36 -152
index eba9fa1..25c6703 100644
@@ -22,9 +22,13 @@
   #include<plat/dma.h>
   #include<plat/cpu.h>
   #include<plat/mcbsp.h>
+#include<plat/omap_hwmod.h>
+#include<plat/omap_device.h>
 
   #include "control.h"
 
+static struct omap_hwmod *oh_st_device[] = {NULL, NULL};
+static int no_of_st;
 
   /* McBSP internal signal muxing functions */
 
@@ -101,199 +105,90 @@ int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id)
   }
   EXPORT_SYMBOL(omap2_mcbsp_set_clks_src);
 
-
-/* Platform data */
-
-#ifdef CONFIG_ARCH_OMAP2420
-static struct omap_mcbsp_platform_data omap2420_mcbsp_pdata[] = {
-       {
-               .phys_base      = OMAP24XX_MCBSP1_BASE,
-               .dma_rx_sync    = OMAP24XX_DMA_MCBSP1_RX,
-               .dma_tx_sync    = OMAP24XX_DMA_MCBSP1_TX,
-               .rx_irq         = INT_24XX_MCBSP1_IRQ_RX,
-               .tx_irq         = INT_24XX_MCBSP1_IRQ_TX,
-       },
+struct omap_device_pm_latency omap2_mcbsp_latency[] = {
          {
-               .phys_base      = OMAP24XX_MCBSP2_BASE,
-               .dma_rx_sync    = OMAP24XX_DMA_MCBSP2_RX,
-               .dma_tx_sync    = OMAP24XX_DMA_MCBSP2_TX,
-               .rx_irq         = INT_24XX_MCBSP2_IRQ_RX,
-               .tx_irq         = INT_24XX_MCBSP2_IRQ_TX,
+               .deactivate_func = omap_device_idle_hwmods,
+               .activate_func   = omap_device_enable_hwmods,
+               .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
          },
   };
-#define OMAP2420_MCBSP_PDATA_SZ                ARRAY_SIZE(omap2420_mcbsp_pdata)
-#define OMAP2420_MCBSP_REG_NUM         (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
-#else
-#define omap2420_mcbsp_pdata           NULL
-#define OMAP2420_MCBSP_PDATA_SZ                0
-#define OMAP2420_MCBSP_REG_NUM         0
-#endif
 
-#ifdef CONFIG_ARCH_OMAP2430
-static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = {
-       {
-               .phys_base      = OMAP24XX_MCBSP1_BASE,
-               .dma_rx_sync    = OMAP24XX_DMA_MCBSP1_RX,
-               .dma_tx_sync    = OMAP24XX_DMA_MCBSP1_TX,
-               .rx_irq         = INT_24XX_MCBSP1_IRQ_RX,
-               .tx_irq         = INT_24XX_MCBSP1_IRQ_TX,
-       },
-       {
-               .phys_base      = OMAP24XX_MCBSP2_BASE,
-               .dma_rx_sync    = OMAP24XX_DMA_MCBSP2_RX,
-               .dma_tx_sync    = OMAP24XX_DMA_MCBSP2_TX,
-               .rx_irq         = INT_24XX_MCBSP2_IRQ_RX,
-               .tx_irq         = INT_24XX_MCBSP2_IRQ_TX,
-       },
-       {
-               .phys_base      = OMAP2430_MCBSP3_BASE,
-               .dma_rx_sync    = OMAP24XX_DMA_MCBSP3_RX,
-               .dma_tx_sync    = OMAP24XX_DMA_MCBSP3_TX,
-               .rx_irq         = INT_24XX_MCBSP3_IRQ_RX,
-               .tx_irq         = INT_24XX_MCBSP3_IRQ_TX,
-       },
-       {
-               .phys_base      = OMAP2430_MCBSP4_BASE,
-               .dma_rx_sync    = OMAP24XX_DMA_MCBSP4_RX,
-               .dma_tx_sync    = OMAP24XX_DMA_MCBSP4_TX,
-               .rx_irq         = INT_24XX_MCBSP4_IRQ_RX,
-               .tx_irq         = INT_24XX_MCBSP4_IRQ_TX,
-       },
-       {
-               .phys_base      = OMAP2430_MCBSP5_BASE,
-               .dma_rx_sync    = OMAP24XX_DMA_MCBSP5_RX,
-               .dma_tx_sync    = OMAP24XX_DMA_MCBSP5_TX,
-               .rx_irq         = INT_24XX_MCBSP5_IRQ_RX,
-               .tx_irq         = INT_24XX_MCBSP5_IRQ_TX,
-       },
-};
-#define OMAP2430_MCBSP_PDATA_SZ                ARRAY_SIZE(omap2430_mcbsp_pdata)
-#define OMAP2430_MCBSP_REG_NUM         (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
-#else
-#define omap2430_mcbsp_pdata           NULL
-#define OMAP2430_MCBSP_PDATA_SZ                0
-#define OMAP2430_MCBSP_REG_NUM         0
-#endif
+static int omap_init_mcbsp(struct omap_hwmod *oh, void *user)
+{
+       int id, count = 1, i;
+       char *name = "omap-mcbsp";
+       char dev_name[16];
+       struct omap_hwmod *oh_device[2];
+       struct omap_mcbsp_platform_data *pdata;
+       struct omap_device *od;
+
+       if (!oh) {
+               pr_err("%s:NULL hwmod pointer (oh)\n", __func__);
+               return -EINVAL;
+       }
 
-#ifdef CONFIG_ARCH_OMAP3
-static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
-       {
-               .phys_base      = OMAP34XX_MCBSP1_BASE,
-               .dma_rx_sync    = OMAP24XX_DMA_MCBSP1_RX,
-               .dma_tx_sync    = OMAP24XX_DMA_MCBSP1_TX,
-               .rx_irq         = INT_24XX_MCBSP1_IRQ_RX,
-               .tx_irq         = INT_24XX_MCBSP1_IRQ_TX,
-               .buffer_size    = 0x80, /* The FIFO has 128 locations */
-       },
-       {
-               .phys_base      = OMAP34XX_MCBSP2_BASE,
-               .phys_base_st   = OMAP34XX_MCBSP2_ST_BASE,
-               .dma_rx_sync    = OMAP24XX_DMA_MCBSP2_RX,
-               .dma_tx_sync    = OMAP24XX_DMA_MCBSP2_TX,
-               .rx_irq         = INT_24XX_MCBSP2_IRQ_RX,
-               .tx_irq         = INT_24XX_MCBSP2_IRQ_TX,
-               .buffer_size    = 0x500, /* The FIFO has 1024 + 256 locations */
-       },
-       {
-               .phys_base      = OMAP34XX_MCBSP3_BASE,
-               .phys_base_st   = OMAP34XX_MCBSP3_ST_BASE,
-               .dma_rx_sync    = OMAP24XX_DMA_MCBSP3_RX,
-               .dma_tx_sync    = OMAP24XX_DMA_MCBSP3_TX,
-               .rx_irq         = INT_24XX_MCBSP3_IRQ_RX,
-               .tx_irq         = INT_24XX_MCBSP3_IRQ_TX,
-               .buffer_size    = 0x80, /* The FIFO has 128 locations */
-       },
-       {
-               .phys_base      = OMAP34XX_MCBSP4_BASE,
-               .dma_rx_sync    = OMAP24XX_DMA_MCBSP4_RX,
-               .dma_tx_sync    = OMAP24XX_DMA_MCBSP4_TX,
-               .rx_irq         = INT_24XX_MCBSP4_IRQ_RX,
-               .tx_irq         = INT_24XX_MCBSP4_IRQ_TX,
-               .buffer_size    = 0x80, /* The FIFO has 128 locations */
-       },
-       {
-               .phys_base      = OMAP34XX_MCBSP5_BASE,
-               .dma_rx_sync    = OMAP24XX_DMA_MCBSP5_RX,
-               .dma_tx_sync    = OMAP24XX_DMA_MCBSP5_TX,
-               .rx_irq         = INT_24XX_MCBSP5_IRQ_RX,
-               .tx_irq         = INT_24XX_MCBSP5_IRQ_TX,
-               .buffer_size    = 0x80, /* The FIFO has 128 locations */
-       },
-};
-#define OMAP34XX_MCBSP_PDATA_SZ                ARRAY_SIZE(omap34xx_mcbsp_pdata)
-#define OMAP34XX_MCBSP_REG_NUM         (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
-#else
-#define omap34xx_mcbsp_pdata           NULL
-#define OMAP34XX_MCBSP_PDATA_SZ                0
-#define OMAP34XX_MCBSP_REG_NUM         0
-#endif
+       pdata = kzalloc(sizeof(struct omap_mcbsp_platform_data), GFP_KERNEL);
+       if (!pdata) {
+               pr_err("%s: No memory for mcbsp\n", __func__);
+               return -ENOMEM;
+       }
 
-static struct omap_mcbsp_platform_data omap44xx_mcbsp_pdata[] = {
-       {
-               .phys_base      = OMAP44XX_MCBSP1_BASE,
-               .dma_rx_sync    = OMAP44XX_DMA_MCBSP1_RX,
-               .dma_tx_sync    = OMAP44XX_DMA_MCBSP1_TX,
-               .tx_irq         = OMAP44XX_IRQ_MCBSP1,
-       },
-       {
-               .phys_base      = OMAP44XX_MCBSP2_BASE,
-               .dma_rx_sync    = OMAP44XX_DMA_MCBSP2_RX,
-               .dma_tx_sync    = OMAP44XX_DMA_MCBSP2_TX,
-               .tx_irq         = OMAP44XX_IRQ_MCBSP2,
-               /* XXX .ops ? */
-       },
-       {
-               .phys_base      = OMAP44XX_MCBSP3_BASE,
-               .dma_rx_sync    = OMAP44XX_DMA_MCBSP3_RX,
-               .dma_tx_sync    = OMAP44XX_DMA_MCBSP3_TX,
-               .tx_irq         = OMAP44XX_IRQ_MCBSP3,
-               /* XXX .ops ? */
-       },
-       {
-               .phys_base      = OMAP44XX_MCBSP4_BASE,
-               .dma_rx_sync    = OMAP44XX_DMA_MCBSP4_RX,
-               .dma_tx_sync    = OMAP44XX_DMA_MCBSP4_TX,
-               .tx_irq         = OMAP44XX_IRQ_MCBSP4,
-               /* XXX .ops ? */
-       },
-};
-#define OMAP44XX_MCBSP_PDATA_SZ                ARRAY_SIZE(omap44xx_mcbsp_pdata)
-#define OMAP44XX_MCBSP_REG_NUM         (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
+       if (cpu_is_omap34xx()) {
+               pdata->dma_op_mode = MCBSP_DMA_MODE_ELEMENT;
+               if (id == 2)
+                       pdata->buffer_size = 0x500;
+               else
+                       pdata->buffer_size = 0x80;
+       } else {
+               pdata->dma_op_mode = -EINVAL;
+               pdata->buffer_size = 0;
+       }
 
Quoted 13 lines

arch/arm/mach-omap2/mcbsp.c int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id) · line 156

Quoted 11 lines
arch/arm/mach-omap2/mcbsp.c +10 -1
-static int __init omap2_mcbsp_init(void)
+       sscanf(oh->name, "mcbsp%d",&id);
+       sprintf(dev_name, "mcbsp%d_sidetone", id);
+       oh_device[0] = oh;
+
+       for (i = 0; i<   no_of_st ; i++) {
+               if (!strcmp(dev_name, oh_st_device[i]->name)) {
+                       oh_device[1] = oh_st_device[i];
+                       count++;
+               }
+       }

Pfuu, it took me a while to follow how all that stuff was working :-)

sorry for that :-)

Quoted 8 lines

Since the sidetone block is tightly coupled to the mcbsp, you should simply add this information directly as a attribute of the mcbsp2& 3 hwmod dev_attr.

You will then easily detect which one does have a sidetone connected to it and avoid all this code.

Review

Quoted 8 lines
(quoted diff) +5 -0
+static struct omap_mcbsp_dev_attr omap34xx_mcbsp2_dev_attr = {
+       .sidetone       = "mcbsp2_sidetone",
+};
 
+static struct omap_hwmod omap34xx_mcbsp2_hwmod = {
...
+       .dev_attr       =&omap34xx_mcbsp2_dev_attr,
...

Thats a good suggestion. Thanks.

-Kishon

Quoted 366 lines

Regards,
Benoit

Quoted 359 lines
arch/arm/mach-omap2/mcbsp.c +27 -25
+
+       od = omap_device_build_ss(name, id, oh_device, count, pdata,
+                               sizeof(*pdata), omap2_mcbsp_latency,
+                               ARRAY_SIZE(omap2_mcbsp_latency), false);
+       if (IS_ERR(od))  {
+               pr_err("%s: Cant build omap_device for %s:%s.\n", __func__,
+                                       name, oh->name);
+               kfree(pdata);
+               return PTR_ERR(od);
+       }
+       omap_mcbsp_count++;
+       return 0;
+}
+
+static int omap_mcbsp_st(struct omap_hwmod *oh, void *user)
   {
-       if (cpu_is_omap2420()) {
-               omap_mcbsp_count = OMAP2420_MCBSP_PDATA_SZ;
-               omap_mcbsp_cache_size = OMAP2420_MCBSP_REG_NUM * sizeof(u16);
-       } else if (cpu_is_omap2430()) {
-               omap_mcbsp_count = OMAP2430_MCBSP_PDATA_SZ;
-               omap_mcbsp_cache_size = OMAP2430_MCBSP_REG_NUM * sizeof(u32);
-       } else if (cpu_is_omap34xx()) {
-               omap_mcbsp_count = OMAP34XX_MCBSP_PDATA_SZ;
-               omap_mcbsp_cache_size = OMAP34XX_MCBSP_REG_NUM * sizeof(u32);
-       } else if (cpu_is_omap44xx()) {
-               omap_mcbsp_count = OMAP44XX_MCBSP_PDATA_SZ;
-               omap_mcbsp_cache_size = OMAP44XX_MCBSP_REG_NUM * sizeof(u32);
+       if (!oh) {
+               pr_err("%s:NULL hwmod pointer (oh)\n", __func__);
+               return -EINVAL;
          }
+       oh_st_device[no_of_st++] = oh;
+       return 0;
+}
+
+static int __init omap2_mcbsp_init(void)
+{
+       omap_hwmod_for_each_by_class("mcbsp_sidetone", omap_mcbsp_st,
+                                       NULL);
+       omap_hwmod_for_each_by_class("mcbsp", omap_init_mcbsp, NULL);
 
          mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *),
                                                                  GFP_KERNEL);
          if (!mcbsp_ptr)
                  return -ENOMEM;
 
-       if (cpu_is_omap2420())
-               omap_mcbsp_register_board_cfg(omap2420_mcbsp_pdata,
-                                               OMAP2420_MCBSP_PDATA_SZ);
-       if (cpu_is_omap2430())
-               omap_mcbsp_register_board_cfg(omap2430_mcbsp_pdata,
-                                               OMAP2430_MCBSP_PDATA_SZ);
-       if (cpu_is_omap34xx())
-               omap_mcbsp_register_board_cfg(omap34xx_mcbsp_pdata,
-                                               OMAP34XX_MCBSP_PDATA_SZ);
-       if (cpu_is_omap44xx())
-               omap_mcbsp_register_board_cfg(omap44xx_mcbsp_pdata,
-                                               OMAP44XX_MCBSP_PDATA_SZ);
-
          return omap_mcbsp_init();
   }
   arch_initcall(omap2_mcbsp_init);
arch/arm/plat-omap/include/plat/mcbsp.h +1 -5
index 4da6f94..1ff283c 100644
@@ -418,11 +418,9 @@ struct omap_mcbsp_platform_data {
          u8 dma_rx_sync, dma_tx_sync;
          u16 rx_irq, tx_irq;
          struct omap_mcbsp_ops *ops;
-#ifdef CONFIG_ARCH_OMAP3
-       /* Sidetone block for McBSP 2 and 3 */
          unsigned long phys_base_st;
          u16 buffer_size;
-#endif
+       int dma_op_mode;
   };
 
   struct omap_mcbsp_st_data {
@@ -466,12 +464,10 @@ struct omap_mcbsp {
          struct omap_mcbsp_platform_data *pdata;
          struct clk *iclk;
          struct clk *fclk;
-#ifdef CONFIG_ARCH_OMAP3
          struct omap_mcbsp_st_data *st_data;
          int dma_op_mode;
          u16 max_tx_thres;
          u16 max_rx_thres;
-#endif
          void *reg_cache;
   };
   extern struct omap_mcbsp **mcbsp_ptr;
arch/arm/plat-omap/mcbsp.c +85 -105
index eac4b97..c7c6a83 100644
@@ -27,6 +27,8 @@
 
   #include<plat/dma.h>
   #include<plat/mcbsp.h>
+#include<plat/omap_hwmod.h>
+#include<plat/omap_device.h>
 
   #include "../mach-omap2/cm-regbits-34xx.h"
 
@@ -1466,7 +1468,6 @@ void omap_mcbsp_set_spi_mode(unsigned int id,
   }
   EXPORT_SYMBOL(omap_mcbsp_set_spi_mode);
 
-#ifdef CONFIG_ARCH_OMAP3
   #define max_thres(m)                   (mcbsp->pdata->buffer_size)
   #define valid_threshold(m, val)                ((val)<= max_thres(m))
   #define THRESHOLD_PROP_BUILDER(prop)                                   \
@@ -1645,98 +1646,6 @@ static const struct attribute_group sidetone_attr_group = {
          .attrs = (struct attribute **)sidetone_attrs,
   };
 
-static int __devinit omap_st_add(struct omap_mcbsp *mcbsp)
-{
-       struct omap_mcbsp_platform_data *pdata = mcbsp->pdata;
-       struct omap_mcbsp_st_data *st_data;
-       int err;
-
-       st_data = kzalloc(sizeof(*mcbsp->st_data), GFP_KERNEL);
-       if (!st_data) {
-               err = -ENOMEM;
-               goto err1;
-       }
-
-       st_data->io_base_st = ioremap(pdata->phys_base_st, SZ_4K);
-       if (!st_data->io_base_st) {
-               err = -ENOMEM;
-               goto err2;
-       }
-
-       err = sysfs_create_group(&mcbsp->dev->kobj,&sidetone_attr_group);
-       if (err)
-               goto err3;
-
-       mcbsp->st_data = st_data;
-       return 0;
-
-err3:
-       iounmap(st_data->io_base_st);
-err2:
-       kfree(st_data);
-err1:
-       return err;
-
-}
-
-static void __devexit omap_st_remove(struct omap_mcbsp *mcbsp)
-{
-       struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
-
-       if (st_data) {
-               sysfs_remove_group(&mcbsp->dev->kobj,&sidetone_attr_group);
-               iounmap(st_data->io_base_st);
-               kfree(st_data);
-       }
-}
-
-static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp)
-{
-       mcbsp->dma_op_mode = MCBSP_DMA_MODE_ELEMENT;
-       if (cpu_is_omap34xx()) {
-               /*
-                * Initially configure the maximum thresholds to a safe value.
-                * The McBSP FIFO usage with these values should not go under
-                * 16 locations.
-                * If the whole FIFO without safety buffer is used, than there
-                * is a possibility that the DMA will be not able to push the
-                * new data on time, causing channel shifts in runtime.
-                */
-               mcbsp->max_tx_thres = max_thres(mcbsp) - 0x10;
-               mcbsp->max_rx_thres = max_thres(mcbsp) - 0x10;
-               /*
-                * REVISIT: Set dmap_op_mode to THRESHOLD as default
-                * for mcbsp2 instances.
-                */
-               if (omap_additional_add(mcbsp->dev))
-                       dev_warn(mcbsp->dev,
-                               "Unable to create additional controls\n");
-
-               if (mcbsp->id == 2 || mcbsp->id == 3)
-                       if (omap_st_add(mcbsp))
-                               dev_warn(mcbsp->dev,
-                                "Unable to create sidetone controls\n");
-
-       } else {
-               mcbsp->max_tx_thres = -EINVAL;
-               mcbsp->max_rx_thres = -EINVAL;
-       }
-}
-
-static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp)
-{
-       if (cpu_is_omap34xx()) {
-               omap_additional_remove(mcbsp->dev);
-
-               if (mcbsp->id == 2 || mcbsp->id == 3)
-                       omap_st_remove(mcbsp);
-       }
-}
-#else
-static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp) {}
-static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp) {}
-#endif /* CONFIG_ARCH_OMAP3 */
-
   /*
    * McBSP1 and McBSP3 are directly mapped on 1610 and 1510.
    * 730 has only 2 McBSP, and both of them are MPU peripherals.
@@ -1746,6 +1655,7 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
          struct omap_mcbsp_platform_data *pdata = pdev->dev.platform_data;
          struct omap_mcbsp *mcbsp;
          int id = pdev->id - 1;
+       struct resource *res;
          int ret = 0;
 
          if (!pdata) {
@@ -1775,25 +1685,50 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
          mcbsp->dma_tx_lch = -1;
          mcbsp->dma_rx_lch = -1;
 
-       mcbsp->phys_base = pdata->phys_base;
-       mcbsp->io_base = ioremap(pdata->phys_base, SZ_4K);
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               dev_err(&pdev->dev, "%s:mcbsp%d has invalid memory resource\n",
+                                       __func__, pdev->id);
+               ret = -ENOMEM;
+               goto exit;
+       }
+       mcbsp->phys_base = res->start;
+       mcbsp->io_base = ioremap(res->start, resource_size(res));
          if (!mcbsp->io_base) {
                  ret = -ENOMEM;
                  goto err_ioremap;
          }
 
+       omap_mcbsp_cache_size = resource_size(res);
+
          /* Default I/O is IRQ based */
          mcbsp->io_type = OMAP_MCBSP_IRQ_IO;
-       mcbsp->tx_irq = pdata->tx_irq;
-       mcbsp->rx_irq = pdata->rx_irq;
-       mcbsp->dma_rx_sync = pdata->dma_rx_sync;
-       mcbsp->dma_tx_sync = pdata->dma_tx_sync;
+       mcbsp->tx_irq = platform_get_irq_byname(pdev, "tx");
+       mcbsp->rx_irq = platform_get_irq_byname(pdev, "rx");
+
+       res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx");
+       if (!res) {
+               dev_err(&pdev->dev, "%s:mcbsp%d has invalid DMA channel\n",
+                                       __func__, pdev->id);
+               ret = -ENODEV;
+               goto err_res;
+       }
+       mcbsp->dma_rx_sync = res->start;
+
+       res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx");
+       if (!res) {
+               dev_err(&pdev->dev, "%s:mcbsp%d has invalid DMA channel\n",
+                                       __func__, pdev->id);
+               ret = -ENODEV;
+               goto err_res;
+       }
+       mcbsp->dma_tx_sync = res->start;
 
          mcbsp->iclk = clk_get(&pdev->dev, "ick");
          if (IS_ERR(mcbsp->iclk)) {
                  ret = PTR_ERR(mcbsp->iclk);
                  dev_err(&pdev->dev, "unable to get ick: %d\n", ret);
-               goto err_iclk;
+               goto err_res;
          }
 
          mcbsp->fclk = clk_get(&pdev->dev, "fck");
@@ -1808,14 +1743,53 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
          mcbsp_ptr[id] = mcbsp;
          platform_set_drvdata(pdev, mcbsp);
 
-       /* Initialize mcbsp properties for OMAP34XX if needed / applicable */
-       omap34xx_device_init(mcbsp);
+       omap_additional_add(mcbsp->dev);
+       if (pdata->dma_op_mode != -EINVAL) {
+               /*
+                * Initially configure the maximum thresholds to a safe value.
+                * The McBSP FIFO usage with these values should not go under
+                * 16 locations.
+                * If the whole FIFO without safety buffer is used, than there
+                * is a possibility that the DMA will be not able to push the
+                * new data on time, causing channel shifts in runtime.
+                */
+               mcbsp->max_tx_thres = max_thres(mcbsp) - 0x10 ;
+               mcbsp->max_rx_thres = max_thres(mcbsp) - 0x10 ;
+       }
+
+       if (cpu_is_omap34xx()) {
+               res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+               if (res) {
+                       mcbsp->st_data = kzalloc(sizeof(*mcbsp->st_data),
+                                               GFP_KERNEL);
+                       if (!mcbsp->st_data) {
+                               ret = -ENOMEM;
+                               goto err_st_data;
+                       }
+                       mcbsp->st_data->io_base_st = ioremap(res->start,
+                                               resource_size(res));
+                       if (!mcbsp->st_data->io_base_st) {
+                               ret = -ENOMEM;
+                               goto err_io_st;
+                       }
+                       ret = sysfs_create_group(&mcbsp->dev->kobj,
+&sidetone_attr_group);
+                       if (ret)
+                               goto err_sysfs;
+               }
+       }
 
          return 0;
 
+err_sysfs:
+       iounmap(mcbsp->st_data->io_base_st);
+err_io_st:
+       kfree(mcbsp->st_data);
+err_st_data:
+       clk_put(mcbsp->fclk);
   err_fclk:
          clk_put(mcbsp->iclk);
-err_iclk:
+err_res:
          iounmap(mcbsp->io_base);
   err_ioremap:
          kfree(mcbsp);
@@ -1834,7 +1808,14 @@ static int __devexit omap_mcbsp_remove(struct platform_device *pdev)
                                  mcbsp->pdata->ops->free)
                          mcbsp->pdata->ops->free(mcbsp->id);
 
-               omap34xx_device_exit(mcbsp);
+               omap_additional_remove(mcbsp->dev);
+
+               if (mcbsp->st_data) {
+                       sysfs_remove_group(&mcbsp->dev->kobj,
+&sidetone_attr_group);
+                       iounmap(mcbsp->st_data->io_base_st);
+                       kfree(mcbsp->st_data);
+               }
 
                  clk_disable(mcbsp->fclk);
                  clk_disable(mcbsp->iclk);
--

1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#12 lore raw

Re: [PATCH 4/7] [RFC] OMAP: hwmod implementation for MCBSP

Quoted 251 lines · KISHON VIJAY
Quoted 224 lines · Benoit
Quoted 223 lines · Kishon Vijay Abraham I
---
    arch/arm/mach-omap2/mcbsp.c             |  251 +++++++++----------------------
    arch/arm/plat-omap/include/plat/mcbsp.h |    6 +-
    arch/arm/plat-omap/mcbsp.c              |  189 +++++++++++-------------
    3 files changed, 159 insertions(+), 287 deletions(-)
arch/arm/mach-omap2/mcbsp.c +36 -152
index eba9fa1..25c6703 100644
@@ -22,9 +22,13 @@
    #include<plat/dma.h>
    #include<plat/cpu.h>
    #include<plat/mcbsp.h>
+#include<plat/omap_hwmod.h>
+#include<plat/omap_device.h>
 
    #include "control.h"
 
+static struct omap_hwmod *oh_st_device[] = {NULL, NULL};
+static int no_of_st;
 
    /* McBSP internal signal muxing functions */
 
@@ -101,199 +105,90 @@ int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id)
    }
    EXPORT_SYMBOL(omap2_mcbsp_set_clks_src);
 
-
-/* Platform data */
-
-#ifdef CONFIG_ARCH_OMAP2420
-static struct omap_mcbsp_platform_data omap2420_mcbsp_pdata[] = {
-       {
-               .phys_base      = OMAP24XX_MCBSP1_BASE,
-               .dma_rx_sync    = OMAP24XX_DMA_MCBSP1_RX,
-               .dma_tx_sync    = OMAP24XX_DMA_MCBSP1_TX,
-               .rx_irq         = INT_24XX_MCBSP1_IRQ_RX,
-               .tx_irq         = INT_24XX_MCBSP1_IRQ_TX,
-       },
+struct omap_device_pm_latency omap2_mcbsp_latency[] = {
           {
-               .phys_base      = OMAP24XX_MCBSP2_BASE,
-               .dma_rx_sync    = OMAP24XX_DMA_MCBSP2_RX,
-               .dma_tx_sync    = OMAP24XX_DMA_MCBSP2_TX,
-               .rx_irq         = INT_24XX_MCBSP2_IRQ_RX,
-               .tx_irq         = INT_24XX_MCBSP2_IRQ_TX,
+               .deactivate_func = omap_device_idle_hwmods,
+               .activate_func   = omap_device_enable_hwmods,
+               .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
           },
    };
-#define OMAP2420_MCBSP_PDATA_SZ                ARRAY_SIZE(omap2420_mcbsp_pdata)
-#define OMAP2420_MCBSP_REG_NUM         (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
-#else
-#define omap2420_mcbsp_pdata           NULL
-#define OMAP2420_MCBSP_PDATA_SZ                0
-#define OMAP2420_MCBSP_REG_NUM         0
-#endif
 
-#ifdef CONFIG_ARCH_OMAP2430
-static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = {
-       {
-               .phys_base      = OMAP24XX_MCBSP1_BASE,
-               .dma_rx_sync    = OMAP24XX_DMA_MCBSP1_RX,
-               .dma_tx_sync    = OMAP24XX_DMA_MCBSP1_TX,
-               .rx_irq         = INT_24XX_MCBSP1_IRQ_RX,
-               .tx_irq         = INT_24XX_MCBSP1_IRQ_TX,
-       },
-       {
-               .phys_base      = OMAP24XX_MCBSP2_BASE,
-               .dma_rx_sync    = OMAP24XX_DMA_MCBSP2_RX,
-               .dma_tx_sync    = OMAP24XX_DMA_MCBSP2_TX,
-               .rx_irq         = INT_24XX_MCBSP2_IRQ_RX,
-               .tx_irq         = INT_24XX_MCBSP2_IRQ_TX,
-       },
-       {
-               .phys_base      = OMAP2430_MCBSP3_BASE,
-               .dma_rx_sync    = OMAP24XX_DMA_MCBSP3_RX,
-               .dma_tx_sync    = OMAP24XX_DMA_MCBSP3_TX,
-               .rx_irq         = INT_24XX_MCBSP3_IRQ_RX,
-               .tx_irq         = INT_24XX_MCBSP3_IRQ_TX,
-       },
-       {
-               .phys_base      = OMAP2430_MCBSP4_BASE,
-               .dma_rx_sync    = OMAP24XX_DMA_MCBSP4_RX,
-               .dma_tx_sync    = OMAP24XX_DMA_MCBSP4_TX,
-               .rx_irq         = INT_24XX_MCBSP4_IRQ_RX,
-               .tx_irq         = INT_24XX_MCBSP4_IRQ_TX,
-       },
-       {
-               .phys_base      = OMAP2430_MCBSP5_BASE,
-               .dma_rx_sync    = OMAP24XX_DMA_MCBSP5_RX,
-               .dma_tx_sync    = OMAP24XX_DMA_MCBSP5_TX,
-               .rx_irq         = INT_24XX_MCBSP5_IRQ_RX,
-               .tx_irq         = INT_24XX_MCBSP5_IRQ_TX,
-       },
-};
-#define OMAP2430_MCBSP_PDATA_SZ                ARRAY_SIZE(omap2430_mcbsp_pdata)
-#define OMAP2430_MCBSP_REG_NUM         (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
-#else
-#define omap2430_mcbsp_pdata           NULL
-#define OMAP2430_MCBSP_PDATA_SZ                0
-#define OMAP2430_MCBSP_REG_NUM         0
-#endif
+static int omap_init_mcbsp(struct omap_hwmod *oh, void *user)
+{
+       int id, count = 1, i;
+       char *name = "omap-mcbsp";
+       char dev_name[16];
+       struct omap_hwmod *oh_device[2];
+       struct omap_mcbsp_platform_data *pdata;
+       struct omap_device *od;
+
+       if (!oh) {
+               pr_err("%s:NULL hwmod pointer (oh)\n", __func__);
+               return -EINVAL;
+       }
 
-#ifdef CONFIG_ARCH_OMAP3
-static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
-       {
-               .phys_base      = OMAP34XX_MCBSP1_BASE,
-               .dma_rx_sync    = OMAP24XX_DMA_MCBSP1_RX,
-               .dma_tx_sync    = OMAP24XX_DMA_MCBSP1_TX,
-               .rx_irq         = INT_24XX_MCBSP1_IRQ_RX,
-               .tx_irq         = INT_24XX_MCBSP1_IRQ_TX,
-               .buffer_size    = 0x80, /* The FIFO has 128 locations */
-       },
-       {
-               .phys_base      = OMAP34XX_MCBSP2_BASE,
-               .phys_base_st   = OMAP34XX_MCBSP2_ST_BASE,
-               .dma_rx_sync    = OMAP24XX_DMA_MCBSP2_RX,
-               .dma_tx_sync    = OMAP24XX_DMA_MCBSP2_TX,
-               .rx_irq         = INT_24XX_MCBSP2_IRQ_RX,
-               .tx_irq         = INT_24XX_MCBSP2_IRQ_TX,
-               .buffer_size    = 0x500, /* The FIFO has 1024 + 256 locations */
-       },
-       {
-               .phys_base      = OMAP34XX_MCBSP3_BASE,
-               .phys_base_st   = OMAP34XX_MCBSP3_ST_BASE,
-               .dma_rx_sync    = OMAP24XX_DMA_MCBSP3_RX,
-               .dma_tx_sync    = OMAP24XX_DMA_MCBSP3_TX,
-               .rx_irq         = INT_24XX_MCBSP3_IRQ_RX,
-               .tx_irq         = INT_24XX_MCBSP3_IRQ_TX,
-               .buffer_size    = 0x80, /* The FIFO has 128 locations */
-       },
-       {
-               .phys_base      = OMAP34XX_MCBSP4_BASE,
-               .dma_rx_sync    = OMAP24XX_DMA_MCBSP4_RX,
-               .dma_tx_sync    = OMAP24XX_DMA_MCBSP4_TX,
-               .rx_irq         = INT_24XX_MCBSP4_IRQ_RX,
-               .tx_irq         = INT_24XX_MCBSP4_IRQ_TX,
-               .buffer_size    = 0x80, /* The FIFO has 128 locations */
-       },
-       {
-               .phys_base      = OMAP34XX_MCBSP5_BASE,
-               .dma_rx_sync    = OMAP24XX_DMA_MCBSP5_RX,
-               .dma_tx_sync    = OMAP24XX_DMA_MCBSP5_TX,
-               .rx_irq         = INT_24XX_MCBSP5_IRQ_RX,
-               .tx_irq         = INT_24XX_MCBSP5_IRQ_TX,
-               .buffer_size    = 0x80, /* The FIFO has 128 locations */
-       },
-};
-#define OMAP34XX_MCBSP_PDATA_SZ                ARRAY_SIZE(omap34xx_mcbsp_pdata)
-#define OMAP34XX_MCBSP_REG_NUM         (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
-#else
-#define omap34xx_mcbsp_pdata           NULL
-#define OMAP34XX_MCBSP_PDATA_SZ                0
-#define OMAP34XX_MCBSP_REG_NUM         0
-#endif
+       pdata = kzalloc(sizeof(struct omap_mcbsp_platform_data), GFP_KERNEL);
+       if (!pdata) {
+               pr_err("%s: No memory for mcbsp\n", __func__);
+               return -ENOMEM;
+       }
 
-static struct omap_mcbsp_platform_data omap44xx_mcbsp_pdata[] = {
-       {
-               .phys_base      = OMAP44XX_MCBSP1_BASE,
-               .dma_rx_sync    = OMAP44XX_DMA_MCBSP1_RX,
-               .dma_tx_sync    = OMAP44XX_DMA_MCBSP1_TX,
-               .tx_irq         = OMAP44XX_IRQ_MCBSP1,
-       },
-       {
-               .phys_base      = OMAP44XX_MCBSP2_BASE,
-               .dma_rx_sync    = OMAP44XX_DMA_MCBSP2_RX,
-               .dma_tx_sync    = OMAP44XX_DMA_MCBSP2_TX,
-               .tx_irq         = OMAP44XX_IRQ_MCBSP2,
-               /* XXX .ops ? */
-       },
-       {
-               .phys_base      = OMAP44XX_MCBSP3_BASE,
-               .dma_rx_sync    = OMAP44XX_DMA_MCBSP3_RX,
-               .dma_tx_sync    = OMAP44XX_DMA_MCBSP3_TX,
-               .tx_irq         = OMAP44XX_IRQ_MCBSP3,
-               /* XXX .ops ? */
-       },
-       {
-               .phys_base      = OMAP44XX_MCBSP4_BASE,
-               .dma_rx_sync    = OMAP44XX_DMA_MCBSP4_RX,
-               .dma_tx_sync    = OMAP44XX_DMA_MCBSP4_TX,
-               .tx_irq         = OMAP44XX_IRQ_MCBSP4,
-               /* XXX .ops ? */
-       },
-};
-#define OMAP44XX_MCBSP_PDATA_SZ                ARRAY_SIZE(omap44xx_mcbsp_pdata)
-#define OMAP44XX_MCBSP_REG_NUM         (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1)
+       if (cpu_is_omap34xx()) {
+               pdata->dma_op_mode = MCBSP_DMA_MODE_ELEMENT;
+               if (id == 2)
+                       pdata->buffer_size = 0x500;
+               else
+                       pdata->buffer_size = 0x80;
+       } else {
+               pdata->dma_op_mode = -EINVAL;
+               pdata->buffer_size = 0;
+       }
 
Quoted 13 lines

arch/arm/mach-omap2/mcbsp.c int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id) · line 156

Quoted 11 lines
arch/arm/mach-omap2/mcbsp.c +10 -1
-static int __init omap2_mcbsp_init(void)
+       sscanf(oh->name, "mcbsp%d",&id);
+       sprintf(dev_name, "mcbsp%d_sidetone", id);
+       oh_device[0] = oh;
+
+       for (i = 0; i<    no_of_st ; i++) {
+               if (!strcmp(dev_name, oh_st_device[i]->name)) {
+                       oh_device[1] = oh_st_device[i];
+                       count++;
+               }
+       }

Pfuu, it took me a while to follow how all that stuff was working :-)

sorry for that :-)

Quoted 12 lines

Since the sidetone block is tightly coupled to the mcbsp, you should
simply add this information directly as a attribute of the mcbsp2& 3
hwmod dev_attr.

You will then easily detect which one does have a sidetone connected to it and avoid all this code.

(quoted diff) +3 -0
+static struct omap_mcbsp_dev_attr omap34xx_mcbsp2_dev_attr = {
+       .sidetone       = "mcbsp2_sidetone",
+};
Quoted 6 lines

Review

Quoted 4 lines
(quoted diff) +2 -0
+static struct omap_hwmod omap34xx_mcbsp2_hwmod = {
...
+       .dev_attr       =&omap34xx_mcbsp2_dev_attr,
...

Thats a good suggestion. Thanks.

Ahh... there's a problem with that approach. Using a device attribute
will help to get rid of only
+ sprintf(dev_name, "mcbsp%d_sidetone", id);
We'll still need to have omap_mcbsp_st() and the following code
snippet

+ for (i = 0; i< no_of_st ; i++) {
+ if (!strcmp(dev_name, oh_st_device[i]->name)) {
+ oh_device[1] = oh_st_device[i];
+ count++;
+ }
+ }
using a dev_attr to get the name of sidetone will be helpful only
when we can use omap_hwmod_lookup() to get the oh address in omap_init_mcbsp(). But omap_init_mcbsp() is called as a callback to omap_hwmod_for_each_by_class() holding 'omap_hwmod_mutex' which disallows call to any other hwmod functions.
I feel adding a dev_attr to get rid of two sprintf instructions
which involve modifying hwmod database file, adding a new structure is not a better option.
Please give your take on this.

-Kishon

Quoted 368 lines

-Kishon

Quoted 366 lines

Regards,
Benoit

Quoted 359 lines
arch/arm/mach-omap2/mcbsp.c +27 -25
+
+       od = omap_device_build_ss(name, id, oh_device, count, pdata,
+                               sizeof(*pdata), omap2_mcbsp_latency,
+                               ARRAY_SIZE(omap2_mcbsp_latency), false);
+       if (IS_ERR(od))  {
+               pr_err("%s: Cant build omap_device for %s:%s.\n", __func__,
+                                       name, oh->name);
+               kfree(pdata);
+               return PTR_ERR(od);
+       }
+       omap_mcbsp_count++;
+       return 0;
+}
+
+static int omap_mcbsp_st(struct omap_hwmod *oh, void *user)
    {
-       if (cpu_is_omap2420()) {
-               omap_mcbsp_count = OMAP2420_MCBSP_PDATA_SZ;
-               omap_mcbsp_cache_size = OMAP2420_MCBSP_REG_NUM * sizeof(u16);
-       } else if (cpu_is_omap2430()) {
-               omap_mcbsp_count = OMAP2430_MCBSP_PDATA_SZ;
-               omap_mcbsp_cache_size = OMAP2430_MCBSP_REG_NUM * sizeof(u32);
-       } else if (cpu_is_omap34xx()) {
-               omap_mcbsp_count = OMAP34XX_MCBSP_PDATA_SZ;
-               omap_mcbsp_cache_size = OMAP34XX_MCBSP_REG_NUM * sizeof(u32);
-       } else if (cpu_is_omap44xx()) {
-               omap_mcbsp_count = OMAP44XX_MCBSP_PDATA_SZ;
-               omap_mcbsp_cache_size = OMAP44XX_MCBSP_REG_NUM * sizeof(u32);
+       if (!oh) {
+               pr_err("%s:NULL hwmod pointer (oh)\n", __func__);
+               return -EINVAL;
           }
+       oh_st_device[no_of_st++] = oh;
+       return 0;
+}
+
+static int __init omap2_mcbsp_init(void)
+{
+       omap_hwmod_for_each_by_class("mcbsp_sidetone", omap_mcbsp_st,
+                                       NULL);
+       omap_hwmod_for_each_by_class("mcbsp", omap_init_mcbsp, NULL);
 
           mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *),
                                                                   GFP_KERNEL);
           if (!mcbsp_ptr)
                   return -ENOMEM;
 
-       if (cpu_is_omap2420())
-               omap_mcbsp_register_board_cfg(omap2420_mcbsp_pdata,
-                                               OMAP2420_MCBSP_PDATA_SZ);
-       if (cpu_is_omap2430())
-               omap_mcbsp_register_board_cfg(omap2430_mcbsp_pdata,
-                                               OMAP2430_MCBSP_PDATA_SZ);
-       if (cpu_is_omap34xx())
-               omap_mcbsp_register_board_cfg(omap34xx_mcbsp_pdata,
-                                               OMAP34XX_MCBSP_PDATA_SZ);
-       if (cpu_is_omap44xx())
-               omap_mcbsp_register_board_cfg(omap44xx_mcbsp_pdata,
-                                               OMAP44XX_MCBSP_PDATA_SZ);
-
           return omap_mcbsp_init();
    }
    arch_initcall(omap2_mcbsp_init);
arch/arm/plat-omap/include/plat/mcbsp.h +1 -5
index 4da6f94..1ff283c 100644
@@ -418,11 +418,9 @@ struct omap_mcbsp_platform_data {
           u8 dma_rx_sync, dma_tx_sync;
           u16 rx_irq, tx_irq;
           struct omap_mcbsp_ops *ops;
-#ifdef CONFIG_ARCH_OMAP3
-       /* Sidetone block for McBSP 2 and 3 */
           unsigned long phys_base_st;
           u16 buffer_size;
-#endif
+       int dma_op_mode;
    };
 
    struct omap_mcbsp_st_data {
@@ -466,12 +464,10 @@ struct omap_mcbsp {
           struct omap_mcbsp_platform_data *pdata;
           struct clk *iclk;
           struct clk *fclk;
-#ifdef CONFIG_ARCH_OMAP3
           struct omap_mcbsp_st_data *st_data;
           int dma_op_mode;
           u16 max_tx_thres;
           u16 max_rx_thres;
-#endif
           void *reg_cache;
    };
    extern struct omap_mcbsp **mcbsp_ptr;
arch/arm/plat-omap/mcbsp.c +85 -105
index eac4b97..c7c6a83 100644
@@ -27,6 +27,8 @@
 
    #include<plat/dma.h>
    #include<plat/mcbsp.h>
+#include<plat/omap_hwmod.h>
+#include<plat/omap_device.h>
 
    #include "../mach-omap2/cm-regbits-34xx.h"
 
@@ -1466,7 +1468,6 @@ void omap_mcbsp_set_spi_mode(unsigned int id,
    }
    EXPORT_SYMBOL(omap_mcbsp_set_spi_mode);
 
-#ifdef CONFIG_ARCH_OMAP3
    #define max_thres(m)                   (mcbsp->pdata->buffer_size)
    #define valid_threshold(m, val)                ((val)<= max_thres(m))
    #define THRESHOLD_PROP_BUILDER(prop)                                   \
@@ -1645,98 +1646,6 @@ static const struct attribute_group sidetone_attr_group = {
           .attrs = (struct attribute **)sidetone_attrs,
    };
 
-static int __devinit omap_st_add(struct omap_mcbsp *mcbsp)
-{
-       struct omap_mcbsp_platform_data *pdata = mcbsp->pdata;
-       struct omap_mcbsp_st_data *st_data;
-       int err;
-
-       st_data = kzalloc(sizeof(*mcbsp->st_data), GFP_KERNEL);
-       if (!st_data) {
-               err = -ENOMEM;
-               goto err1;
-       }
-
-       st_data->io_base_st = ioremap(pdata->phys_base_st, SZ_4K);
-       if (!st_data->io_base_st) {
-               err = -ENOMEM;
-               goto err2;
-       }
-
-       err = sysfs_create_group(&mcbsp->dev->kobj,&sidetone_attr_group);
-       if (err)
-               goto err3;
-
-       mcbsp->st_data = st_data;
-       return 0;
-
-err3:
-       iounmap(st_data->io_base_st);
-err2:
-       kfree(st_data);
-err1:
-       return err;
-
-}
-
-static void __devexit omap_st_remove(struct omap_mcbsp *mcbsp)
-{
-       struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
-
-       if (st_data) {
-               sysfs_remove_group(&mcbsp->dev->kobj,&sidetone_attr_group);
-               iounmap(st_data->io_base_st);
-               kfree(st_data);
-       }
-}
-
-static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp)
-{
-       mcbsp->dma_op_mode = MCBSP_DMA_MODE_ELEMENT;
-       if (cpu_is_omap34xx()) {
-               /*
-                * Initially configure the maximum thresholds to a safe value.
-                * The McBSP FIFO usage with these values should not go under
-                * 16 locations.
-                * If the whole FIFO without safety buffer is used, than there
-                * is a possibility that the DMA will be not able to push the
-                * new data on time, causing channel shifts in runtime.
-                */
-               mcbsp->max_tx_thres = max_thres(mcbsp) - 0x10;
-               mcbsp->max_rx_thres = max_thres(mcbsp) - 0x10;
-               /*
-                * REVISIT: Set dmap_op_mode to THRESHOLD as default
-                * for mcbsp2 instances.
-                */
-               if (omap_additional_add(mcbsp->dev))
-                       dev_warn(mcbsp->dev,
-                               "Unable to create additional controls\n");
-
-               if (mcbsp->id == 2 || mcbsp->id == 3)
-                       if (omap_st_add(mcbsp))
-                               dev_warn(mcbsp->dev,
-                                "Unable to create sidetone controls\n");
-
-       } else {
-               mcbsp->max_tx_thres = -EINVAL;
-               mcbsp->max_rx_thres = -EINVAL;
-       }
-}
-
-static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp)
-{
-       if (cpu_is_omap34xx()) {
-               omap_additional_remove(mcbsp->dev);
-
-               if (mcbsp->id == 2 || mcbsp->id == 3)
-                       omap_st_remove(mcbsp);
-       }
-}
-#else
-static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp) {}
-static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp) {}
-#endif /* CONFIG_ARCH_OMAP3 */
-
    /*
     * McBSP1 and McBSP3 are directly mapped on 1610 and 1510.
     * 730 has only 2 McBSP, and both of them are MPU peripherals.
@@ -1746,6 +1655,7 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
           struct omap_mcbsp_platform_data *pdata = pdev->dev.platform_data;
           struct omap_mcbsp *mcbsp;
           int id = pdev->id - 1;
+       struct resource *res;
           int ret = 0;
 
           if (!pdata) {
@@ -1775,25 +1685,50 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
           mcbsp->dma_tx_lch = -1;
           mcbsp->dma_rx_lch = -1;
 
-       mcbsp->phys_base = pdata->phys_base;
-       mcbsp->io_base = ioremap(pdata->phys_base, SZ_4K);
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               dev_err(&pdev->dev, "%s:mcbsp%d has invalid memory resource\n",
+                                       __func__, pdev->id);
+               ret = -ENOMEM;
+               goto exit;
+       }
+       mcbsp->phys_base = res->start;
+       mcbsp->io_base = ioremap(res->start, resource_size(res));
           if (!mcbsp->io_base) {
                   ret = -ENOMEM;
                   goto err_ioremap;
           }
 
+       omap_mcbsp_cache_size = resource_size(res);
+
           /* Default I/O is IRQ based */
           mcbsp->io_type = OMAP_MCBSP_IRQ_IO;
-       mcbsp->tx_irq = pdata->tx_irq;
-       mcbsp->rx_irq = pdata->rx_irq;
-       mcbsp->dma_rx_sync = pdata->dma_rx_sync;
-       mcbsp->dma_tx_sync = pdata->dma_tx_sync;
+       mcbsp->tx_irq = platform_get_irq_byname(pdev, "tx");
+       mcbsp->rx_irq = platform_get_irq_byname(pdev, "rx");
+
+       res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx");
+       if (!res) {
+               dev_err(&pdev->dev, "%s:mcbsp%d has invalid DMA channel\n",
+                                       __func__, pdev->id);
+               ret = -ENODEV;
+               goto err_res;
+       }
+       mcbsp->dma_rx_sync = res->start;
+
+       res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx");
+       if (!res) {
+               dev_err(&pdev->dev, "%s:mcbsp%d has invalid DMA channel\n",
+                                       __func__, pdev->id);
+               ret = -ENODEV;
+               goto err_res;
+       }
+       mcbsp->dma_tx_sync = res->start;
 
           mcbsp->iclk = clk_get(&pdev->dev, "ick");
           if (IS_ERR(mcbsp->iclk)) {
                   ret = PTR_ERR(mcbsp->iclk);
                   dev_err(&pdev->dev, "unable to get ick: %d\n", ret);
-               goto err_iclk;
+               goto err_res;
           }
 
           mcbsp->fclk = clk_get(&pdev->dev, "fck");
@@ -1808,14 +1743,53 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
           mcbsp_ptr[id] = mcbsp;
           platform_set_drvdata(pdev, mcbsp);
 
-       /* Initialize mcbsp properties for OMAP34XX if needed / applicable */
-       omap34xx_device_init(mcbsp);
+       omap_additional_add(mcbsp->dev);
+       if (pdata->dma_op_mode != -EINVAL) {
+               /*
+                * Initially configure the maximum thresholds to a safe value.
+                * The McBSP FIFO usage with these values should not go under
+                * 16 locations.
+                * If the whole FIFO without safety buffer is used, than there
+                * is a possibility that the DMA will be not able to push the
+                * new data on time, causing channel shifts in runtime.
+                */
+               mcbsp->max_tx_thres = max_thres(mcbsp) - 0x10 ;
+               mcbsp->max_rx_thres = max_thres(mcbsp) - 0x10 ;
+       }
+
+       if (cpu_is_omap34xx()) {
+               res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+               if (res) {
+                       mcbsp->st_data = kzalloc(sizeof(*mcbsp->st_data),
+                                               GFP_KERNEL);
+                       if (!mcbsp->st_data) {
+                               ret = -ENOMEM;
+                               goto err_st_data;
+                       }
+                       mcbsp->st_data->io_base_st = ioremap(res->start,
+                                               resource_size(res));
+                       if (!mcbsp->st_data->io_base_st) {
+                               ret = -ENOMEM;
+                               goto err_io_st;
+                       }
+                       ret = sysfs_create_group(&mcbsp->dev->kobj,
+&sidetone_attr_group);
+                       if (ret)
+                               goto err_sysfs;
+               }
+       }
 
           return 0;
 
+err_sysfs:
+       iounmap(mcbsp->st_data->io_base_st);
+err_io_st:
+       kfree(mcbsp->st_data);
+err_st_data:
+       clk_put(mcbsp->fclk);
    err_fclk:
           clk_put(mcbsp->iclk);
-err_iclk:
+err_res:
           iounmap(mcbsp->io_base);
    err_ioremap:
           kfree(mcbsp);
@@ -1834,7 +1808,14 @@ static int __devexit omap_mcbsp_remove(struct platform_device *pdev)
                                   mcbsp->pdata->ops->free)
                           mcbsp->pdata->ops->free(mcbsp->id);
 
-               omap34xx_device_exit(mcbsp);
+               omap_additional_remove(mcbsp->dev);
+
+               if (mcbsp->st_data) {
+                       sysfs_remove_group(&mcbsp->dev->kobj,
+&sidetone_attr_group);
+                       iounmap(mcbsp->st_data->io_base_st);
+                       kfree(mcbsp->st_data);
+               }
 
                   clk_disable(mcbsp->fclk);
                   clk_disable(mcbsp->iclk);
--

1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#13 lore raw

RFC PATCH 5/7 OMAP: hwmod: New API to modify the autoidle bit of sysconfig register

In reply to Kishon Vijay Abraham I

This patch was already posted in lo as RFC. But since no conclusion was drawn, I'm again posting this patch.

The previous patch and discussion can be found at
https://patchwork.kernel.org/patch/134371/

---
 arch/arm/mach-omap2/omap_hwmod.c             |   29 ++++++++++++++++++++++++++
 arch/arm/plat-omap/include/plat/omap_hwmod.h |    1 +
 2 files changed, 30 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/omap_hwmod.c +29 -0
index 955861a..631286b 100644
@@ -1250,6 +1250,35 @@ int _omap_hwmod_idle(struct omap_hwmod *oh)
 	return 0;
 }
 
+/*
+ * omap_hwmod_set_module_autoidle - set the hwmod's OCP slave autoidle
+ * @oh: struct omap_hwmod *
+ * @autoidle: desired AUTOIDLE bitfield value (0 or 1)
+ *
+ * Sets the IP block's OCP slave autoidle in hardware, and updates our
+ * local copy. Intended to be used by drivers that have some erratum
+ * that requires direct manipulation of the AUTOIDLE bits.  Returns
+ * -EINVAL if @oh is null, or passes along the return value from
+ * _set_module_autoidle().
+ */
+int omap_hwmod_set_module_autoidle(struct omap_hwmod *oh, u8 autoidle)
+{
+	u32 v;
+	int retval = 0;
+
+	if (!oh)
+		return -EINVAL;
+
+	v = oh->_sysc_cache;
+
+	retval = _set_module_autoidle(oh, autoidle, &v);
+
+	if (!retval)
+		_write_sysconfig(v, oh);
+
+	return retval;
+}
+
 /**
  * _shutdown - shutdown an omap_hwmod
  * @oh: struct omap_hwmod *
arch/arm/plat-omap/include/plat/omap_hwmod.h +1 -0
index c1835af..0d31317 100644
@@ -523,6 +523,7 @@ int omap_hwmod_enable_clocks(struct omap_hwmod *oh);
 int omap_hwmod_disable_clocks(struct omap_hwmod *oh);
 
 int omap_hwmod_set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode);
+int omap_hwmod_set_module_autoidle(struct omap_hwmod *oh, u8 autoidle);
 
 int omap_hwmod_reset(struct omap_hwmod *oh);
 void omap_hwmod_ocp_barrier(struct omap_hwmod *oh);
Signature · 1 line
1.7.0.4
#14 lore raw

RFC PATCH 6/7 OMAP: hwmod: SYSCONFIG register modification for MCBSP

In reply to Kishon Vijay Abraham I

MCBSP 2 and 3 in OMAP3 has sidetone feature which requires autoidle to be disabled before starting the sidetone. Also SYSCONFIG register has to be set with smart idle or no idle depending on the dma op mode (threshold or element sync). For doing these operations dynamically at runtime, hwmod API'S are used to modify SYSCONFIG register directly.

---
 arch/arm/plat-omap/mcbsp.c |   69 ++++++++++++++++++++++++++------------------
 1 files changed, 41 insertions(+), 28 deletions(-)
arch/arm/plat-omap/mcbsp.c +41 -28
index c7c6a83..6b705e1 100644
@@ -228,10 +228,21 @@ void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config)
 EXPORT_SYMBOL(omap_mcbsp_config);
 
 #ifdef CONFIG_ARCH_OMAP3
+static struct omap_hwmod **find_hwmods_by_dev(struct device *dev)
+{
+	struct platform_device *pdev;
+	struct omap_device *od;
+	pdev = container_of(dev, struct platform_device, dev);
+	od = container_of(pdev, struct omap_device, pdev);
+	return od->hwmods;
+}
+
 static void omap_st_on(struct omap_mcbsp *mcbsp)
 {
 	unsigned int w;
+	struct omap_hwmod **oh;
 
+	oh = find_hwmods_by_dev(mcbsp->dev);
 	/*
 	 * Sidetone uses McBSP ICLK - which must not idle when sidetones
 	 * are enabled or sidetones start sounding ugly.
@@ -244,8 +255,7 @@ static void omap_st_on(struct omap_mcbsp *mcbsp)
 	w = MCBSP_READ(mcbsp, SSELCR);
 	MCBSP_WRITE(mcbsp, SSELCR, w | SIDETONEEN);
 
-	w = MCBSP_ST_READ(mcbsp, SYSCONFIG);
-	MCBSP_ST_WRITE(mcbsp, SYSCONFIG, w & ~(ST_AUTOIDLE));
+	omap_hwmod_set_module_autoidle(oh[1], 0);
 
 	/* Enable Sidetone from Sidetone Core */
 	w = MCBSP_ST_READ(mcbsp, SSELCR);
@@ -255,12 +265,14 @@ static void omap_st_on(struct omap_mcbsp *mcbsp)
 static void omap_st_off(struct omap_mcbsp *mcbsp)
 {
 	unsigned int w;
+	struct omap_hwmod **oh;
+
+	oh = find_hwmods_by_dev(mcbsp->dev);
 
 	w = MCBSP_ST_READ(mcbsp, SSELCR);
 	MCBSP_ST_WRITE(mcbsp, SSELCR, w & ~(ST_SIDETONEEN));
 
-	w = MCBSP_ST_READ(mcbsp, SYSCONFIG);
-	MCBSP_ST_WRITE(mcbsp, SYSCONFIG, w | ST_AUTOIDLE);
+	omap_hwmod_set_module_autoidle(oh[1], 1);
 
 	w = MCBSP_READ(mcbsp, SSELCR);
 	MCBSP_WRITE(mcbsp, SSELCR, w & ~(SIDETONEEN));
@@ -273,9 +285,11 @@ static void omap_st_off(struct omap_mcbsp *mcbsp)
 static void omap_st_fir_write(struct omap_mcbsp *mcbsp, s16 *fir)
 {
 	u16 val, i;
+	struct omap_hwmod **oh;
 
-	val = MCBSP_ST_READ(mcbsp, SYSCONFIG);
-	MCBSP_ST_WRITE(mcbsp, SYSCONFIG, val & ~(ST_AUTOIDLE));
+	oh = find_hwmods_by_dev(mcbsp->dev);
+
+	omap_hwmod_set_module_autoidle(oh[1], 0);
 
 	val = MCBSP_ST_READ(mcbsp, SSELCR);
 
@@ -303,9 +317,11 @@ static void omap_st_chgain(struct omap_mcbsp *mcbsp)
 {
 	u16 w;
 	struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
+	struct omap_hwmod **oh;
+
+	oh = find_hwmods_by_dev(mcbsp->dev);
 
-	w = MCBSP_ST_READ(mcbsp, SYSCONFIG);
-	MCBSP_ST_WRITE(mcbsp, SYSCONFIG, w & ~(ST_AUTOIDLE));
+	omap_hwmod_set_module_autoidle(oh[1], 0);
 
 	w = MCBSP_ST_READ(mcbsp, SSELCR);
 
@@ -648,49 +664,46 @@ EXPORT_SYMBOL(omap_mcbsp_get_dma_op_mode);
 
 static inline void omap34xx_mcbsp_request(struct omap_mcbsp *mcbsp)
 {
+	struct omap_hwmod **oh;
+
+	oh = find_hwmods_by_dev(mcbsp->dev);
 	/*
 	 * Enable wakup behavior, smart idle and all wakeups
 	 * REVISIT: some wakeups may be unnecessary
 	 */
 	if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
-		u16 syscon;
-
-		syscon = MCBSP_READ(mcbsp, SYSCON);
-		syscon &= ~(ENAWAKEUP | SIDLEMODE(0x03) | CLOCKACTIVITY(0x03));
 
 		if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) {
-			syscon |= (ENAWAKEUP | SIDLEMODE(0x02) |
-					CLOCKACTIVITY(0x02));
-			MCBSP_WRITE(mcbsp, WAKEUPEN, XRDYEN | RRDYEN);
+			omap_hwmod_enable_wakeup(oh[0]);
+			omap_hwmod_set_slave_idlemode(oh[0],
+						HWMOD_IDLEMODE_SMART);
 		} else {
-			syscon |= SIDLEMODE(0x01);
+			omap_hwmod_disable_wakeup(oh[0]);
+			omap_hwmod_set_slave_idlemode(oh[0],
+						HWMOD_IDLEMODE_NO);
 		}
-
-		MCBSP_WRITE(mcbsp, SYSCON, syscon);
 	}
 }
 
 static inline void omap34xx_mcbsp_free(struct omap_mcbsp *mcbsp)
 {
+	struct omap_hwmod **oh;
+
+	oh = find_hwmods_by_dev(mcbsp->dev);
 	/*
 	 * Disable wakup behavior, smart idle and all wakeups
 	 */
 	if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
-		u16 syscon;
-
-		syscon = MCBSP_READ(mcbsp, SYSCON);
-		syscon &= ~(ENAWAKEUP | SIDLEMODE(0x03) | CLOCKACTIVITY(0x03));
 		/*
 		 * HW bug workaround - If no_idle mode is taken, we need to
 		 * go to smart_idle before going to always_idle, or the
 		 * device will not hit retention anymore.
 		 */
-		syscon |= SIDLEMODE(0x02);
-		MCBSP_WRITE(mcbsp, SYSCON, syscon);
-
-		syscon &= ~(SIDLEMODE(0x03));
-		MCBSP_WRITE(mcbsp, SYSCON, syscon);
-
+		omap_hwmod_disable_wakeup(oh[0]);
+		omap_hwmod_set_slave_idlemode(oh[0],
+					HWMOD_IDLEMODE_SMART);
+		omap_hwmod_set_slave_idlemode(oh[0],
+					HWMOD_IDLEMODE_FORCE);
 		MCBSP_WRITE(mcbsp, WAKEUPEN, 0);
 	}
 }
Signature · 1 line
1.7.0.4
#15 lore raw

Re: [PATCH 6/7] [RFC] OMAP: hwmod: SYSCONFIG register modification for MCBSP

Hi Kishon,

Quoted 6 lines · KISHON VIJAY

MCBSP 2 and 3 in OMAP3 has sidetone feature which requires autoidle to be disabled before starting the sidetone. Also SYSCONFIG register has to be set with smart idle or no idle depending on the dma op mode (threshold or element sync). For doing these operations dynamically at runtime, hwmod API'S are used to modify SYSCONFIG register directly.

OK, it looks like we don't have the choice... But for the implementation, please discussed with Manju on that, He is doing the similar thing for the smartstandby issue on SDMA.

Quoted 14 lines
---
  arch/arm/plat-omap/mcbsp.c |   69 ++++++++++++++++++++++++++------------------
  1 files changed, 41 insertions(+), 28 deletions(-)
arch/arm/plat-omap/mcbsp.c +0 -0
index c7c6a83..6b705e1 100644

arch/arm/plat-omap/mcbsp.c void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config) · line 237

Quoted 10 lines
arch/arm/plat-omap/mcbsp.c +7 -0
@@ -228,10 +228,21 @@ void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config)
  EXPORT_SYMBOL(omap_mcbsp_config);
 
  #ifdef CONFIG_ARCH_OMAP3
+static struct omap_hwmod **find_hwmods_by_dev(struct device *dev)
+{
+	struct platform_device *pdev;
+	struct omap_device *od;
+	pdev = container_of(dev, struct platform_device, dev);
+	od = container_of(pdev, struct omap_device, pdev);
+	return od->hwmods;

Rule #1, don't touch oh in your code. The device should be the only interface.
If such API is needed, it should be in omap_device. But in your case, I don't thing it is needed.

Quoted 12 lines
arch/arm/plat-omap/mcbsp.c +4 -0
+}
+
  static void omap_st_on(struct omap_mcbsp *mcbsp)
  {
  	unsigned int w;
+	struct omap_hwmod **oh;
 
+	oh = find_hwmods_by_dev(mcbsp->dev);
  	/*
  	 * Sidetone uses McBSP ICLK - which must not idle when sidetones
  	 * are enabled or sidetones start sounding ugly.

arch/arm/plat-omap/mcbsp.c static void omap_st_on(struct omap_mcbsp *mcbsp) · line 258

Quoted 6 lines
arch/arm/plat-omap/mcbsp.c +1 -2
@@ -244,8 +255,7 @@ static void omap_st_on(struct omap_mcbsp *mcbsp)
  	w = MCBSP_READ(mcbsp, SSELCR);
  	MCBSP_WRITE(mcbsp, SSELCR, w | SIDETONEEN);
 
-	w = MCBSP_ST_READ(mcbsp, SYSCONFIG);
-	MCBSP_ST_WRITE(mcbsp, SYSCONFIG, w&  ~(ST_AUTOIDLE));
+	omap_hwmod_set_module_autoidle(oh[1], 0);

Don't use internal hwmod API. You have to create a similar omap_device API.
You don't have to select only one hwmod in this case, just change the sysconfig setting for all hwmod that belong to the omap_device, and it will be fine. It will avoid you to access one hwmod in particular. This is the implementation that Manju is doing.

Quoted 60 lines
arch/arm/plat-omap/mcbsp.c +15 -6
  	/* Enable Sidetone from Sidetone Core */
  	w = MCBSP_ST_READ(mcbsp, SSELCR);
@@ -255,12 +265,14 @@ static void omap_st_on(struct omap_mcbsp *mcbsp)
  static void omap_st_off(struct omap_mcbsp *mcbsp)
  {
  	unsigned int w;
+	struct omap_hwmod **oh;
+
+	oh = find_hwmods_by_dev(mcbsp->dev);
 
  	w = MCBSP_ST_READ(mcbsp, SSELCR);
  	MCBSP_ST_WRITE(mcbsp, SSELCR, w&  ~(ST_SIDETONEEN));
 
-	w = MCBSP_ST_READ(mcbsp, SYSCONFIG);
-	MCBSP_ST_WRITE(mcbsp, SYSCONFIG, w | ST_AUTOIDLE);
+	omap_hwmod_set_module_autoidle(oh[1], 1);
 
  	w = MCBSP_READ(mcbsp, SSELCR);
  	MCBSP_WRITE(mcbsp, SSELCR, w&  ~(SIDETONEEN));
@@ -273,9 +285,11 @@ static void omap_st_off(struct omap_mcbsp *mcbsp)
  static void omap_st_fir_write(struct omap_mcbsp *mcbsp, s16 *fir)
  {
  	u16 val, i;
+	struct omap_hwmod **oh;
 
-	val = MCBSP_ST_READ(mcbsp, SYSCONFIG);
-	MCBSP_ST_WRITE(mcbsp, SYSCONFIG, val&  ~(ST_AUTOIDLE));
+	oh = find_hwmods_by_dev(mcbsp->dev);
+
+	omap_hwmod_set_module_autoidle(oh[1], 0);
 
  	val = MCBSP_ST_READ(mcbsp, SSELCR);
 
@@ -303,9 +317,11 @@ static void omap_st_chgain(struct omap_mcbsp *mcbsp)
  {
  	u16 w;
  	struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
+	struct omap_hwmod **oh;
+
+	oh = find_hwmods_by_dev(mcbsp->dev);
 
-	w = MCBSP_ST_READ(mcbsp, SYSCONFIG);
-	MCBSP_ST_WRITE(mcbsp, SYSCONFIG, w&  ~(ST_AUTOIDLE));
+	omap_hwmod_set_module_autoidle(oh[1], 0);
 
  	w = MCBSP_ST_READ(mcbsp, SSELCR);
 
@@ -648,49 +664,46 @@ EXPORT_SYMBOL(omap_mcbsp_get_dma_op_mode);
 
  static inline void omap34xx_mcbsp_request(struct omap_mcbsp *mcbsp)
  {
+	struct omap_hwmod **oh;
+
+	oh = find_hwmods_by_dev(mcbsp->dev);
  	/*
  	 * Enable wakup behavior, smart idle and all wakeups
  	 * REVISIT: some wakeups may be unnecessary
  	 */
  	if (cpu_is_omap34xx() || cpu_is_omap44xx()) {

arch/arm/plat-omap/mcbsp.c EXPORT_SYMBOL(omap_mcbsp_get_dma_op_mode); · line 677

Quoted 10 lines
arch/arm/plat-omap/mcbsp.c +1 -7
-		u16 syscon;
-
-		syscon = MCBSP_READ(mcbsp, SYSCON);
-		syscon&= ~(ENAWAKEUP | SIDLEMODE(0x03) | CLOCKACTIVITY(0x03));
 
  		if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) {
-			syscon |= (ENAWAKEUP | SIDLEMODE(0x02) |
-					CLOCKACTIVITY(0x02));
-			MCBSP_WRITE(mcbsp, WAKEUPEN, XRDYEN | RRDYEN);
+			omap_hwmod_enable_wakeup(oh[0]);

Thanks to the patch done by Rajendra, the wakeup should enable based on smartidle config.

Quoted 12 lines
arch/arm/plat-omap/mcbsp.c +5 -3
+			omap_hwmod_set_slave_idlemode(oh[0],
+						HWMOD_IDLEMODE_SMART);
  		} else {
-			syscon |= SIDLEMODE(0x01);
+			omap_hwmod_disable_wakeup(oh[0]);
+			omap_hwmod_set_slave_idlemode(oh[0],
+						HWMOD_IDLEMODE_NO);
  		}
-
-		MCBSP_WRITE(mcbsp, SYSCON, syscon);
  	}
  }

arch/arm/plat-omap/mcbsp.c EXPORT_SYMBOL(omap_mcbsp_get_dma_op_mode); · line 696

Quoted 10 lines
arch/arm/plat-omap/mcbsp.c +3 -0
 
  static inline void omap34xx_mcbsp_free(struct omap_mcbsp *mcbsp)
  {
+	struct omap_hwmod **oh;
+
+	oh = find_hwmods_by_dev(mcbsp->dev);
  	/*
  	 * Disable wakup behavior, smart idle and all wakeups
  	 */
  	if (cpu_is_omap34xx() || cpu_is_omap44xx()) {

Please try to avoid this cpu_is_xxx checks. You should identified the IP version if possible or add some SW rev, features or errata in hwmod and retrieve them during omap_device_build.

arch/arm/plat-omap/mcbsp.c EXPORT_SYMBOL(omap_mcbsp_get_dma_op_mode); · line 701

Quoted 9 lines
arch/arm/plat-omap/mcbsp.c +0 -4
-		u16 syscon;
-
-		syscon = MCBSP_READ(mcbsp, SYSCON);
-		syscon&= ~(ENAWAKEUP | SIDLEMODE(0x03) | CLOCKACTIVITY(0x03));
  		/*
  		 * HW bug workaround - If no_idle mode is taken, we need to
  		 * go to smart_idle before going to always_idle, or the
  		 * device will not hit retention anymore.
  		 */

What is that other bug? The changelog does not mention it?

Quoted 4 lines
arch/arm/plat-omap/mcbsp.c +0 -4
-		syscon |= SIDLEMODE(0x02);
-		MCBSP_WRITE(mcbsp, SYSCON, syscon);
-
-		syscon&= ~(SIDLEMODE(0x03));

arch/arm/plat-omap/mcbsp.c EXPORT_SYMBOL(omap_mcbsp_get_dma_op_mode); · line 709

Quoted 10 lines
arch/arm/plat-omap/mcbsp.c +5 -2
-		MCBSP_WRITE(mcbsp, SYSCON, syscon);
-
+		omap_hwmod_disable_wakeup(oh[0]);
+		omap_hwmod_set_slave_idlemode(oh[0],
+					HWMOD_IDLEMODE_SMART);
+		omap_hwmod_set_slave_idlemode(oh[0],
+					HWMOD_IDLEMODE_FORCE);
  		MCBSP_WRITE(mcbsp, WAKEUPEN, 0);
  	}
  }

Regards,
Benoit

#16 lore raw

Re: [PATCH 6/7] [RFC] OMAP: hwmod: SYSCONFIG register modification for MCBSP

Quoted 10 lines · Benoit

Hi Kishon,

Quoted 6 lines · KISHON VIJAY

MCBSP 2 and 3 in OMAP3 has sidetone feature which requires autoidle to be disabled before starting the sidetone. Also SYSCONFIG register has to be set with smart idle or no idle depending on the dma op mode (threshold or element sync). For doing these operations dynamically at runtime, hwmod API'S are used to modify SYSCONFIG register directly.

Quoted 3 lines

OK, it looks like we don't have the choice... But for the implementation, please discussed with Manju on that, He is doing the similar thing for the smartstandby issue on SDMA.

OK.

Quoted 17 lines
Quoted 17 lines
---
   arch/arm/plat-omap/mcbsp.c |   69 ++++++++++++++++++++++++++------------------
   1 files changed, 41 insertions(+), 28 deletions(-)
arch/arm/plat-omap/mcbsp.c +0 -0
index c7c6a83..6b705e1 100644
@@ -228,10 +228,21 @@ void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config)
   EXPORT_SYMBOL(omap_mcbsp_config);
 
Quoted 13 lines

arch/arm/plat-omap/mcbsp.c void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config) · line 237

Quoted 8 lines
arch/arm/plat-omap/mcbsp.c +7 -0
   #ifdef CONFIG_ARCH_OMAP3
+static struct omap_hwmod **find_hwmods_by_dev(struct device *dev)
+{
+	struct platform_device *pdev;
+	struct omap_device *od;
+	pdev = container_of(dev, struct platform_device, dev);
+	od = container_of(pdev, struct omap_device, pdev);
+	return od->hwmods;

Rule #1, don't touch oh in your code. The device should be the only interface.
If such API is needed, it should be in omap_device. But in your case, I don't thing it is needed.

OK

Quoted 16 lines
Quoted 16 lines
arch/arm/plat-omap/mcbsp.c +4 -0
+}
+
   static void omap_st_on(struct omap_mcbsp *mcbsp)
   {
   	unsigned int w;
+	struct omap_hwmod **oh;
 
+	oh = find_hwmods_by_dev(mcbsp->dev);
   	/*
   	 * Sidetone uses McBSP ICLK - which must not idle when sidetones
   	 * are enabled or sidetones start sounding ugly.
@@ -244,8 +255,7 @@ static void omap_st_on(struct omap_mcbsp *mcbsp)
   	w = MCBSP_READ(mcbsp, SSELCR);
   	MCBSP_WRITE(mcbsp, SSELCR, w | SIDETONEEN);
 
Quoted 9 lines

arch/arm/plat-omap/mcbsp.c static void omap_st_on(struct omap_mcbsp *mcbsp) · line 258

Quoted 3 lines
arch/arm/plat-omap/mcbsp.c +1 -2
-	w = MCBSP_ST_READ(mcbsp, SYSCONFIG);
-	MCBSP_ST_WRITE(mcbsp, SYSCONFIG, w&   ~(ST_AUTOIDLE));
+	omap_hwmod_set_module_autoidle(oh[1], 0);

Don't use internal hwmod API. You have to create a similar omap_device API. You don't have to select only one hwmod in this case, just change the sysconfig setting for all hwmod that belong to the omap_device, and it will be fine. It will avoid you to access one hwmod in particular. This is the implementation that Manju is doing.

OK

Quoted 66 lines
Quoted 66 lines
arch/arm/plat-omap/mcbsp.c +15 -10
   	/* Enable Sidetone from Sidetone Core */
   	w = MCBSP_ST_READ(mcbsp, SSELCR);
@@ -255,12 +265,14 @@ static void omap_st_on(struct omap_mcbsp *mcbsp)
   static void omap_st_off(struct omap_mcbsp *mcbsp)
   {
   	unsigned int w;
+	struct omap_hwmod **oh;
+
+	oh = find_hwmods_by_dev(mcbsp->dev);
 
   	w = MCBSP_ST_READ(mcbsp, SSELCR);
   	MCBSP_ST_WRITE(mcbsp, SSELCR, w&   ~(ST_SIDETONEEN));
 
-	w = MCBSP_ST_READ(mcbsp, SYSCONFIG);
-	MCBSP_ST_WRITE(mcbsp, SYSCONFIG, w | ST_AUTOIDLE);
+	omap_hwmod_set_module_autoidle(oh[1], 1);
 
   	w = MCBSP_READ(mcbsp, SSELCR);
   	MCBSP_WRITE(mcbsp, SSELCR, w&   ~(SIDETONEEN));
@@ -273,9 +285,11 @@ static void omap_st_off(struct omap_mcbsp *mcbsp)
   static void omap_st_fir_write(struct omap_mcbsp *mcbsp, s16 *fir)
   {
   	u16 val, i;
+	struct omap_hwmod **oh;
 
-	val = MCBSP_ST_READ(mcbsp, SYSCONFIG);
-	MCBSP_ST_WRITE(mcbsp, SYSCONFIG, val&   ~(ST_AUTOIDLE));
+	oh = find_hwmods_by_dev(mcbsp->dev);
+
+	omap_hwmod_set_module_autoidle(oh[1], 0);
 
   	val = MCBSP_ST_READ(mcbsp, SSELCR);
 
@@ -303,9 +317,11 @@ static void omap_st_chgain(struct omap_mcbsp *mcbsp)
   {
   	u16 w;
   	struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
+	struct omap_hwmod **oh;
+
+	oh = find_hwmods_by_dev(mcbsp->dev);
 
-	w = MCBSP_ST_READ(mcbsp, SYSCONFIG);
-	MCBSP_ST_WRITE(mcbsp, SYSCONFIG, w&   ~(ST_AUTOIDLE));
+	omap_hwmod_set_module_autoidle(oh[1], 0);
 
   	w = MCBSP_ST_READ(mcbsp, SSELCR);
 
@@ -648,49 +664,46 @@ EXPORT_SYMBOL(omap_mcbsp_get_dma_op_mode);
 
   static inline void omap34xx_mcbsp_request(struct omap_mcbsp *mcbsp)
   {
+	struct omap_hwmod **oh;
+
+	oh = find_hwmods_by_dev(mcbsp->dev);
   	/*
   	 * Enable wakup behavior, smart idle and all wakeups
   	 * REVISIT: some wakeups may be unnecessary
   	 */
   	if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
-		u16 syscon;
-
-		syscon = MCBSP_READ(mcbsp, SYSCON);
-		syscon&= ~(ENAWAKEUP | SIDLEMODE(0x03) | CLOCKACTIVITY(0x03));
 
Quoted 8 lines

arch/arm/plat-omap/mcbsp.c EXPORT_SYMBOL(omap_mcbsp_get_dma_op_mode); · line 677

Quoted 5 lines
arch/arm/plat-omap/mcbsp.c +1 -3
   		if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) {
-			syscon |= (ENAWAKEUP | SIDLEMODE(0x02) |
-					CLOCKACTIVITY(0x02));
-			MCBSP_WRITE(mcbsp, WAKEUPEN, XRDYEN | RRDYEN);
+			omap_hwmod_enable_wakeup(oh[0]);

Thanks to the patch done by Rajendra, the wakeup should enable based on smartidle config.

OK.

Quoted 14 lines
Quoted 14 lines
arch/arm/plat-omap/mcbsp.c +5 -3
+			omap_hwmod_set_slave_idlemode(oh[0],
+						HWMOD_IDLEMODE_SMART);
   		} else {
-			syscon |= SIDLEMODE(0x01);
+			omap_hwmod_disable_wakeup(oh[0]);
+			omap_hwmod_set_slave_idlemode(oh[0],
+						HWMOD_IDLEMODE_NO);
   		}
-
-		MCBSP_WRITE(mcbsp, SYSCON, syscon);
   	}
   }
 
Quoted 13 lines

arch/arm/plat-omap/mcbsp.c EXPORT_SYMBOL(omap_mcbsp_get_dma_op_mode); · line 696

Quoted 9 lines
arch/arm/plat-omap/mcbsp.c +3 -0
   static inline void omap34xx_mcbsp_free(struct omap_mcbsp *mcbsp)
   {
+	struct omap_hwmod **oh;
+
+	oh = find_hwmods_by_dev(mcbsp->dev);
   	/*
   	 * Disable wakup behavior, smart idle and all wakeups
   	 */
   	if (cpu_is_omap34xx() || cpu_is_omap44xx()) {

Please try to avoid this cpu_is_xxx checks. You should identified the IP version if possible or add some SW rev, features or errata in hwmod and retrieve them during omap_device_build.

OK.

Quoted 12 lines

arch/arm/plat-omap/mcbsp.c EXPORT_SYMBOL(omap_mcbsp_get_dma_op_mode); · line 701

Quoted 10 lines
arch/arm/plat-omap/mcbsp.c +0 -4
-		u16 syscon;
-
-		syscon = MCBSP_READ(mcbsp, SYSCON);
-		syscon&= ~(ENAWAKEUP | SIDLEMODE(0x03) | CLOCKACTIVITY(0x03));
   		/*
   		 * HW bug workaround - If no_idle mode is taken, we need to
   		 * go to smart_idle before going to always_idle, or the
   		 * device will not hit retention anymore.
   		 */

What is that other bug? The changelog does not mention it?

This is based on the patch sent by Eero Nurkkala [1]. They've observed
when DMA mode is selected to element sync(NO IDLE is set in sysconfig), the device does not hit retention if force idle mode is selected without switching to smart idle..

[1] http://kerneltrap.org/mailarchive/alsa-devel/2009/8/20/6333573

Quoted 18 lines
Quoted 5 lines
arch/arm/plat-omap/mcbsp.c +0 -4
-		syscon |= SIDLEMODE(0x02);
-		MCBSP_WRITE(mcbsp, SYSCON, syscon);
-
-		syscon&= ~(SIDLEMODE(0x03));

arch/arm/plat-omap/mcbsp.c EXPORT_SYMBOL(omap_mcbsp_get_dma_op_mode); · line 709

Quoted 10 lines
arch/arm/plat-omap/mcbsp.c +5 -2
-		MCBSP_WRITE(mcbsp, SYSCON, syscon);
-
+		omap_hwmod_disable_wakeup(oh[0]);
+		omap_hwmod_set_slave_idlemode(oh[0],
+					HWMOD_IDLEMODE_SMART);
+		omap_hwmod_set_slave_idlemode(oh[0],
+					HWMOD_IDLEMODE_FORCE);
   		MCBSP_WRITE(mcbsp, WAKEUPEN, 0);
   	}
   }

Regards,
Benoit

A message that is not in the archive (sent off-list or not yet received): [email protected]

#18 lore raw

Re: [PATCH 6/7] [RFC] OMAP: hwmod: SYSCONFIG register modification for MCBSP

Resending the mail in plain text format..

Quoted 70 lines · KISHON VIJAY
Quoted 10 lines · KISHON VIJAY
Quoted 8 lines · Benoit

Hi Kishon,

Quoted 5 lines · KISHON VIJAY

MCBSP 2 and 3 in OMAP3 has sidetone feature which requires autoidle to be disabled before starting the sidetone. Also SYSCONFIG register has to be set with smart idle or no idle depending on the dma op mode (threshold or element sync). For doing these operations dynamically at runtime, hwmod API'S are used to modify SYSCONFIG

Quoted 8 lines

register

Quoted 5 lines
Quoted 1 line

directly.

OK, it looks like we don't have the choice... But for the implementation, please discussed with Manju on that, He is doing the similar thing for the smartstandby issue on SDMA.

  OK.

      Looks like we have a problem when we write an API similar to the one written by Manju (omap_hwmod_set_master_standbymode()) [1]. In the case of McBSP, I have to modify omap_hwmod_set_slave_idlemode() (which is already existing), to include something like

                        +    if (sf & SYSC_HAS_SIDLEMODE) {
                        +        if (idlemode)
                        +            idlemode = HWMOD_IDLEMODE_NO;
                        +        else
                        +            idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ? +                HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART; +    }

      Then an API like omap_device_require_no_idle() and omap_device_release_no_idle() would be written similar to omap_device_require_no_mstandby and omap_device_release_no_mstandby() (see [1]) that calls omap_hwmod_set_slave_idlemode() with true/false. Passing true to omap_hwmod_set_slave_idlemode() will write SIDLE bits with HWMOD_IDLEMODE_NO and false to it will write HWMOD_IDLEMODE_NO/HWMOD_IDLEMODE_SMART depending on HWMOD_SWSUP_SIDLE to SIDLE bits.

      This works fine for McBSP since only two modes come to play here (HWMOD_IDLEMODE_NO/HWMOD_IDLEMODE_SMART).

      But omap_hwmod_set_slave_idlemode() API is used by UART (serial.c Please refer [2]) which writes SIDLE bits to HWMOD_IDLEMODE_NO/HWMOD_IDLEMODE_SMART/ and HWMOD_IDLEMODE_FORCE.

      Modifying omap_hwmod_set_slave_idlemode() will require
          1) serial.c to be modified to call functions like 'omap_device_require_no_idle(), omap_device_release_no_idle()' and 'omap_device_require_force_idle() and omap_device_release_force_idle()' instead of omap_hwmod_set_slave_idlemode() which is currently present.

      There are 2 problems associated with it
      1) The first problem is having a single API like omap_hwmod_set_slave_idlemode() to set two different values like HWMOD_IDLEMODE_NO or HWMOD_IDLEMODE_FORCE (intended to be called by omap_device_require_no_idle() and omap_device_require_force_idle() respectively). According to the new design omap_hwmod_set_slave_idlemode() is intended to take only true/false as arguments.

      2) The second problem is having the release API's (omap_device_release_no_idle() and omap_device_release_force_idle()) to restore the SYSCONFIG to the previous state. Remember, this was not problem for McBSP since only two modes were needed.

Quoted 220 lines

      Please provide your comment on this.

-Kishon

      [1] https://patchwork.kernel.org/patch/335591/
      [2] http://git.kernel.org/?p=linux/kernel/git/tmlind/linux-omap-2.6.git;a=blob;f=arch/arm/mach-omap2/serial.c;h=edd7c99de38dde5bf877788fb4e48055c0d9fbfa;hb=HEAD

Quoted 213 lines
Quoted 9 lines
Quoted 9 lines

---
   arch/arm/plat-omap/mcbsp.c |   69

++++++++++++++++++++++++++------------------

Quoted 7 lines

arch/arm/plat-omap/mcbsp.c void omap_mcbsp_config(unsigned int id, const

Quoted 7 lines
   1 files changed, 41 insertions(+), 28 deletions(-)
arch/arm/plat-omap/mcbsp.c +0 -0
index c7c6a83..6b705e1 100644
@@ -228,10 +228,21 @@ void omap_mcbsp_config(unsigned int id, const

struct omap_mcbsp_reg_cfg *config)

Quoted 15 lines

arch/arm/plat-omap/mcbsp.c void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config) · line 237

Quoted 10 lines
arch/arm/plat-omap/mcbsp.c +7 -0
    EXPORT_SYMBOL(omap_mcbsp_config);
 
    #ifdef CONFIG_ARCH_OMAP3
+static struct omap_hwmod **find_hwmods_by_dev(struct device *dev)
+{
+    struct platform_device *pdev;
+    struct omap_device *od;
+    pdev = container_of(dev, struct platform_device, dev);
+    od = container_of(pdev, struct omap_device, pdev);
+    return od->hwmods;

Rule #1, don't touch oh in your code. The device should be the only interface.
If such API is needed, it should be in omap_device. But in your case, I don't thing it is needed.

  OK

Quoted 16 lines
Quoted 16 lines
arch/arm/plat-omap/mcbsp.c +4 -0
+}
+
    static void omap_st_on(struct omap_mcbsp *mcbsp)
    {
      unsigned int w;
+    struct omap_hwmod **oh;
 
+    oh = find_hwmods_by_dev(mcbsp->dev);
      /*
       * Sidetone uses McBSP ICLK - which must not idle when sidetones
       * are enabled or sidetones start sounding ugly.
@@ -244,8 +255,7 @@ static void omap_st_on(struct omap_mcbsp *mcbsp)
      w = MCBSP_READ(mcbsp, SSELCR);
      MCBSP_WRITE(mcbsp, SSELCR, w | SIDETONEEN);
 
Quoted 5 lines

arch/arm/plat-omap/mcbsp.c static void omap_st_on(struct omap_mcbsp *mcbsp) · line 258

Quoted 3 lines
arch/arm/plat-omap/mcbsp.c +1 -2
-    w = MCBSP_ST_READ(mcbsp, SYSCONFIG);
-    MCBSP_ST_WRITE(mcbsp, SYSCONFIG, w&   ~(ST_AUTOIDLE));
+    omap_hwmod_set_module_autoidle(oh[1], 0);

Don't use internal hwmod API. You have to create a similar omap_device

API.

Quoted 4 lines

You don't have to select only one hwmod in this case, just change the sysconfig setting for all hwmod that belong to the omap_device, and it will be fine. It will avoid you to access one hwmod in particular. This is the implementation that Manju is doing.

  OK

Quoted 33 lines
Quoted 33 lines
arch/arm/plat-omap/mcbsp.c +8 -4
      /* Enable Sidetone from Sidetone Core */
      w = MCBSP_ST_READ(mcbsp, SSELCR);
@@ -255,12 +265,14 @@ static void omap_st_on(struct omap_mcbsp *mcbsp)
    static void omap_st_off(struct omap_mcbsp *mcbsp)
    {
      unsigned int w;
+    struct omap_hwmod **oh;
+
+    oh = find_hwmods_by_dev(mcbsp->dev);
 
      w = MCBSP_ST_READ(mcbsp, SSELCR);
      MCBSP_ST_WRITE(mcbsp, SSELCR, w&   ~(ST_SIDETONEEN));
 
-    w = MCBSP_ST_READ(mcbsp, SYSCONFIG);
-    MCBSP_ST_WRITE(mcbsp, SYSCONFIG, w | ST_AUTOIDLE);
+    omap_hwmod_set_module_autoidle(oh[1], 1);
 
      w = MCBSP_READ(mcbsp, SSELCR);
      MCBSP_WRITE(mcbsp, SSELCR, w&   ~(SIDETONEEN));
@@ -273,9 +285,11 @@ static void omap_st_off(struct omap_mcbsp *mcbsp)
    static void omap_st_fir_write(struct omap_mcbsp *mcbsp, s16 *fir)
    {
      u16 val, i;
+    struct omap_hwmod **oh;
 
-    val = MCBSP_ST_READ(mcbsp, SYSCONFIG);
-    MCBSP_ST_WRITE(mcbsp, SYSCONFIG, val&   ~(ST_AUTOIDLE));
+    oh = find_hwmods_by_dev(mcbsp->dev);
+
+    omap_hwmod_set_module_autoidle(oh[1], 0);
 
Quoted 3 lines

arch/arm/plat-omap/mcbsp.c static void omap_st_chgain(struct omap_mcbsp

Quoted 3 lines
arch/arm/plat-omap/mcbsp.c +0 -0
      val = MCBSP_ST_READ(mcbsp, SSELCR);
 
@@ -303,9 +317,11 @@ static void omap_st_chgain(struct omap_mcbsp

*mcbsp)

Quoted 15 lines
Quoted 15 lines
arch/arm/plat-omap/mcbsp.c +4 -2
    {
      u16 w;
      struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
+    struct omap_hwmod **oh;
+
+    oh = find_hwmods_by_dev(mcbsp->dev);
 
-    w = MCBSP_ST_READ(mcbsp, SYSCONFIG);
-    MCBSP_ST_WRITE(mcbsp, SYSCONFIG, w&   ~(ST_AUTOIDLE));
+    omap_hwmod_set_module_autoidle(oh[1], 0);
 
      w = MCBSP_ST_READ(mcbsp, SSELCR);
 
@@ -648,49 +664,46 @@ EXPORT_SYMBOL(omap_mcbsp_get_dma_op_mode);
 
Quoted 14 lines
Quoted 4 lines
arch/arm/plat-omap/mcbsp.c +2 -0
    static inline void omap34xx_mcbsp_request(struct omap_mcbsp *mcbsp)
    {
+    struct omap_hwmod **oh;
+

arch/arm/plat-omap/mcbsp.c EXPORT_SYMBOL(omap_mcbsp_get_dma_op_mode);

Quoted 10 lines
arch/arm/plat-omap/mcbsp.c +1 -4
+    oh = find_hwmods_by_dev(mcbsp->dev);
      /*
       * Enable wakup behavior, smart idle and all wakeups
       * REVISIT: some wakeups may be unnecessary
       */
      if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
-            u16 syscon;
-
-            syscon = MCBSP_READ(mcbsp, SYSCON);
-            syscon&= ~(ENAWAKEUP | SIDLEMODE(0x03) |

CLOCKACTIVITY(0x03));

Quoted 9 lines

arch/arm/plat-omap/mcbsp.c EXPORT_SYMBOL(omap_mcbsp_get_dma_op_mode); · line 677

Quoted 6 lines
arch/arm/plat-omap/mcbsp.c +1 -3
              if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) {
-                    syscon |= (ENAWAKEUP | SIDLEMODE(0x02) |
-                                    CLOCKACTIVITY(0x02));
-                    MCBSP_WRITE(mcbsp, WAKEUPEN, XRDYEN | RRDYEN);
+                    omap_hwmod_enable_wakeup(oh[0]);

Thanks to the patch done by Rajendra, the wakeup should enable based on smartidle config.

  OK.

Quoted 14 lines
Quoted 14 lines
arch/arm/plat-omap/mcbsp.c +5 -3
+                    omap_hwmod_set_slave_idlemode(oh[0],
+                                            HWMOD_IDLEMODE_SMART);
              } else {
-                    syscon |= SIDLEMODE(0x01);
+                    omap_hwmod_disable_wakeup(oh[0]);
+                    omap_hwmod_set_slave_idlemode(oh[0],
+                                            HWMOD_IDLEMODE_NO);
              }
-
-            MCBSP_WRITE(mcbsp, SYSCON, syscon);
      }
    }
 
Quoted 13 lines

arch/arm/plat-omap/mcbsp.c EXPORT_SYMBOL(omap_mcbsp_get_dma_op_mode); · line 696

Quoted 9 lines
arch/arm/plat-omap/mcbsp.c +3 -0
    static inline void omap34xx_mcbsp_free(struct omap_mcbsp *mcbsp)
    {
+    struct omap_hwmod **oh;
+
+    oh = find_hwmods_by_dev(mcbsp->dev);
      /*
       * Disable wakup behavior, smart idle and all wakeups
       */
      if (cpu_is_omap34xx() || cpu_is_omap44xx()) {

Please try to avoid this cpu_is_xxx checks. You should identified the IP version if possible or add some SW rev, features or errata in hwmod and retrieve them during omap_device_build.

  OK.

Quoted 5 lines

arch/arm/plat-omap/mcbsp.c EXPORT_SYMBOL(omap_mcbsp_get_dma_op_mode);

Quoted 5 lines
arch/arm/plat-omap/mcbsp.c +0 -4
-            u16 syscon;
-
-            syscon = MCBSP_READ(mcbsp, SYSCON);
-            syscon&= ~(ENAWAKEUP | SIDLEMODE(0x03) |

CLOCKACTIVITY(0x03));

Quoted 2 lines

arch/arm/plat-omap/mcbsp.c EXPORT_SYMBOL(omap_mcbsp_get_dma_op_mode); · line 697

Quoted 2 lines
arch/arm/plat-omap/mcbsp.c +0 -0
              /*
               * HW bug workaround - If no_idle mode is taken, we need

to

Quoted 5 lines

arch/arm/plat-omap/mcbsp.c EXPORT_SYMBOL(omap_mcbsp_get_dma_op_mode); · line 701

Quoted 3 lines
arch/arm/plat-omap/mcbsp.c +0 -0
               * go to smart_idle before going to always_idle, or the
               * device will not hit retention anymore.
               */

What is that other bug? The changelog does not mention it?

  This is based on the patch sent by Eero Nurkkala [1]. They've observed when DMA mode is selected to element sync(NO IDLE is set in sysconfig), the device does not hit retention if force idle mode is selected without switching to smart idle..

[1] http://kerneltrap.org/mailarchive/alsa-devel/2009/8/20/6333573

Quoted 18 lines
Quoted 5 lines
arch/arm/plat-omap/mcbsp.c +0 -4
-            syscon |= SIDLEMODE(0x02);
-            MCBSP_WRITE(mcbsp, SYSCON, syscon);
-
-            syscon&= ~(SIDLEMODE(0x03));

arch/arm/plat-omap/mcbsp.c EXPORT_SYMBOL(omap_mcbsp_get_dma_op_mode); · line 709

Quoted 10 lines
arch/arm/plat-omap/mcbsp.c +5 -2
-            MCBSP_WRITE(mcbsp, SYSCON, syscon);
-
+            omap_hwmod_disable_wakeup(oh[0]);
+            omap_hwmod_set_slave_idlemode(oh[0],
+                                    HWMOD_IDLEMODE_SMART);
+            omap_hwmod_set_slave_idlemode(oh[0],
+                                    HWMOD_IDLEMODE_FORCE);
              MCBSP_WRITE(mcbsp, WAKEUPEN, 0);
      }
    }

Regards,
Benoit

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#19 lore raw

Re: [PATCH 6/7] [RFC] OMAP: hwmod: SYSCONFIG register modification for MCBSP

Hi Kishon,

Sorry, for the delay.

Quoted 37 lines · KISHON VIJAY

Resending the mail in plain text format..

Quoted 34 lines · KISHON VIJAY
Quoted 10 lines · KISHON VIJAY
Quoted 8 lines · Benoit

Hi Kishon,

Quoted 5 lines · KISHON VIJAY

MCBSP 2 and 3 in OMAP3 has sidetone feature which requires autoidle to be disabled before starting the sidetone. Also SYSCONFIG register has to be set with smart idle or no idle depending on the dma op mode (threshold or element sync). For doing these operations dynamically at runtime, hwmod API'S are used to modify SYSCONFIG

Quoted 8 lines

register

Quoted 5 lines
Quoted 1 line

directly.

OK, it looks like we don't have the choice... But for the implementation, please discussed with Manju on that, He is doing the similar thing for the smartstandby issue on SDMA.

   OK.

Looks like we have a problem when we write an API similar to the one written by Manju (omap_hwmod_set_master_standbymode()) [1]. In the case of McBSP, I have to modify omap_hwmod_set_slave_idlemode() (which is already existing), to include something like

+ if (sf& SYSC_HAS_SIDLEMODE) {
+ if (idlemode)
+ idlemode = HWMOD_IDLEMODE_NO;
+ else
+ idlemode = (oh->flags& HWMOD_SWSUP_SIDLE) ?
+ HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART;
+ }

How to you enable HWMOD_IDLEMODE_FORCE mode in that case?

Quoted 9 lines
Quoted 9 lines

Then an API like omap_device_require_no_idle() and omap_device_release_no_idle() would be written similar to omap_device_require_no_mstandby and omap_device_release_no_mstandby() (see [1]) that calls omap_hwmod_set_slave_idlemode() with true/false. Passing true to omap_hwmod_set_slave_idlemode() will write SIDLE bits with HWMOD_IDLEMODE_NO and false to it will write HWMOD_IDLEMODE_NO/HWMOD_IDLEMODE_SMART depending on HWMOD_SWSUP_SIDLE to SIDLE bits.

Quoted 7 lines
Quoted 7 lines

This works fine for McBSP since only two modes come to play here (HWMOD_IDLEMODE_NO/HWMOD_IDLEMODE_SMART).

But omap_hwmod_set_slave_idlemode() API is used by UART (serial.c Please refer [2]) which writes SIDLE bits to HWMOD_IDLEMODE_NO/HWMOD_IDLEMODE_SMART/ and HWMOD_IDLEMODE_FORCE.

That code should not be there. It was a temporary hacks that should be replaced eventually with a clean omap_device API like the one you are currently implementing. There are a bunch of direct access to omap_hwmod struct that need to be removed as well.

Quoted 5 lines
Quoted 5 lines

Modifying omap_hwmod_set_slave_idlemode() will require
1) serial.c to be modified to call functions like 'omap_device_require_no_idle(), omap_device_release_no_idle()' and 'omap_device_require_force_idle() and omap_device_release_force_idle()' instead of omap_hwmod_set_slave_idlemode() which is currently present.

Yep, you're right.

Quoted 9 lines
Quoted 9 lines

There are 2 problems associated with it
1) The first problem is having a single API like omap_hwmod_set_slave_idlemode() to set two different values like HWMOD_IDLEMODE_NO or HWMOD_IDLEMODE_FORCE (intended to be called by omap_device_require_no_idle() and omap_device_require_force_idle() respectively). According to the new design omap_hwmod_set_slave_idlemode() is intended to take only true/false as arguments.

Quoted 3 lines
Quoted 3 lines

2) The second problem is having the release API's (omap_device_release_no_idle() and omap_device_release_force_idle()) to restore the SYSCONFIG to the previous state. Remember, this was not problem for McBSP since only two modes were needed.

And what about 3 APIs?

omap_device_force_idle
omap_device_no_idle
omap_device_smart_idle

It is probably much more appropriate than a require / release in that case?

Regards,
Benoit

#20 lore raw

RE: [PATCH 6/7] [RFC] OMAP: hwmod: SYSCONFIG register modification for MCBSP

Quoted 123 lines

-----Original Message-----
From: Cousson, Benoit
Sent: Tuesday, November 30, 2010 9:33 PM
To: ABRAHAM, KISHON VIJAY; Paul Walmsley
Cc: Kevin Hilman; Basak, Partha; [email protected]; Kamat, Nishant; Varadarajan, Charulatha; Datta, Shubhrajyoti; ext- [email protected]; [email protected]
Subject: Re: [PATCH 6/7] [RFC] OMAP: hwmod: SYSCONFIG register modification for MCBSP

Hi Kishon,

Sorry, for the delay.

Quoted 3 lines · KISHON VIJAY

Resending the mail in plain text format..

On Mon, Nov 22, 2010 at 9:20 PM, ABRAHAM, KISHON VIJAY<[email protected]>

Quoted 2 lines · wrote:
Quoted 2 lines

On Mon, Oct 11, 2010 at 11:48 AM, ABRAHAM, KISHON

Quoted 7 lines · VIJAY
Quoted 7 lines
Quoted 7 lines · Benoit
Quoted 5 lines

Hi Kishon,

Quoted 2 lines · KISHON VIJAY

MCBSP 2 and 3 in OMAP3 has sidetone feature which requires autoidle to be disabled before starting the sidetone. Also

SYSCONFIG

Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

register has to be set with smart idle or no idle depending on

the

Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

dma op mode (threshold or element sync). For doing these

operations

Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 1 line
Quoted 1 line

dynamically at runtime, hwmod API'S are used to modify SYSCONFIG

register

Quoted 4 lines
Quoted 1 line

directly.

OK, it looks like we don't have the choice... But for the implementation, please discussed with Manju on that, He is doing

the

Quoted 6 lines
Quoted 6 lines
Quoted 3 lines
Quoted 1 line

similar thing for the smartstandby issue on SDMA.

   OK.

Looks like we have a problem when we write an API similar to

the one written

Quoted 1 line
Quoted 1 line

by Manju (omap_hwmod_set_master_standbymode()) [1]. In the

case of McBSP,

Quoted 1 line
Quoted 1 line

I have to modify omap_hwmod_set_slave_idlemode() (which is

already existing),

Quoted 7 lines
Quoted 7 lines

to include something like

+ if (sf& SYSC_HAS_SIDLEMODE) {
+ if (idlemode)
+ idlemode = HWMOD_IDLEMODE_NO;
+ else
+ idlemode = (oh->flags&

HWMOD_SWSUP_SIDLE) ?

Quoted 1 line
Quoted 1 line

+ HWMOD_IDLEMODE_NO :

HWMOD_IDLEMODE_SMART;

Quoted 1 line
Quoted 1 line

+ }

How to you enable HWMOD_IDLEMODE_FORCE mode in that case?

Quoted 1 line
Quoted 1 line

Then an API like omap_device_require_no_idle() and

omap_device_release_no_idle()

Quoted 1 line
Quoted 1 line

would be written similar to omap_device_require_no_mstandby

and

Quoted 2 lines
Quoted 2 lines

omap_device_release_no_mstandby() (see [1]) that calls omap_hwmod_set_slave_idlemode() with true/false. Passing true

to

Quoted 6 lines
Quoted 6 lines

omap_hwmod_set_slave_idlemode() will write SIDLE bits with HWMOD_IDLEMODE_NO and false to it will write HWMOD_IDLEMODE_NO/HWMOD_IDLEMODE_SMART depending on HWMOD_SWSUP_SIDLE to SIDLE bits.

This works fine for McBSP since only two modes come to play

here

Quoted 6 lines
Quoted 6 lines

(HWMOD_IDLEMODE_NO/HWMOD_IDLEMODE_SMART).

But omap_hwmod_set_slave_idlemode() API is used by UART (serial.c Please refer [2]) which writes SIDLE bits to HWMOD_IDLEMODE_NO/HWMOD_IDLEMODE_SMART/ and HWMOD_IDLEMODE_FORCE.

That code should not be there. It was a temporary hacks that should be replaced eventually with a clean omap_device API like the one you are currently implementing.
There are a bunch of direct access to omap_hwmod struct that need to be removed as well.

Quoted 2 lines
Quoted 2 lines

Modifying omap_hwmod_set_slave_idlemode() will require
1) serial.c to be modified to call functions like

'omap_device_require_no_idle(),

Quoted 1 line
Quoted 1 line

omap_device_release_no_idle()' and

'omap_device_require_force_idle() and

Quoted 2 lines
Quoted 2 lines

omap_device_release_force_idle()' instead of omap_hwmod_set_slave_idlemode() which is currently

present.

Yep, you're right.

Quoted 3 lines
Quoted 3 lines

There are 2 problems associated with it
1) The first problem is having a single API like

omap_hwmod_set_slave_idlemode() to

Quoted 2 lines
Quoted 2 lines

set two different values like HWMOD_IDLEMODE_NO or HWMOD_IDLEMODE_FORCE (intended to be called by

omap_device_require_no_idle()

Quoted 1 line
Quoted 1 line

and omap_device_require_force_idle() respectively).

According to the new design

Quoted 1 line
Quoted 1 line

omap_hwmod_set_slave_idlemode() is intended to take only

true/false as

Quoted 3 lines
Quoted 3 lines

arguments.

2) The second problem is having the release API's

(omap_device_release_no_idle() and

Quoted 1 line
Quoted 1 line

omap_device_release_force_idle()) to restore the

SYSCONFIG to the previous state.

Quoted 8 lines
Quoted 1 line
Quoted 1 line

Remember, this was not problem for McBSP since only two

modes were needed.

And what about 3 APIs?

omap_device_force_idle
omap_device_no_idle
omap_device_smart_idle

Want to reiterate Paul Walmsley's comments on Manju's DMA email dated 11/11/2010 <snip>
2. Rather than just using a single omap_device_mstandby() function call, I'd rather see something like omap_device_require_no_standby() and omap_device_release_no_standby(). omap_device_require_no_standby() would force the initiator port into no-standby. omap_device_release_no_standby() would return the initiator port MSTANDBYMODE to whatever the state should be (this depends on whether HWMOD_SWSUP_MSTDBY is set). I'd rather not have the drivers manage the contents of the MSTANDBYMODE bits directly. Then you should be able to drop _get_master_standbymode() and omap_hwmod_get_master_idlemode() also. Can you please make these changes?
<snip>

The key point is, in the absence of any special situation like errata etc, the IdleMode settings should be dicated solely by the hwmod flags. We should have a mechanism though to supersede this setting & request /release customized settings to handle errata etc.

So, it makes sense to have request/release API pairs. In this case, omap_device_request_no_idle() & omap_device_release_no_idle().

omap_hwmod_set_slave_idlemode should continue to take absolute values instead of true/false to support all possible settings of IdleMode.

Quoted 6 lines

It is probably much more appropriate than a require / release in that case?

Regards,
Benoit

#21 lore raw

Re: [PATCH 6/7] [RFC] OMAP: hwmod: SYSCONFIG register modification for MCBSP

+ Govindraj

Hi Partha,

Quoted 142 lines · Partha
Quoted 115 lines

From: Cousson, Benoit
Sent: Tuesday, November 30, 2010 9:33 PM

Hi Kishon,

Sorry, for the delay.

Quoted 3 lines · KISHON VIJAY

Resending the mail in plain text format..

On Mon, Nov 22, 2010 at 9:20 PM, ABRAHAM, KISHON VIJAY<[email protected]>

Quoted 2 lines · wrote:
Quoted 2 lines

On Mon, Oct 11, 2010 at 11:48 AM, ABRAHAM, KISHON

Quoted 7 lines · VIJAY
Quoted 7 lines
Quoted 7 lines · Benoit
Quoted 5 lines

Hi Kishon,

Quoted 2 lines · KISHON VIJAY

MCBSP 2 and 3 in OMAP3 has sidetone feature which requires autoidle to be disabled before starting the sidetone. Also

SYSCONFIG

Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

register has to be set with smart idle or no idle depending on

the

Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

dma op mode (threshold or element sync). For doing these

operations

Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 1 line
Quoted 1 line

dynamically at runtime, hwmod API'S are used to modify SYSCONFIG

register

Quoted 4 lines
Quoted 1 line

directly.

OK, it looks like we don't have the choice... But for the implementation, please discussed with Manju on that, He is doing

the

Quoted 6 lines
Quoted 6 lines
Quoted 3 lines
Quoted 1 line

similar thing for the smartstandby issue on SDMA.

    OK.

Looks like we have a problem when we write an API similar to

the one written

Quoted 1 line
Quoted 1 line

by Manju (omap_hwmod_set_master_standbymode()) [1]. In the

case of McBSP,

Quoted 1 line
Quoted 1 line

I have to modify omap_hwmod_set_slave_idlemode() (which is

already existing),

Quoted 7 lines
Quoted 7 lines

to include something like

+ if (sf& SYSC_HAS_SIDLEMODE) {
+ if (idlemode)
+ idlemode = HWMOD_IDLEMODE_NO;
+ else
+ idlemode = (oh->flags&

HWMOD_SWSUP_SIDLE) ?

Quoted 1 line
Quoted 1 line

+ HWMOD_IDLEMODE_NO :

HWMOD_IDLEMODE_SMART;

Quoted 1 line
Quoted 1 line

+ }

How to you enable HWMOD_IDLEMODE_FORCE mode in that case?

Quoted 1 line
Quoted 1 line

Then an API like omap_device_require_no_idle() and

omap_device_release_no_idle()

Quoted 1 line
Quoted 1 line

would be written similar to omap_device_require_no_mstandby

and

Quoted 2 lines
Quoted 2 lines

omap_device_release_no_mstandby() (see [1]) that calls omap_hwmod_set_slave_idlemode() with true/false. Passing true

to

Quoted 6 lines
Quoted 6 lines

omap_hwmod_set_slave_idlemode() will write SIDLE bits with HWMOD_IDLEMODE_NO and false to it will write HWMOD_IDLEMODE_NO/HWMOD_IDLEMODE_SMART depending on HWMOD_SWSUP_SIDLE to SIDLE bits.

This works fine for McBSP since only two modes come to play

here

Quoted 6 lines
Quoted 6 lines

(HWMOD_IDLEMODE_NO/HWMOD_IDLEMODE_SMART).

But omap_hwmod_set_slave_idlemode() API is used by UART (serial.c Please refer [2]) which writes SIDLE bits to HWMOD_IDLEMODE_NO/HWMOD_IDLEMODE_SMART/ and HWMOD_IDLEMODE_FORCE.

That code should not be there. It was a temporary hacks that should be replaced eventually with a clean omap_device API like the one you are currently implementing.
There are a bunch of direct access to omap_hwmod struct that need to be removed as well.

Quoted 2 lines
Quoted 2 lines

Modifying omap_hwmod_set_slave_idlemode() will require
1) serial.c to be modified to call functions like

'omap_device_require_no_idle(),

Quoted 1 line
Quoted 1 line

omap_device_release_no_idle()' and

'omap_device_require_force_idle() and

Quoted 2 lines
Quoted 2 lines

omap_device_release_force_idle()' instead of omap_hwmod_set_slave_idlemode() which is currently

present.

Yep, you're right.

Quoted 3 lines
Quoted 3 lines

There are 2 problems associated with it
1) The first problem is having a single API like

omap_hwmod_set_slave_idlemode() to

Quoted 2 lines
Quoted 2 lines

set two different values like HWMOD_IDLEMODE_NO or HWMOD_IDLEMODE_FORCE (intended to be called by

omap_device_require_no_idle()

Quoted 1 line
Quoted 1 line

and omap_device_require_force_idle() respectively).

According to the new design

Quoted 1 line
Quoted 1 line

omap_hwmod_set_slave_idlemode() is intended to take only

true/false as

Quoted 3 lines
Quoted 3 lines

arguments.

2) The second problem is having the release API's

(omap_device_release_no_idle() and

Quoted 1 line
Quoted 1 line

omap_device_release_force_idle()) to restore the

SYSCONFIG to the previous state.

Quoted 8 lines
Quoted 1 line
Quoted 1 line

Remember, this was not problem for McBSP since only two

modes were needed.

And what about 3 APIs?

omap_device_force_idle
omap_device_no_idle
omap_device_smart_idle

Want to reiterate Paul Walmsley's comments on Manju's DMA email dated 11/11/2010 <snip>
2. Rather than just using a single omap_device_mstandby() function call, I'd rather see something like omap_device_require_no_standby() and omap_device_release_no_standby(). omap_device_require_no_standby() would force the initiator port into no-standby. omap_device_release_no_standby() would return the initiator port MSTANDBYMODE to whatever the state should be (this depends on whether HWMOD_SWSUP_MSTDBY is set). I'd rather not have the drivers manage the contents of the MSTANDBYMODE bits directly. Then you should be able to drop _get_master_standbymode() and omap_hwmod_get_master_idlemode() also. Can you please make these changes?
<snip>

The key point is, in the absence of any special situation like errata etc, the IdleMode settings should be dicated solely by the hwmod flags. We should have a mechanism though to supersede this setting& request /release customized settings to handle errata etc.

Quoted 5 lines

So, it makes sense to have request/release API pairs. In this case, omap_device_request_no_idle()& omap_device_release_no_idle().

omap_hwmod_set_slave_idlemode should continue to take absolute values instead of true/false to support all possible settings of IdleMode.

Mmm, and how that email is helping to progress in the discussion?

The issue is not really for the mcbsp but for the serial that need to handle the 3 different states.

	if (enable) {
		/**
		 * Errata 2.15: [UART]:Cannot Acknowledge Idle Requests
		 * in Smartidle Mode When Configured for DMA Operations.
		 */
		if (uart->dma_enabled)
			idlemode = HWMOD_IDLEMODE_FORCE;
		else
			idlemode = HWMOD_IDLEMODE_SMART;
	} else {
		idlemode = HWMOD_IDLEMODE_NO;
	}

You do need to explicitly set the 3 modes, hence the following 3 APIs:
omap_device_force_idle
omap_device_no_idle
omap_device_smart_idle

You can potentially add another API to restore the default idle mode:

omap_device_default_idle

That seems much simpler than 3 pairs of APIs.

Regards,
Benoit

#22 lore raw

Re: [PATCH 6/7] [RFC] OMAP: hwmod: SYSCONFIG register modification for MCBSP

Quoted 226 lines · Benoit

+ Govindraj

Hi Partha,

Quoted 196 lines · Partha
Quoted 167 lines

From: Cousson, Benoit
Sent: Tuesday, November 30, 2010 9:33 PM

Hi Kishon,

Sorry, for the delay.

Quoted 4 lines · KISHON VIJAY

Resending the mail in plain text format..

On Mon, Nov 22, 2010 at 9:20 PM, ABRAHAM, KISHON VIJAY<[email protected]>

Quoted 2 lines · wrote:
Quoted 2 lines

On Mon, Oct 11, 2010 at 11:48 AM, ABRAHAM, KISHON

Quoted 9 lines · VIJAY
Quoted 9 lines
Quoted 9 lines · Benoit
Quoted 7 lines

Hi Kishon,

Quoted 3 lines · KISHON VIJAY

MCBSP 2 and 3 in OMAP3 has sidetone feature which requires autoidle to be disabled before starting the sidetone. Also

SYSCONFIG

Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

register has to be set with smart idle or no idle depending on

the

Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

dma op mode (threshold or element sync). For doing these

operations

Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
Quoted 2 lines
Quoted 2 lines

dynamically at runtime, hwmod API'S are used to modify SYSCONFIG

register

Quoted 5 lines
Quoted 2 lines

directly.

OK, it looks like we don't have the choice... But for the implementation, please discussed with Manju on that, He is doing

the

Quoted 7 lines
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines

similar thing for the smartstandby issue on SDMA.

   OK.

       Looks like we have a problem when we write an API similar to

the one written

Quoted 2 lines
Quoted 2 lines

       by Manju (omap_hwmod_set_master_standbymode()) [1]. In the

case of McBSP,

Quoted 2 lines
Quoted 2 lines

       I have to modify omap_hwmod_set_slave_idlemode() (which is

already existing),

Quoted 8 lines
Quoted 8 lines

       to include something like

                         +    if (sf&   SYSC_HAS_SIDLEMODE) {
                         +        if (idlemode)
                         +            idlemode = HWMOD_IDLEMODE_NO;
                         +        else
                         +            idlemode = (oh->flags&

HWMOD_SWSUP_SIDLE) ?

Quoted 2 lines
Quoted 2 lines

                         +                HWMOD_IDLEMODE_NO :

HWMOD_IDLEMODE_SMART;

Quoted 2 lines
Quoted 2 lines

                         +    }

How to you enable HWMOD_IDLEMODE_FORCE mode in that case?

Quoted 1 line
Quoted 1 line

       Then an API like omap_device_require_no_idle() and

omap_device_release_no_idle()

Quoted 2 lines
Quoted 2 lines

       would be written similar to omap_device_require_no_mstandby

and

Quoted 3 lines
Quoted 3 lines

       omap_device_release_no_mstandby() (see [1]) that calls omap_hwmod_set_slave_idlemode() with true/false. Passing true

to

Quoted 7 lines
Quoted 7 lines

       omap_hwmod_set_slave_idlemode() will write SIDLE bits with HWMOD_IDLEMODE_NO and false to it will write HWMOD_IDLEMODE_NO/HWMOD_IDLEMODE_SMART depending on HWMOD_SWSUP_SIDLE to SIDLE bits.

       This works fine for McBSP since only two modes come to play

here

Quoted 7 lines
Quoted 7 lines

       (HWMOD_IDLEMODE_NO/HWMOD_IDLEMODE_SMART).

       But omap_hwmod_set_slave_idlemode() API is used by UART (serial.c Please refer [2]) which writes SIDLE bits to HWMOD_IDLEMODE_NO/HWMOD_IDLEMODE_SMART/ and HWMOD_IDLEMODE_FORCE.

That code should not be there. It was a temporary hacks that should be replaced eventually with a clean omap_device API like the one you are currently implementing.
There are a bunch of direct access to omap_hwmod struct that need to be removed as well.

Quoted 2 lines
Quoted 2 lines

       Modifying omap_hwmod_set_slave_idlemode() will require
           1) serial.c to be modified to call functions like

'omap_device_require_no_idle(),

Quoted 2 lines
Quoted 2 lines

               omap_device_release_no_idle()' and

'omap_device_require_force_idle() and

Quoted 3 lines
Quoted 3 lines

               omap_device_release_force_idle()' instead of omap_hwmod_set_slave_idlemode() which is currently

present.

Yep, you're right.

Quoted 3 lines
Quoted 3 lines

       There are 2 problems associated with it
       1) The first problem is having a single API like

omap_hwmod_set_slave_idlemode() to

Quoted 3 lines
Quoted 3 lines

           set two different values like HWMOD_IDLEMODE_NO or HWMOD_IDLEMODE_FORCE (intended to be called by

omap_device_require_no_idle()

Quoted 2 lines
Quoted 2 lines

           and omap_device_require_force_idle() respectively).

According to the new design

Quoted 2 lines
Quoted 2 lines

           omap_hwmod_set_slave_idlemode() is intended to take only

true/false as

Quoted 4 lines
Quoted 4 lines

           arguments.

       2) The second problem is having the release API's

(omap_device_release_no_idle() and

Quoted 2 lines
Quoted 2 lines

            omap_device_release_force_idle()) to restore the

SYSCONFIG to the previous state.

Quoted 2 lines
Quoted 2 lines

            Remember, this was not problem for McBSP since only two

Quoted 7 lines

modes were needed.

And what about 3 APIs?

omap_device_force_idle
omap_device_no_idle
omap_device_smart_idle

Want to reiterate Paul Walmsley's comments on Manju's DMA email dated 11/11/2010
<snip>
2.  Rather than just using a single omap_device_mstandby() function call, I'd rather see something like omap_device_require_no_standby() and omap_device_release_no_standby().  omap_device_require_no_standby() would force the initiator port into no-standby. omap_device_release_no_standby() would return the initiator port MSTANDBYMODE to whatever the state should be (this depends on whether HWMOD_SWSUP_MSTDBY is set).  I'd rather not have the drivers manage the contents of the MSTANDBYMODE bits directly.  Then you should be able to drop _get_master_standbymode() and omap_hwmod_get_master_idlemode() also. Can you please make these changes?
<snip>

The key point is, in the absence of any special situation like errata etc, the IdleMode settings should
be dicated solely by the hwmod flags. We should have a mechanism though to supersede this setting&  request
/release customized settings to handle errata etc.

Quoted 6 lines

So, it makes sense to have request/release API pairs. In this case, omap_device_request_no_idle()&  omap_device_release_no_idle().

omap_hwmod_set_slave_idlemode should continue to take absolute values instead of true/false to support
all possible settings of IdleMode.

Mmm, and how that email is helping to progress in the discussion?

The issue is not really for the mcbsp but for the serial that need to handle the 3 different states.

       if (enable) {
               /**
                * Errata 2.15: [UART]:Cannot Acknowledge Idle Requests
                * in Smartidle Mode When Configured for DMA Operations. */
               if (uart->dma_enabled)
                       idlemode = HWMOD_IDLEMODE_FORCE;
               else
                       idlemode = HWMOD_IDLEMODE_SMART;
       } else {
               idlemode = HWMOD_IDLEMODE_NO;
       }

Quoted 4 lines

You do need to explicitly set the 3 modes, hence the following 3 APIs:
omap_device_force_idle
omap_device_no_idle
omap_device_smart_idle

Agree, if we have to hide "oh" info from driver use only pdev. we need those 3 exported API's.

Quoted 4 lines

You can potentially add another API to restore the default idle mode:

omap_device_default_idle

If default mode is smart idle mode?
we cant enter low power states as we may need to be in force idle mode.

--
Thanks
Govindraj.R

Quoted 10 lines

That seems much simpler than 3 pairs of APIs.

Regards,
Benoit
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#23 lore raw

Re: [PATCH 6/7] [RFC] OMAP: hwmod: SYSCONFIG register modification for MCBSP

In reply to Cousson, Benoit

"Cousson, Benoit" <[email protected]> writes:

[...]

Quoted 22 lines

The issue is not really for the mcbsp but for the serial that need to handle the 3 different states.

	if (enable) {
		/**
		 * Errata 2.15: [UART]:Cannot Acknowledge Idle Requests
		 * in Smartidle Mode When Configured for DMA Operations.
		 */
		if (uart->dma_enabled)
			idlemode = HWMOD_IDLEMODE_FORCE;
		else
			idlemode = HWMOD_IDLEMODE_SMART;
	} else {
		idlemode = HWMOD_IDLEMODE_NO;
	}

You do need to explicitly set the 3 modes, hence the following 3 APIs:
omap_device_force_idle
omap_device_no_idle
omap_device_smart_idle

Quoted 5 lines

You can potentially add another API to restore the default idle mode:

omap_device_default_idle

That seems much simpler than 3 pairs of APIs.

My $0.02... based on the fact that we already have some IPs needing to conrol all 3 modes, I think having the 3 functions above is better than having 3 pairs of request/release functions.

Kevin

#24 lore raw

RE: [PATCH 6/7] [RFC] OMAP: hwmod: SYSCONFIG register modification for MCBSP

Quoted 34 lines

-----Original Message-----
From: Kevin Hilman [mailto:[email protected]]
Sent: Thursday, December 02, 2010 4:24 PM
To: Cousson, Benoit
Cc: Basak, Partha; ABRAHAM, KISHON VIJAY; Paul Walmsley; linux- [email protected]; Kamat, Nishant; Varadarajan, Charulatha; Datta, Shubhrajyoti; [email protected]; [email protected]; Raja, Govindraj
Subject: Re: [PATCH 6/7] [RFC] OMAP: hwmod: SYSCONFIG register modification for MCBSP

"Cousson, Benoit" <[email protected]> writes:

[...]

Quoted 17 lines

The issue is not really for the mcbsp but for the serial that need to handle the 3 different states.

	if (enable) {
		/**
		 * Errata 2.15: [UART]:Cannot Acknowledge Idle Requests
		 * in Smartidle Mode When Configured for DMA Operations.
		 */
		if (uart->dma_enabled)
			idlemode = HWMOD_IDLEMODE_FORCE;
		else
			idlemode = HWMOD_IDLEMODE_SMART;
	} else {
		idlemode = HWMOD_IDLEMODE_NO;
	}
Quoted 5 lines
Quoted 1 line

You do need to explicitly set the 3 modes, hence the following 3

APIs:

Quoted 3 lines

omap_device_force_idle
omap_device_no_idle
omap_device_smart_idle

I am OK with Benoit's 3 + 1 API approach, 3 individual set functions and one common function to restore back to the value as dictated by the flag. What do you say guys?

Quoted 13 lines
Quoted 6 lines

You can potentially add another API to restore the default idle mode:

omap_device_default_idle

That seems much simpler than 3 pairs of APIs.

My $0.02... based on the fact that we already have some IPs needing to conrol all 3 modes, I think having the 3 functions above is better than having 3 pairs of request/release functions.

Kevin

#25 lore raw

RFC PATCH 7/7 OMAP: pm_runtime support for MCBSP

In reply to Kishon Vijay Abraham I
---
 arch/arm/mach-omap2/mcbsp.c             |    7 ++++---
 arch/arm/plat-omap/include/plat/mcbsp.h |    1 -
 arch/arm/plat-omap/mcbsp.c              |   27 +++++++--------------------
 3 files changed, 11 insertions(+), 24 deletions(-)
arch/arm/mach-omap2/mcbsp.c +4 -3
index 25c6703..e9082ff 100644
@@ -7,7 +7,7 @@
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
- *
+*
  * Multichannel mode not supported.
  */
 #include <linux/module.h>
@@ -24,6 +24,7 @@
 #include <plat/mcbsp.h>
 #include <plat/omap_hwmod.h>
 #include <plat/omap_device.h>
+#include <linux/pm_runtime.h>
 
 #include "control.h"
 
@@ -87,7 +88,7 @@ int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id)
 		return -EINVAL;
 	}
 
-	clk_disable(mcbsp->fclk);
+	pm_runtime_put_sync(mcbsp->dev);
 
 	r = clk_set_parent(mcbsp->fclk, fck_src);
 	if (IS_ERR_VALUE(r)) {
@@ -97,7 +98,7 @@ int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id)
 		return -EINVAL;
 	}
 
-	clk_enable(mcbsp->fclk);
+	pm_runtime_get_sync(mcbsp->dev);
 
 	clk_put(fck_src);
 
arch/arm/plat-omap/include/plat/mcbsp.h +0 -1
index 1ff283c..b989d0c 100644
@@ -462,7 +462,6 @@ struct omap_mcbsp {
 	/* Protect the field .free, while checking if the mcbsp is in use */
 	spinlock_t lock;
 	struct omap_mcbsp_platform_data *pdata;
-	struct clk *iclk;
 	struct clk *fclk;
 	struct omap_mcbsp_st_data *st_data;
 	int dma_op_mode;
arch/arm/plat-omap/mcbsp.c +7 -20
index 6b705e1..2a1dce1 100644
@@ -29,6 +29,7 @@
 #include <plat/mcbsp.h>
 #include <plat/omap_hwmod.h>
 #include <plat/omap_device.h>
+#include <linux/pm_runtime.h>
 
 #include "../mach-omap2/cm-regbits-34xx.h"
 
@@ -777,8 +778,7 @@ int omap_mcbsp_request(unsigned int id)
 	if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->request)
 		mcbsp->pdata->ops->request(id);
 
-	clk_enable(mcbsp->iclk);
-	clk_enable(mcbsp->fclk);
+	pm_runtime_get_sync(mcbsp->dev);
 
 	/* Do procedure specific to omap34xx arch, if applicable */
 	omap34xx_mcbsp_request(mcbsp);
@@ -826,8 +826,7 @@ err_clk_disable:
 	/* Do procedure specific to omap34xx arch, if applicable */
 	omap34xx_mcbsp_free(mcbsp);
 
-	clk_disable(mcbsp->fclk);
-	clk_disable(mcbsp->iclk);
+	pm_runtime_put_sync(mcbsp->dev);
 
 	spin_lock(&mcbsp->lock);
 	mcbsp->free = 1;
@@ -857,8 +856,7 @@ void omap_mcbsp_free(unsigned int id)
 	/* Do procedure specific to omap34xx arch, if applicable */
 	omap34xx_mcbsp_free(mcbsp);
 
-	clk_disable(mcbsp->fclk);
-	clk_disable(mcbsp->iclk);
+	pm_runtime_put_sync(mcbsp->dev);
 
 	if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) {
 		/* Free IRQs */
@@ -1737,24 +1735,18 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
 	}
 	mcbsp->dma_tx_sync = res->start;
 
-	mcbsp->iclk = clk_get(&pdev->dev, "ick");
-	if (IS_ERR(mcbsp->iclk)) {
-		ret = PTR_ERR(mcbsp->iclk);
-		dev_err(&pdev->dev, "unable to get ick: %d\n", ret);
-		goto err_res;
-	}
-
 	mcbsp->fclk = clk_get(&pdev->dev, "fck");
 	if (IS_ERR(mcbsp->fclk)) {
 		ret = PTR_ERR(mcbsp->fclk);
 		dev_err(&pdev->dev, "unable to get fck: %d\n", ret);
-		goto err_fclk;
+		goto err_res;
 	}
 
 	mcbsp->pdata = pdata;
 	mcbsp->dev = &pdev->dev;
 	mcbsp_ptr[id] = mcbsp;
 	platform_set_drvdata(pdev, mcbsp);
+	pm_runtime_enable(mcbsp->dev);
 
 	omap_additional_add(mcbsp->dev);
 	if (pdata->dma_op_mode != -EINVAL) {
@@ -1800,8 +1792,6 @@ err_io_st:
 	kfree(mcbsp->st_data);
 err_st_data:
 	clk_put(mcbsp->fclk);
-err_fclk:
-	clk_put(mcbsp->iclk);
 err_res:
 	iounmap(mcbsp->io_base);
 err_ioremap:
@@ -1830,15 +1820,12 @@ static int __devexit omap_mcbsp_remove(struct platform_device *pdev)
 			kfree(mcbsp->st_data);
 		}
 
-		clk_disable(mcbsp->fclk);
-		clk_disable(mcbsp->iclk);
 		clk_put(mcbsp->fclk);
-		clk_put(mcbsp->iclk);
+		pm_runtime_put_sync(mcbsp->dev);
 
 		iounmap(mcbsp->io_base);
 
 		mcbsp->fclk = NULL;
-		mcbsp->iclk = NULL;
 		mcbsp->free = 0;
 		mcbsp->dev = NULL;
 	}
Signature · 1 line
1.7.0.4
#26 lore raw
In reply to Kishon Vijay Abraham I
Quoted 11 lines

-----Original Message-----
From: ABRAHAM, KISHON VIJAY
Sent: Tuesday, October 05, 2010 10:08 PM
To: [email protected]
Cc: Kamat, Nishant; Varadarajan, Charulatha; ABRAHAM, KISHON VIJAY; Datta, Shubhrajyoti; Basak, Partha
Subject: [PATCH 1/7] [RFC] OMAP: MCBSP: hwmod database for 2xxx devices

This patch series is targeted to implement mcbsp driver in hwmod way and to make use of pm_runtime APIs.

This patch series is tested on OMAP3 & 4 and yet to be tested on OMAP2.

There are few clarifications required so that the next patch series can be implemented after aligning.

1. Audio layer is making use of mcbsp and it's dma base addresses and is closely coupled with omap-mcbsp.
This can be handled either by
a. providing an API with which Audio layer can get these addresses. (or)
b. move the plat-omap/mcbsp.c and mach-omap2/mcbsp.c to sound/soc/omap/
[1]

Option (a) would only be a workaround to handle the situation. As audio is the only user for mcbsp, option (b) is better. If option(b) is agreed upon, the same can be addressed on top of the mcbsp hwmod series.

2. Sidetone feature is available only in OMAP3 (McBSP2&3) which has different base address and sys configs compared to it's mcbsp port. Hence the mcbsp is considered as a single device with two hwmods for McBSP2&3 devices in OMAP3.

3. Autoidle needs to be disabled for sidetone before enabling the sidetone feature. There was a design proposed by Kishon [2] to add an API in hwmod to modify the autoidle bit but was not agreed upon. How do we handle this situation where the device has to disable or enable the autoidle bit at runtime?

[1] https://patchwork.kernel.org/patch/225582/
[2] https://patchwork.kernel.org/patch/134371/

We would resend the same patch series by including alsa mailing list ([email protected])

<<snip>>

#27 lore raw

Hello,

Quoted 17 lines · Charulatha

This patch series is targeted to implement mcbsp driver in hwmod way and to make use of pm_runtime APIs.

This patch series is tested on OMAP3 & 4 and yet to be tested on OMAP2.

There are few clarifications required so that the next patch series can be implemented after aligning.

1. Audio layer is making use of mcbsp and it's dma base addresses and is closely coupled with omap-mcbsp.
This can be handled either by
a. providing an API with which Audio layer can get these addresses. (or)
b. move the plat-omap/mcbsp.c and mach-omap2/mcbsp.c to sound/soc/omap/
[1]

Quoted 4 lines

Option (a) would only be a workaround to handle the situation. As audio is the only user for mcbsp, option (b) is better. If option(b) is agreed upon, the same can be addressed on top of the mcbsp hwmod series.

it is true that at the moment only audio is using the McBSP ports, but McBSP is really flexible, it can run for example in SPI mode, and it can be configured to use other serial protocols.
I would go with option c.
Since ASoC is moving to multi-component (the conversion is already in linux- next), this means that the sound/soc/omap/omap-mcbsp, omap-pcm drivers are platform drivers.
So if the plat-omap/mcbsp would register the platform device for McBSP clients (we have only ASoC client at the moment), and use platform data to pass the needed information to the McBSP client driver, than we do not need new API. We still need to modify the ASoC drivers to make use of this platform data, but at least we are going to keep the door open for others to use the McBSP ports for other than audio.

Quoted 4 lines

2. Sidetone feature is available only in OMAP3 (McBSP2&3) which has different base address and sys configs compared to it's mcbsp port. Hence the mcbsp is considered as a single device with two hwmods for McBSP2&3 devices in OMAP3.

Sounds fair enough.

Quoted 5 lines

3. Autoidle needs to be disabled for sidetone before enabling the sidetone feature. There was a design proposed by Kishon [2] to add an API in hwmod to modify the autoidle bit but was not agreed upon. How do we handle this situation where the device has to disable or enable the autoidle bit at runtime?

Yeah, this is really annoying problem. The McBSP ST should block autoidle from McBSP side, but it does not.
If you can not get through the proposed API, we should consider to switch the corresponding McBSP port to NoIdle, when the ST is in use (and restore the idle mode, when the ST has been disabled).
When McBSP is in NoIdle the interface clock is not going to be gated, so ST block will be running without a problem (ST needs the iface clock for operation)

What do you think?

Quoted 8 lines

[1] https://patchwork.kernel.org/patch/225582/
[2] https://patchwork.kernel.org/patch/134371/

We would resend the same patch series by including alsa mailing list ([email protected])

<<snip>>

Signature · 1 line
Péter
#28 lore raw
Quoted 13 lines

-----Original Message-----
From: Peter Ujfalusi [mailto:[email protected]]
Sent: Wednesday, October 06, 2010 12:47 PM
To: Varadarajan, Charulatha
Cc: [email protected]; [email protected]; Kamat, Nishant; Datta, Shubhrajyoti; Basak, Partha; Girdwood, Liam; [email protected]; [email protected]; ABRAHAM, KISHON VIJAY
Subject: Re: [PATCH 1/7] [RFC] OMAP: MCBSP: hwmod database for 2xxx devices

Quoted 1 line

Hello,

Thanks for the quick response.

Quoted 24 lines · Charulatha
Quoted 17 lines

This patch series is targeted to implement mcbsp driver in hwmod way and to make use of pm_runtime APIs.

This patch series is tested on OMAP3 & 4 and yet to be tested on OMAP2.

There are few clarifications required so that the next patch series can be implemented after aligning.

1. Audio layer is making use of mcbsp and it's dma base addresses and is closely coupled with omap-mcbsp.
This can be handled either by
a. providing an API with which Audio layer can get these addresses. (or)
b. move the plat-omap/mcbsp.c and mach-omap2/mcbsp.c to sound/soc/omap/
[1]

Quoted 4 lines

Option (a) would only be a workaround to handle the situation. As audio is the only user for mcbsp, option (b) is better. If option(b) is agreed upon, the same can be addressed on top of the mcbsp hwmod series.

Quoted 5 lines

it is true that at the moment only audio is using the McBSP ports, but McBSP is
really flexible, it can run for example in SPI mode, and it can be configured to
use other serial protocols.

Yes.

Quoted 10 lines

I would go with option c.
Since ASoC is moving to multi-component (the conversion is already in linux-
next), this means that the sound/soc/omap/omap-mcbsp, omap-pcm drivers are platform drivers.
So if the plat-omap/mcbsp would register the platform device for McBSP clients
(we have only ASoC client at the moment), and use platform data to pass the
needed information to the McBSP client driver, than we do not need new API.

Sorry I am confused.

With hwmod implementation, there is a device register code for mcbsp devices in mach-omap2/mcbsp.c and a probe in plat-omap/mcbsp.c. The base address, dma info are not part of pdata and are available to the driver only after probe. I do not understand how the multi-component design in ASOC can avoid the new API.

Also with this multi-component approach in ASOC, two device registrations happens for a single mcbsp device with two different rames ("omap-mcbsp-dai.id" & "omap-mcbsp.id"). Please explain if this what is expected?

Quoted 5 lines

We still need to modify the ASoC drivers to make use of this platform data, but
at least we are going to keep the door open for others to use the McBSP ports
for other than audio.

Agreed. But the current omap-mcbsp driver cannot work standalone for OMAP3/4 due to the issues stated below:
1. omap_mcbsp_pollwrite and omap_mcbsp_pollread functions access McBSP registers as 16-bit. But in OMAP3/4, McBSP registers (DRR_REG and DXR_REG) are limited to 32-bit data accesses and hence poll mode would not work [x].
2. DMA transfers would also not work as it requires a patch similar to [y].

Patches [x] & [y] were rejected as there are no users other than asoc. If it is not agreed to move omap-mcbsp driver to asoc layer, we need to get the omap-mcbsp driver working as a standalone driver. Otherwise it is of no use keeping the mcbsp driver in plat-omap.

Once [x] & [y] patches are upstreamed, audio layer needs to be modified to make use of omap-mcbsp APIs rather than Audio layer calling dma APIs directly to transfer data.

Coming back to the original question. Either we need to fix the broken legacy mcbsp driver or move the omap-mcbsp driver completely to asoc layer. What do you say?

[x] http://www.mail-archive.com/[email protected]/msg19531.html
[y] http://www.mail-archive.com/[email protected]/msg04085.html

Quoted 7 lines
Quoted 5 lines

2. Sidetone feature is available only in OMAP3 (McBSP2&3) which has different base address and sys configs compared to it's mcbsp port. Hence the mcbsp is considered as a single device with two hwmods for McBSP2&3 devices in OMAP3.

Sounds fair enough.

Thanks.

Quoted 23 lines
Quoted 2 lines

3. Autoidle needs to be disabled for sidetone before enabling the

sidetone

Quoted 1 line

feature. There was a design proposed by Kishon [2] to add an API in

hwmod

Quoted 1 line

to modify the autoidle bit but was not agreed upon. How do we handle

this

Quoted 2 lines

situation where the device has to disable or enable the autoidle bit at runtime?

Yeah, this is really annoying problem. The McBSP ST should block autoidle from
McBSP side, but it does not.
If you can not get through the proposed API, we should consider to switch the
corresponding McBSP port to NoIdle, when the ST is in use (and restore the idle
mode, when the ST has been disabled).
When McBSP is in NoIdle the interface clock is not going to be gated, so ST
block will be running without a problem (ST needs the iface clock for operation)

Quoted 1 line

What do you think?

I think it might not be possible to handle this, as the clocks are the same for ST and mcbsp port. pm_runtime APIs are not called during ST enable/disable as clocks are already enabled while enabling mcbsp port. Hence the idle bit change cannot happen even if the oh->flags are modified runtime during ST enable/disable.

Quoted 11 lines
Quoted 8 lines

[1] https://patchwork.kernel.org/patch/225582/
[2] https://patchwork.kernel.org/patch/134371/

We would resend the same patch series by including alsa mailing list ([email protected])

<<snip>>

--
Péter

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#29 lore raw

Hi Charu,

Quoted 133 lines · Charulatha
Quoted 12 lines

From: Peter Ujfalusi [mailto:[email protected]]
Sent: Wednesday, October 06, 2010 12:47 PM
To: Varadarajan, Charulatha
Cc: [email protected]; [email protected]; Kamat, Nishant; Datta, Shubhrajyoti; Basak, Partha; Girdwood, Liam; [email protected]; [email protected]; ABRAHAM, KISHON VIJAY
Subject: Re: [PATCH 1/7] [RFC] OMAP: MCBSP: hwmod database for 2xxx devices

Quoted 1 line

Hello,

Thanks for the quick response.

Quoted 24 lines · Charulatha
Quoted 17 lines

This patch series is targeted to implement mcbsp driver in hwmod way and to make use of pm_runtime APIs.

This patch series is tested on OMAP3& 4 and yet to be tested on OMAP2.

There are few clarifications required so that the next patch series can be implemented after aligning.

1. Audio layer is making use of mcbsp and it's dma base addresses and is closely coupled with omap-mcbsp.
This can be handled either by
a. providing an API with which Audio layer can get these addresses. (or)
b. move the plat-omap/mcbsp.c and mach-omap2/mcbsp.c to sound/soc/omap/
[1]

Quoted 4 lines

Option (a) would only be a workaround to handle the situation. As audio is the only user for mcbsp, option (b) is better. If option(b) is agreed upon, the same can be addressed on top of the mcbsp hwmod series.

Quoted 5 lines

it is true that at the moment only audio is using the McBSP ports, but McBSP is
really flexible, it can run for example in SPI mode, and it can be configured to
use other serial protocols.

Yes.

Quoted 10 lines

I would go with option c.
Since ASoC is moving to multi-component (the conversion is already in linux-
next), this means that the sound/soc/omap/omap-mcbsp, omap-pcm drivers are platform drivers.
So if the plat-omap/mcbsp would register the platform device for McBSP clients
(we have only ASoC client at the moment), and use platform data to pass the
needed information to the McBSP client driver, than we do not need new API.

Sorry I am confused.

With hwmod implementation, there is a device register code for mcbsp devices in mach-omap2/mcbsp.c and a probe in plat-omap/mcbsp.c. The base address, dma info are not part of pdata and are available to the driver only after probe. I do not understand how the multi-component design in ASOC can avoid the new API.

Also with this multi-component approach in ASOC, two device registrations happens for a single mcbsp device with two different rames ("omap-mcbsp-dai.id"& "omap-mcbsp.id"). Please explain if this what is expected?

Quoted 5 lines

We still need to modify the ASoC drivers to make use of this platform data, but
at least we are going to keep the door open for others to use the McBSP ports
for other than audio.

Agreed. But the current omap-mcbsp driver cannot work standalone for OMAP3/4 due to the issues stated below:
1. omap_mcbsp_pollwrite and omap_mcbsp_pollread functions access McBSP registers as 16-bit. But in OMAP3/4, McBSP registers (DRR_REG and DXR_REG) are limited to 32-bit data accesses and hence poll mode would not work [x].
2. DMA transfers would also not work as it requires a patch similar to [y].

Patches [x]& [y] were rejected as there are no users other than asoc. If it is not agreed to move omap-mcbsp driver to asoc layer, we need to get the omap-mcbsp driver working as a standalone driver. Otherwise it is of no use keeping the mcbsp driver in plat-omap.

Once [x]& [y] patches are upstreamed, audio layer needs to be modified to make use of omap-mcbsp APIs rather than Audio layer calling dma APIs directly to transfer data.

Coming back to the original question. Either we need to fix the broken legacy mcbsp driver or move the omap-mcbsp driver completely to asoc layer. What do you say?

[x] http://www.mail-archive.com/[email protected]/msg19531.html
[y] http://www.mail-archive.com/[email protected]/msg04085.html

Quoted 7 lines
Quoted 5 lines

2. Sidetone feature is available only in OMAP3 (McBSP2&3) which has different base address and sys configs compared to it's mcbsp port. Hence the mcbsp is considered as a single device with two hwmods for McBSP2&3 devices in OMAP3.

Sounds fair enough.

Thanks.

Quoted 23 lines
Quoted 2 lines

3. Autoidle needs to be disabled for sidetone before enabling the

sidetone

Quoted 1 line

feature. There was a design proposed by Kishon [2] to add an API in

hwmod

Quoted 1 line

to modify the autoidle bit but was not agreed upon. How do we handle

this

Quoted 2 lines

situation where the device has to disable or enable the autoidle bit at runtime?

Yeah, this is really annoying problem. The McBSP ST should block autoidle from
McBSP side, but it does not.
If you can not get through the proposed API, we should consider to switch the
corresponding McBSP port to NoIdle, when the ST is in use (and restore the idle
mode, when the ST has been disabled).
When McBSP is in NoIdle the interface clock is not going to be gated, so ST
block will be running without a problem (ST needs the iface clock for operation)

Quoted 3 lines
Quoted 1 line

What do you think?

I think it might not be possible to handle this, as the clocks are the same for ST and mcbsp port. pm_runtime APIs are not called during ST enable/disable as clocks are already enabled while enabling mcbsp port. Hence the idle bit change cannot happen even if the oh->flags are modified runtime during ST enable/disable.

This is mainly because of the 2 hwmods for 1 device implementation, which make perfect sense in theory, but because of that bug, becomes tricky to handle it in the fmwk.

FYI, SDMA and MUSB are as well requiring some sysconfig change during runtime. So a couple of API will have to be implemented. I guess we don't have the choice. Now, it is just a matter of having the right implementation.
I'll comment on that patch directly.

Benoit

Quoted 8 lines
Quoted 8 lines
Quoted 8 lines

[1] https://patchwork.kernel.org/patch/225582/
[2] https://patchwork.kernel.org/patch/134371/

We would resend the same patch series by including alsa mailing list ([email protected])

Quoted 8 lines
Quoted 4 lines
Quoted 1 line

<<snip>>

--
Péter

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#30 lore raw
In reply to Varadarajan, Charulatha

ping..

Quoted 134 lines · Charulatha
Quoted 13 lines

-----Original Message-----
From: Peter Ujfalusi [mailto:[email protected]]
Sent: Wednesday, October 06, 2010 12:47 PM
To: Varadarajan, Charulatha
Cc: [email protected]; [email protected]; Kamat, Nishant; Datta, Shubhrajyoti; Basak, Partha; Girdwood, Liam; [email protected]; [email protected]; ABRAHAM, KISHON VIJAY
Subject: Re: [PATCH 1/7] [RFC] OMAP: MCBSP: hwmod database for 2xxx devices

Quoted 1 line

Hello,

Thanks for the quick response.

Quoted 24 lines · Charulatha
Quoted 17 lines

This patch series is targeted to implement mcbsp driver in hwmod way and to make use of pm_runtime APIs.

This patch series is tested on OMAP3& 4 and yet to be tested on OMAP2.

There are few clarifications required so that the next patch series can be implemented after aligning.

1. Audio layer is making use of mcbsp and it's dma base addresses and is closely coupled with omap-mcbsp.
This can be handled either by
a. providing an API with which Audio layer can get these addresses. (or)
b. move the plat-omap/mcbsp.c and mach-omap2/mcbsp.c to sound/soc/omap/
[1]

Quoted 4 lines

Option (a) would only be a workaround to handle the situation. As audio is the only user for mcbsp, option (b) is better. If option(b) is agreed upon, the same can be addressed on top of the mcbsp hwmod series.

Quoted 5 lines

it is true that at the moment only audio is using the McBSP ports, but McBSP is
really flexible, it can run for example in SPI mode, and it can be configured to
use other serial protocols.

Yes.

Quoted 10 lines

I would go with option c.
Since ASoC is moving to multi-component (the conversion is already in linux-
next), this means that the sound/soc/omap/omap-mcbsp, omap-pcm drivers are platform drivers.
So if the plat-omap/mcbsp would register the platform device for McBSP clients
(we have only ASoC client at the moment), and use platform data to pass the
needed information to the McBSP client driver, than we do not need new API.

Sorry I am confused.

With hwmod implementation, there is a device register code for mcbsp devices in mach-omap2/mcbsp.c and a probe in plat-omap/mcbsp.c. The base address, dma info are not part of pdata and are available to the driver only after probe. I do not understand how the multi-component design in ASOC can avoid the new API.

Also with this multi-component approach in ASOC, two device registrations happens for a single mcbsp device with two different rames ("omap-mcbsp-dai.id"& "omap-mcbsp.id"). Please explain if this what is expected?

Quoted 5 lines

We still need to modify the ASoC drivers to make use of this platform data, but
at least we are going to keep the door open for others to use the McBSP ports
for other than audio.

Agreed. But the current omap-mcbsp driver cannot work standalone for OMAP3/4 due to the issues stated below:
1. omap_mcbsp_pollwrite and omap_mcbsp_pollread functions access McBSP registers as 16-bit. But in OMAP3/4, McBSP registers (DRR_REG and DXR_REG) are limited to 32-bit data accesses and hence poll mode would not work [x].
2. DMA transfers would also not work as it requires a patch similar to [y].

Patches [x]& [y] were rejected as there are no users other than asoc. If it is not agreed to move omap-mcbsp driver to asoc layer, we need to get the omap-mcbsp driver working as a standalone driver. Otherwise it is of no use keeping the mcbsp driver in plat-omap.

Once [x]& [y] patches are upstreamed, audio layer needs to be modified to make use of omap-mcbsp APIs rather than Audio layer calling dma APIs directly to transfer data.

Coming back to the original question. Either we need to fix the broken legacy mcbsp driver or move the omap-mcbsp driver completely to asoc layer. What do you say?

[x] http://www.mail-archive.com/[email protected]/msg19531.html
[y] http://www.mail-archive.com/[email protected]/msg04085.html

Quoted 7 lines
Quoted 5 lines

2. Sidetone feature is available only in OMAP3 (McBSP2&3) which has different base address and sys configs compared to it's mcbsp port. Hence the mcbsp is considered as a single device with two hwmods for McBSP2&3 devices in OMAP3.

Sounds fair enough.

Thanks.

Quoted 23 lines
Quoted 2 lines

3. Autoidle needs to be disabled for sidetone before enabling the

sidetone

Quoted 1 line

feature. There was a design proposed by Kishon [2] to add an API in

hwmod

Quoted 1 line

to modify the autoidle bit but was not agreed upon. How do we handle

this

Quoted 2 lines

situation where the device has to disable or enable the autoidle bit at runtime?

Yeah, this is really annoying problem. The McBSP ST should block autoidle from
McBSP side, but it does not.
If you can not get through the proposed API, we should consider to switch the
corresponding McBSP port to NoIdle, when the ST is in use (and restore the idle
mode, when the ST has been disabled).
When McBSP is in NoIdle the interface clock is not going to be gated, so ST
block will be running without a problem (ST needs the iface clock for operation)

Quoted 18 lines
Quoted 1 line

What do you think?

I think it might not be possible to handle this, as the clocks are the same for ST and mcbsp port. pm_runtime APIs are not called during ST enable/disable as clocks are already enabled while enabling mcbsp port. Hence the idle bit change cannot happen even if the oh->flags are modified runtime during ST enable/disable.

Quoted 11 lines
Quoted 8 lines

[1] https://patchwork.kernel.org/patch/225582/
[2] https://patchwork.kernel.org/patch/134371/

We would resend the same patch series by including alsa mailing list ([email protected])

<<snip>>

--
Péter

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#31 lore raw
In reply to Varadarajan, Charulatha

Hi,

Quoted 8 lines · Charulatha

Sorry I am confused.

With hwmod implementation, there is a device register code for mcbsp devices in mach-omap2/mcbsp.c and a probe in plat-omap/mcbsp.c. The base address, dma info are not part of pdata and are available to the driver only after probe. I do not understand how the multi-component design in ASOC can avoid the new API.

Quoted 4 lines

Also with this multi-component approach in ASOC, two device registrations happens for a single mcbsp device with two different rames ("omap-mcbsp-dai.id" & "omap-mcbsp.id"). Please explain if this what is expected?

I have given myself some time to think this over...
I think the best way forward is to provide an API from plat-omap/mcbsp.c for client drivers (like ASoC audio) to ask for the needed configuration (the things that is 'hard wired' in soc/omap/omap-mcbsp.c at the monent). Something like omap-mcbsp-get-config(id, &config);

In this way we can keep the door open for other uses of McBSP if ever needed.

Quoted 11 lines
Quoted 5 lines

We still need to modify the ASoC drivers to make use of this platform data, but
at least we are going to keep the door open for others to use the McBSP ports
for other than audio.

Agreed. But the current omap-mcbsp driver cannot work standalone for OMAP3/4 due to the issues stated below:
1. omap_mcbsp_pollwrite and omap_mcbsp_pollread functions access McBSP registers as 16-bit. But in OMAP3/4, McBSP registers (DRR_REG and DXR_REG) are limited to 32-bit data accesses and hence poll mode would not work [x].

Yes, this need to be fixed, but it can be done later, it does not need to be part of the hwmod series.

Quoted 1 line

2. DMA transfers would also not work as it requires a patch similar to [y].

Well, this patch was sent in 2008. nowdays we moved the OMAP audio support to ASoC, and there are no 'legacy' ALSA arm/omap drivers anymore.
In ASoC the cpu_dai and the platform drivers are separate things. This allows us to use the same platform driver (omap-pcm) for McBSp, McPDM (and in theory we could have OMAP2 EAC) cpu_dai drivers without duplicating code. As a note: most of the features this patch was trying to implement is already done for the ASoC implementation, but if there is need for new features, it has to be done using the ASoC framework.

Quoted 3 lines

Coming back to the original question. Either we need to fix the broken legacy mcbsp driver or move the omap-mcbsp driver completely to asoc layer. What do you say?

I would keep the partitioning same as it is now.
If there is a reason we can add bus driver functionality to McBSP, but at the moment there is no need for that.

Signature · 1 line
Péter
#32 lore raw
Quoted 27 lines

-----Original Message-----
From: Peter Ujfalusi [mailto:[email protected]]
Sent: Wednesday, October 13, 2010 2:02 PM
To: Varadarajan, Charulatha
Cc: [email protected]; [email protected]; Kamat, Nishant; Datta, Shubhrajyoti; Basak, Partha; Girdwood, Liam; [email protected]; [email protected]; ABRAHAM, KISHON VIJAY
Subject: Re: [PATCH 1/7] [RFC] OMAP: MCBSP: hwmod database for 2xxx devices

Hi,

Quoted 4 lines · Charulatha

Sorry I am confused.

With hwmod implementation, there is a device register code for mcbsp devices in mach-omap2/mcbsp.c and a probe in

plat-omap/mcbsp.c. The base

Quoted 1 line

address, dma info are not part of pdata and are available

to the driver

Quoted 1 line

only after probe. I do not understand how the

multi-component design in

Quoted 2 lines

ASOC can avoid the new API.

Quoted 7 lines
Quoted 3 lines

Also with this multi-component approach in ASOC, two device registrations happens for a single mcbsp device with two different rames ("omap-mcbsp-dai.id" & "omap-mcbsp.id"). Please

explain if this

Quoted 1 line

what is expected?

I have given myself some time to think this over...

Thanks Peter.

Quoted 6 lines

I think the best way forward is to provide an API from plat-omap/mcbsp.c for
client drivers (like ASoC audio) to ask for the needed configuration (the things
that is 'hard wired' in soc/omap/omap-mcbsp.c at the monent). Something like omap-mcbsp-get-config(id, &config);

Agreed.

Quoted 3 lines

In this way we can keep the door open for other uses of McBSP if ever needed.

Okay.

Quoted 13 lines
Quoted 2 lines
Quoted 2 lines

We still need to modify the ASoC drivers to make use of

this platform

Quoted 2 lines
Quoted 2 lines

data, but
at least we are going to keep the door open for others to

use the McBSP

Quoted 6 lines
Quoted 2 lines

ports
for other than audio.

Agreed. But the current omap-mcbsp driver cannot work standalone for OMAP3/4 due to the issues stated below:
1. omap_mcbsp_pollwrite and omap_mcbsp_pollread functions

access McBSP

Quoted 8 lines
Quoted 1 line

registers as 16-bit. But in OMAP3/4, McBSP registers

(DRR_REG and DXR_REG)

Quoted 1 line

are limited to 32-bit data accesses and hence poll mode

would not work [x].

Yes, this need to be fixed, but it can be done later, it does not need to be
part of the hwmod series.

Okay.

Quoted 4 lines
Quoted 2 lines

2. DMA transfers would also not work as it requires a patch

similar to [y].

Quoted 13 lines

Well, this patch was sent in 2008. nowdays we moved the OMAP audio support to
ASoC, and there are no 'legacy' ALSA arm/omap drivers anymore. In ASoC the cpu_dai and the platform drivers are separate things. This allows us to use the same platform driver (omap-pcm) for McBSp, McPDM (and
in theory we could have OMAP2 EAC) cpu_dai drivers without duplicating code.
As a note: most of the features this patch was trying to implement is already
done for the ASoC implementation, but if there is need for new features, it has
to be done using the ASoC framework.

If we do this, would it not contradict the idea of keeping the door open for others to use the McBSP ports?

If other users should be allowed to use McBSP ports, it is good to have DMA support in plat-omap/mcbsp.c itself and modify the asoc implementation to take advantage of the proposed new mcbsp design. If agreed, this shall be addressed later. Please let me know your thoughts on this.

Quoted 7 lines
Quoted 2 lines

Coming back to the original question. Either we need to fix

the broken

Quoted 2 lines

legacy mcbsp driver or move the omap-mcbsp driver completely to asoc layer. What do you say?

I would keep the partitioning same as it is now.

Okay.

Quoted 2 lines

If there is a reason we can add bus driver functionality to McBSP,

Can you elaborate? mcbsp driver is already following platform bus device model.

Quoted 2 lines

but at the
moment there is no need for that.

For testing any changes in mcbsp driver (including hwmod), we are relying on internal patches (dma/pollmode patches). Instead, if mcbsp dma support is available in the driver itself, it would be useful for bug fixing/development activities.

Quoted 4 lines
Signature · 3 lines
-- 
Péter
--

To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#33 lore raw
Quoted 6 lines · Charulatha

If other users should be allowed to use McBSP ports, it is good to have DMA support in plat-omap/mcbsp.c itself and modify the asoc implementation to take advantage of the proposed new mcbsp design. If agreed, this shall be addressed later. Please let me know your thoughts on this.

ASoC design allows to have other data movers (ASoC platfrom driver) also than SDMA only [1]. So tieing McBSP and DMA together means leaving out DSP<->McBSP<->Codec setup.

I think API between McBSP driver and client should deal only with port transfer setup and a layer above that should take care of data transfer setup and implement an use-case specific API. E.g. where ALSA is using continuous transmission from/to circular buffer some another use-case would need chained scatter-gather DMA transfers, PIO, etc.

So things can get complicated if trying to implement generic transfer API to general purpose block like McBSP compared to some dedicated block where transfer setup is always more or less the same.

Signature · 3 lines
Jarkko
1.
http://mailman.alsa-project.org/pipermail/alsa-devel/2010-August/030392.html
#34 lore raw
Quoted 3 lines · Jarkko Nikula

So things can get complicated if trying to implement generic transfer API to general purpose block like McBSP compared to some dedicated block where transfer setup is always more or less the same.

I tend to agree. Experience with some of the other platforms suggests that doing the abstracted API for data transfers doesn't save you that much unless the hardware is really hard to manage and so needs lots of code that can be factored out from the leaf drivers.

#35 lore raw
In reply to Varadarajan, Charulatha
Quoted 5 lines · Charulatha
Quoted 3 lines

Yes, this need to be fixed, but it can be done later, it does not need to be
part of the hwmod series.

Okay.

This problem there for a long time, and so far no one complained, or fixed it. Probably there are no users for pollread/write at all, but I would not remove the functionality. It is better to fix them later.

Quoted 18 lines
Quoted 4 lines
Quoted 1 line

2. DMA transfers would also not work as it requires a patch

similar to [y].

Quoted 13 lines

Well, this patch was sent in 2008. nowdays we moved the OMAP audio support to
ASoC, and there are no 'legacy' ALSA arm/omap drivers anymore. In ASoC the cpu_dai and the platform drivers are separate things. This allows us to use the same platform driver (omap-pcm) for McBSp, McPDM (and
in theory we could have OMAP2 EAC) cpu_dai drivers without duplicating code.
As a note: most of the features this patch was trying to implement is already
done for the ASoC implementation, but if there is need for new features, it has
to be done using the ASoC framework.

Quoted 2 lines

If we do this, would it not contradict the idea of keeping the door open for others to use the McBSP ports?

Why? If you add support for different sample formats to ASoC, it will not change anything.

Quoted 5 lines

If other users should be allowed to use McBSP ports, it is good to have DMA support in plat-omap/mcbsp.c itself and modify the asoc implementation to take advantage of the proposed new mcbsp design. If agreed, this shall be addressed later. Please let me know your thoughts on this.

What I mean is that later we could add DMA transfer functionality if there is a need, but at the moment I don't see any reason to do that.
Also moving the DMA functionality to plat-omap/mcbsp.c would require quite a big change in there, and as well in the ASoC code. On top of that we will broke the sound/soc/omap/omap-pcm.c to be McBSP independent, and that is one of the main points here. We are using omap-pcm.c with McBSP and McPDM dai drivers. That has to remain the same.
In the future we can implement DMA transfer capabilities to mcbsp. I would not do this as part of hwmod either.
I think such an extension to the current McBSP code is only needed if/when we have other users for McBSP than audio.

Quoted 9 lines
Quoted 8 lines
Quoted 1 line

Coming back to the original question. Either we need to fix

the broken

Quoted 2 lines

legacy mcbsp driver or move the omap-mcbsp driver completely to asoc layer. What do you say?

I would keep the partitioning same as it is now.

Quoted 7 lines

Okay.

Quoted 2 lines

If there is a reason we can add bus driver functionality to McBSP,

Can you elaborate? mcbsp driver is already following platform bus device model.

I meant adding DMA functionality to McBSP. I would not worry about this at this time.

Quoted 8 lines
Quoted 3 lines

but at the
moment there is no need for that.

For testing any changes in mcbsp driver (including hwmod), we are relying on internal patches (dma/pollmode patches). Instead, if mcbsp dma support is available in the driver itself, it would be useful for bug fixing/development activities.

You should use audio (ASoC) for verification, for example Beagle, or other board. I would say that the audio support is solid on OMAP platforms, and that is the main thing which must work after hwmod conversion.

Signature · 1 line
Péter
#36 lore raw
In reply to Kishon Vijay Abraham I

Hi,

Next version of this patch series will have proper subject in it.

-Kishon

Quoted 502 lines · KISHON VIJAY

From: Charulatha V<[email protected]>

---
  arch/arm/mach-omap2/omap_hwmod_2420_data.c |  125 +++++++++++
  arch/arm/mach-omap2/omap_hwmod_2430_data.c |  313 ++++++++++++++++++++++++++++
  2 files changed, 438 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/omap_hwmod_2420_data.c +125 -0
index adf6e36..289ef86 100644
@@ -36,6 +36,8 @@ static struct omap_hwmod omap2420_iva_hwmod;
  static struct omap_hwmod omap2420_l3_main_hwmod;
  static struct omap_hwmod omap2420_l4_core_hwmod;
  static struct omap_hwmod omap2420_wd_timer2_hwmod;
+static struct omap_hwmod omap2420_mcbsp1_hwmod;
+static struct omap_hwmod omap2420_mcbsp2_hwmod;
 
  /* L3 ->  L4_CORE interface */
  static struct omap_hwmod_ocp_if omap2420_l3_main__l4_core = {
@@ -418,6 +420,127 @@ static struct omap_hwmod omap2420_uart3_hwmod = {
         .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
  };
 
+/*
+ * 'mcbsp' class
+ * multi channel buffered serial port controller
+ */
+
+static struct omap_hwmod_class omap2420_mcbsp_hwmod_class = {
+       .name = "mcbsp",
+};
+
+/* mcbsp1 */
+static struct omap_hwmod_irq_info omap2420_mcbsp1_irqs[] = {
+       { .name = "tx", .irq = 59 },
+       { .name = "rx", .irq = 60 },
+};
+
+static struct omap_hwmod_dma_info omap2420_mcbsp1_sdma_chs[] = {
+       { .name = "rx", .dma_req = 31 },
+       { .name = "tx", .dma_req = 30 },
+};
+
+static struct omap_hwmod_addr_space omap2420_mcbsp1_addrs[] = {
+       {
+               .pa_start       = 0x48074000,
+               .pa_end         = 0x480740ff,
+               .flags          = ADDR_TYPE_RT
+       },
+};
+
+/* l4_core ->  mcbsp1 */
+static struct omap_hwmod_ocp_if omap2420_l4_core__mcbsp1 = {
+       .master         =&omap2420_l4_core_hwmod,
+       .slave          =&omap2420_mcbsp1_hwmod,
+       .clk            = "mcbsp1_ick",
+       .addr           = omap2420_mcbsp1_addrs,
+       .addr_cnt       = ARRAY_SIZE(omap2420_mcbsp1_addrs),
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mcbsp1 slave ports */
+static struct omap_hwmod_ocp_if *omap2420_mcbsp1_slaves[] = {
+&omap2420_l4_core__mcbsp1,
+};
+
+static struct omap_hwmod omap2420_mcbsp1_hwmod = {
+       .name           = "mcbsp1",
+       .class          =&omap2420_mcbsp_hwmod_class,
+       .mpu_irqs       = omap2420_mcbsp1_irqs,
+       .mpu_irqs_cnt   = ARRAY_SIZE(omap2420_mcbsp1_irqs),
+       .sdma_reqs      = omap2420_mcbsp1_sdma_chs,
+       .sdma_reqs_cnt  = ARRAY_SIZE(omap2420_mcbsp1_sdma_chs),
+       .main_clk       = "mcbsp1_fck",
+       .prcm           = {
+               .omap2 = {
+                       .prcm_reg_id = 1,
+                       .module_bit = OMAP24XX_EN_MCBSP1_SHIFT,
+                       .module_offs = CORE_MOD,
+                       .idlest_reg_id = 1,
+                       .idlest_idle_bit = OMAP24XX_EN_MCBSP1_SHIFT,
+               },
+       },
+       .slaves         = omap2420_mcbsp1_slaves,
+       .slaves_cnt     = ARRAY_SIZE(omap2420_mcbsp1_slaves),
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+/* mcbsp2 */
+static struct omap_hwmod_irq_info omap2420_mcbsp2_irqs[] = {
+       { .name = "tx", .irq = 62 },
+       { .name = "rx", .irq = 63 },
+};
+
+static struct omap_hwmod_dma_info omap2420_mcbsp2_sdma_chs[] = {
+       { .name = "rx", .dma_req = 33 },
+       { .name = "tx", .dma_req = 32 },
+};
+
+static struct omap_hwmod_addr_space omap2420_mcbsp2_addrs[] = {
+       {
+               .pa_start       = 0x48076000,
+               .pa_end         = 0x480760ff,
+               .flags          = ADDR_TYPE_RT
+       },
+};
+
+/* l4_core ->  mcbsp2 */
+static struct omap_hwmod_ocp_if omap2420_l4_core__mcbsp2 = {
+       .master         =&omap2420_l4_core_hwmod,
+       .slave          =&omap2420_mcbsp2_hwmod,
+       .clk            = "mcbsp2_ick",
+       .addr           = omap2420_mcbsp2_addrs,
+       .addr_cnt       = ARRAY_SIZE(omap2420_mcbsp2_addrs),
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mcbsp2 slave ports */
+static struct omap_hwmod_ocp_if *omap2420_mcbsp2_slaves[] = {
+&omap2420_l4_core__mcbsp2,
+};
+
+static struct omap_hwmod omap2420_mcbsp2_hwmod = {
+       .name           = "mcbsp2",
+       .class          =&omap2420_mcbsp_hwmod_class,
+       .mpu_irqs       = omap2420_mcbsp2_irqs,
+       .mpu_irqs_cnt   = ARRAY_SIZE(omap2420_mcbsp2_irqs),
+       .sdma_reqs      = omap2420_mcbsp2_sdma_chs,
+       .sdma_reqs_cnt  = ARRAY_SIZE(omap2420_mcbsp2_sdma_chs),
+       .main_clk       = "mcbsp2_fck",
+       .prcm           = {
+               .omap2 = {
+                       .prcm_reg_id = 1,
+                       .module_bit = OMAP24XX_EN_MCBSP2_SHIFT,
+                       .module_offs = CORE_MOD,
+                       .idlest_reg_id = 1,
+                       .idlest_idle_bit = OMAP24XX_EN_MCBSP2_SHIFT,
+               },
+       },
+       .slaves         = omap2420_mcbsp2_slaves,
+       .slaves_cnt     = ARRAY_SIZE(omap2420_mcbsp2_slaves),
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
  static __initdata struct omap_hwmod *omap2420_hwmods[] = {
         &omap2420_l3_main_hwmod,
         &omap2420_l4_core_hwmod,
@@ -428,6 +551,8 @@ static __initdata struct omap_hwmod *omap2420_hwmods[] = {
         &omap2420_uart1_hwmod,
         &omap2420_uart2_hwmod,
         &omap2420_uart3_hwmod,
+&omap2420_mcbsp1_hwmod,
+&omap2420_mcbsp2_hwmod,
         NULL,
  };
 
arch/arm/mach-omap2/omap_hwmod_2430_data.c +313 -1
index 12d939e..5eb1fe4 100644
@@ -36,6 +36,11 @@ static struct omap_hwmod omap2430_iva_hwmod;
  static struct omap_hwmod omap2430_l3_main_hwmod;
  static struct omap_hwmod omap2430_l4_core_hwmod;
  static struct omap_hwmod omap2430_wd_timer2_hwmod;
+static struct omap_hwmod omap2430_mcbsp1_hwmod;
+static struct omap_hwmod omap2430_mcbsp2_hwmod;
+static struct omap_hwmod omap2430_mcbsp3_hwmod;
+static struct omap_hwmod omap2430_mcbsp4_hwmod;
+static struct omap_hwmod omap2430_mcbsp5_hwmod;
 
  /* L3 ->  L4_CORE interface */
  static struct omap_hwmod_ocp_if omap2430_l3_main__l4_core = {
@@ -418,6 +423,309 @@ static struct omap_hwmod omap2430_uart3_hwmod = {
         .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
  };
 
+/*
+ * 'mcbsp' class
+ * multi channel buffered serial port controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap2430_mcbsp_sysc = {
+       .rev_offs       = 0x007C,
+       .sysc_offs      = 0x008C,
+       .sysc_flags     = (SYSC_HAS_SOFTRESET),
+       .sysc_fields    =&omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2430_mcbsp_hwmod_class = {
+       .name = "mcbsp",
+       .sysc =&omap2430_mcbsp_sysc,
+};
+
+/* mcbsp1 */
+static struct omap_hwmod_irq_info omap2430_mcbsp1_irqs[] = {
+       { .name = "tx",         .irq = 59 },
+       { .name = "rx",         .irq = 60 },
+       { .name = "ovr",        .irq = 61 },
+       { .name = "common",     .irq = 64 },
+};
+
+static struct omap_hwmod_dma_info omap2430_mcbsp1_sdma_chs[] = {
+       { .name = "rx", .dma_req = 31 },
+       { .name = "tx", .dma_req = 30 },
+};
+
+static struct omap_hwmod_addr_space omap2430_mcbsp1_addrs[] = {
+       {
+               .pa_start       = 0x48074000,
+               .pa_end         = 0x480740ff,
+               .flags          = ADDR_TYPE_RT
+       },
+};
+
+/* l4_core ->  mcbsp1 */
+static struct omap_hwmod_ocp_if omap2430_l4_core__mcbsp1 = {
+       .master         =&omap2430_l4_core_hwmod,
+       .slave          =&omap2430_mcbsp1_hwmod,
+       .clk            = "mcbsp1_ick",
+       .addr           = omap2430_mcbsp1_addrs,
+       .addr_cnt       = ARRAY_SIZE(omap2430_mcbsp1_addrs),
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mcbsp1 slave ports */
+static struct omap_hwmod_ocp_if *omap2430_mcbsp1_slaves[] = {
+&omap2430_l4_core__mcbsp1,
+};
+
+static struct omap_hwmod omap2430_mcbsp1_hwmod = {
+       .name           = "mcbsp1",
+       .class          =&omap2430_mcbsp_hwmod_class,
+       .mpu_irqs       = omap2430_mcbsp1_irqs,
+       .mpu_irqs_cnt   = ARRAY_SIZE(omap2430_mcbsp1_irqs),
+       .sdma_reqs      = omap2430_mcbsp1_sdma_chs,
+       .sdma_reqs_cnt  = ARRAY_SIZE(omap2430_mcbsp1_sdma_chs),
+       .main_clk       = "mcbsp1_fck",
+       .prcm           = {
+               .omap2 = {
+                       .prcm_reg_id = 1,
+                       .module_bit = OMAP24XX_EN_MCBSP1_SHIFT,
+                       .module_offs = CORE_MOD,
+                       .idlest_reg_id = 1,
+                       .idlest_idle_bit = OMAP24XX_EN_MCBSP1_SHIFT,
+               },
+       },
+       .slaves         = omap2430_mcbsp1_slaves,
+       .slaves_cnt     = ARRAY_SIZE(omap2430_mcbsp1_slaves),
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* mcbsp2 */
+static struct omap_hwmod_irq_info omap2430_mcbsp2_irqs[] = {
+       { .name = "tx",         .irq = 62 },
+       { .name = "rx",         .irq = 63 },
+       { .name = "common",     .irq = 16 },
+};
+
+static struct omap_hwmod_dma_info omap2430_mcbsp2_sdma_chs[] = {
+       { .name = "rx", .dma_req = 33 },
+       { .name = "tx", .dma_req = 32 },
+};
+
+static struct omap_hwmod_addr_space omap2430_mcbsp2_addrs[] = {
+       {
+               .pa_start       = 0x48076000,
+               .pa_end         = 0x480760ff,
+               .flags          = ADDR_TYPE_RT
+       },
+};
+
+/* l4_core ->  mcbsp2 */
+static struct omap_hwmod_ocp_if omap2430_l4_core__mcbsp2 = {
+       .master         =&omap2430_l4_core_hwmod,
+       .slave          =&omap2430_mcbsp2_hwmod,
+       .clk            = "mcbsp2_ick",
+       .addr           = omap2430_mcbsp2_addrs,
+       .addr_cnt       = ARRAY_SIZE(omap2430_mcbsp2_addrs),
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mcbsp2 slave ports */
+static struct omap_hwmod_ocp_if *omap2430_mcbsp2_slaves[] = {
+&omap2430_l4_core__mcbsp2,
+};
+
+static struct omap_hwmod omap2430_mcbsp2_hwmod = {
+       .name           = "mcbsp2",
+       .class          =&omap2430_mcbsp_hwmod_class,
+       .mpu_irqs       = omap2430_mcbsp2_irqs,
+       .mpu_irqs_cnt   = ARRAY_SIZE(omap2430_mcbsp2_irqs),
+       .sdma_reqs      = omap2430_mcbsp2_sdma_chs,
+       .sdma_reqs_cnt  = ARRAY_SIZE(omap2430_mcbsp2_sdma_chs),
+       .main_clk       = "mcbsp2_fck",
+       .prcm           = {
+               .omap2 = {
+                       .prcm_reg_id = 1,
+                       .module_bit = OMAP24XX_EN_MCBSP2_SHIFT,
+                       .module_offs = CORE_MOD,
+                       .idlest_reg_id = 1,
+                       .idlest_idle_bit = OMAP24XX_EN_MCBSP2_SHIFT,
+               },
+       },
+       .slaves         = omap2430_mcbsp2_slaves,
+       .slaves_cnt     = ARRAY_SIZE(omap2430_mcbsp2_slaves),
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* mcbsp3 */
+static struct omap_hwmod_irq_info omap2430_mcbsp3_irqs[] = {
+       { .name = "tx",         .irq = 89 },
+       { .name = "rx",         .irq = 90 },
+       { .name = "common",     .irq = 17 },
+};
+
+static struct omap_hwmod_dma_info omap2430_mcbsp3_sdma_chs[] = {
+       { .name = "rx", .dma_req = 17 },
+       { .name = "tx", .dma_req = 16 },
+};
+
+static struct omap_hwmod_addr_space omap2430_mcbsp3_addrs[] = {
+       {
+               .pa_start       = 0x4808C000,
+               .pa_end         = 0x4808C0ff,
+               .flags          = ADDR_TYPE_RT
+       },
+};
+
+/* l4_core ->  mcbsp3 */
+static struct omap_hwmod_ocp_if omap2430_l4_core__mcbsp3 = {
+       .master         =&omap2430_l4_core_hwmod,
+       .slave          =&omap2430_mcbsp3_hwmod,
+       .clk            = "mcbsp3_ick",
+       .addr           = omap2430_mcbsp3_addrs,
+       .addr_cnt       = ARRAY_SIZE(omap2430_mcbsp3_addrs),
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mcbsp3 slave ports */
+static struct omap_hwmod_ocp_if *omap2430_mcbsp3_slaves[] = {
+&omap2430_l4_core__mcbsp3,
+};
+
+static struct omap_hwmod omap2430_mcbsp3_hwmod = {
+       .name           = "mcbsp3",
+       .class          =&omap2430_mcbsp_hwmod_class,
+       .mpu_irqs       = omap2430_mcbsp3_irqs,
+       .mpu_irqs_cnt   = ARRAY_SIZE(omap2430_mcbsp3_irqs),
+       .sdma_reqs      = omap2430_mcbsp3_sdma_chs,
+       .sdma_reqs_cnt  = ARRAY_SIZE(omap2430_mcbsp3_sdma_chs),
+       .main_clk       = "mcbsp3_fck",
+       .prcm           = {
+               .omap2 = {
+                       .prcm_reg_id = 1,
+                       .module_bit = OMAP2430_EN_MCBSP3_SHIFT,
+                       .module_offs = CORE_MOD,
+                       .idlest_reg_id = 2,
+                       .idlest_idle_bit = OMAP2430_ST_MCBSP3_SHIFT,
+               },
+       },
+       .slaves         = omap2430_mcbsp3_slaves,
+       .slaves_cnt     = ARRAY_SIZE(omap2430_mcbsp3_slaves),
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* mcbsp4 */
+static struct omap_hwmod_irq_info omap2430_mcbsp4_irqs[] = {
+       { .name = "tx",         .irq = 54 },
+       { .name = "rx",         .irq = 55 },
+       { .name = "common",     .irq = 18 },
+};
+
+static struct omap_hwmod_dma_info omap2430_mcbsp4_sdma_chs[] = {
+       { .name = "rx", .dma_req = 19 },
+       { .name = "tx", .dma_req = 18 },
+};
+
+static struct omap_hwmod_addr_space omap2430_mcbsp4_addrs[] = {
+       {
+               .pa_start       = 0x4808E000,
+               .pa_end         = 0x4808E0ff,
+               .flags          = ADDR_TYPE_RT
+       },
+};
+
+/* l4_core ->  mcbsp4 */
+static struct omap_hwmod_ocp_if omap2430_l4_core__mcbsp4 = {
+       .master         =&omap2430_l4_core_hwmod,
+       .slave          =&omap2430_mcbsp4_hwmod,
+       .clk            = "mcbsp4_ick",
+       .addr           = omap2430_mcbsp4_addrs,
+       .addr_cnt       = ARRAY_SIZE(omap2430_mcbsp4_addrs),
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mcbsp4 slave ports */
+static struct omap_hwmod_ocp_if *omap2430_mcbsp4_slaves[] = {
+&omap2430_l4_core__mcbsp4,
+};
+
+static struct omap_hwmod omap2430_mcbsp4_hwmod = {
+       .name           = "mcbsp4",
+       .class          =&omap2430_mcbsp_hwmod_class,
+       .mpu_irqs       = omap2430_mcbsp4_irqs,
+       .mpu_irqs_cnt   = ARRAY_SIZE(omap2430_mcbsp4_irqs),
+       .sdma_reqs      = omap2430_mcbsp4_sdma_chs,
+       .sdma_reqs_cnt  = ARRAY_SIZE(omap2430_mcbsp4_sdma_chs),
+       .main_clk       = "mcbsp4_fck",
+       .prcm           = {
+               .omap2 = {
+                       .prcm_reg_id = 1,
+                       .module_bit = OMAP2430_EN_MCBSP4_SHIFT,
+                       .module_offs = CORE_MOD,
+                       .idlest_reg_id = 2,
+                       .idlest_idle_bit = OMAP2430_ST_MCBSP4_SHIFT,
+               },
+       },
+       .slaves         = omap2430_mcbsp4_slaves,
+       .slaves_cnt     = ARRAY_SIZE(omap2430_mcbsp4_slaves),
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* mcbsp5 */
+static struct omap_hwmod_irq_info omap2430_mcbsp5_irqs[] = {
+       { .name = "tx",         .irq = 81 },
+       { .name = "rx",         .irq = 82 },
+       { .name = "common",     .irq = 19 },
+};
+
+static struct omap_hwmod_dma_info omap2430_mcbsp5_sdma_chs[] = {
+       { .name = "rx", .dma_req = 21 },
+       { .name = "tx", .dma_req = 20 },
+};
+
+static struct omap_hwmod_addr_space omap2430_mcbsp5_addrs[] = {
+       {
+               .pa_start       = 0x48096000,
+               .pa_end         = 0x480960ff,
+               .flags          = ADDR_TYPE_RT
+       },
+};
+
+/* l4_core ->  mcbsp5 */
+static struct omap_hwmod_ocp_if omap2430_l4_core__mcbsp5 = {
+       .master         =&omap2430_l4_core_hwmod,
+       .slave          =&omap2430_mcbsp5_hwmod,
+       .clk            = "mcbsp5_ick",
+       .addr           = omap2430_mcbsp5_addrs,
+       .addr_cnt       = ARRAY_SIZE(omap2430_mcbsp5_addrs),
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mcbsp5 slave ports */
+static struct omap_hwmod_ocp_if *omap2430_mcbsp5_slaves[] = {
+&omap2430_l4_core__mcbsp5,
+};
+
+static struct omap_hwmod omap2430_mcbsp5_hwmod = {
+       .name           = "mcbsp5",
+       .class          =&omap2430_mcbsp_hwmod_class,
+       .mpu_irqs       = omap2430_mcbsp5_irqs,
+       .mpu_irqs_cnt   = ARRAY_SIZE(omap2430_mcbsp5_irqs),
+       .sdma_reqs      = omap2430_mcbsp5_sdma_chs,
+       .sdma_reqs_cnt  = ARRAY_SIZE(omap2430_mcbsp5_sdma_chs),
+       .main_clk       = "mcbsp5_fck",
+       .prcm           = {
+               .omap2 = {
+                       .prcm_reg_id = 1,
+                       .module_bit = OMAP2430_EN_MCBSP5_SHIFT,
+                       .module_offs = CORE_MOD,
+                       .idlest_reg_id = 2,
+                       .idlest_idle_bit = OMAP2430_ST_MCBSP5_SHIFT,
+               },
+       },
+       .slaves         = omap2430_mcbsp5_slaves,
+       .slaves_cnt     = ARRAY_SIZE(omap2430_mcbsp5_slaves),
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
  static __initdata struct omap_hwmod *omap2430_hwmods[] = {
         &omap2430_l3_main_hwmod,
         &omap2430_l4_core_hwmod,
@@ -428,6 +736,11 @@ static __initdata struct omap_hwmod *omap2430_hwmods[] = {
         &omap2430_uart1_hwmod,
         &omap2430_uart2_hwmod,
         &omap2430_uart3_hwmod,
+&omap2430_mcbsp1_hwmod,
+&omap2430_mcbsp2_hwmod,
+&omap2430_mcbsp3_hwmod,
+&omap2430_mcbsp4_hwmod,
+&omap2430_mcbsp5_hwmod,
         NULL,
  };
 
--

1.7.0.4