Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e60a8fe1 authored by Tony Lindgren's avatar Tony Lindgren
Browse files

Merge tag 'for-v4.1-rc/omap-fixes-a' of...

Merge tag 'for-v4.1-rc/omap-fixes-a' of git://git.kernel.org/pub/scm/linux/kernel/git/pjw/omap-pending into omap-for-v4.1/fixes

ARM: OMAP2+: first set of hwmod fixes for v4.1-rc

Fix a few AM43xx problems: add the VPFE hwmod data, which removes some
warnings; and fix the IP block hardreset implementation.

Basic build, boot, and PM test results are here:

http://www.pwsan.com/omap/testlogs/omap-hwmod-a-for-v4.1-rc/20150508130543/

Note that I do not have an AM43xx board in the testbed, and thus
cannot test on that platform.
parents b0897972 a5bf00cd
Loading
Loading
Loading
Loading
+14 −54
Original line number Original line Diff line number Diff line
@@ -171,6 +171,12 @@
 */
 */
#define LINKS_PER_OCP_IF		2
#define LINKS_PER_OCP_IF		2


/*
 * Address offset (in bytes) between the reset control and the reset
 * status registers: 4 bytes on OMAP4
 */
#define OMAP4_RST_CTRL_ST_OFFSET	4

/**
/**
 * struct omap_hwmod_soc_ops - fn ptrs for some SoC-specific operations
 * struct omap_hwmod_soc_ops - fn ptrs for some SoC-specific operations
 * @enable_module: function to enable a module (via MODULEMODE)
 * @enable_module: function to enable a module (via MODULEMODE)
@@ -3016,10 +3022,12 @@ static int _omap4_deassert_hardreset(struct omap_hwmod *oh,
	if (ohri->st_shift)
	if (ohri->st_shift)
		pr_err("omap_hwmod: %s: %s: hwmod data error: OMAP4 does not support st_shift\n",
		pr_err("omap_hwmod: %s: %s: hwmod data error: OMAP4 does not support st_shift\n",
		       oh->name, ohri->name);
		       oh->name, ohri->name);
	return omap_prm_deassert_hardreset(ohri->rst_shift, 0,
	return omap_prm_deassert_hardreset(ohri->rst_shift, ohri->rst_shift,
					   oh->clkdm->pwrdm.ptr->prcm_partition,
					   oh->clkdm->pwrdm.ptr->prcm_partition,
					   oh->clkdm->pwrdm.ptr->prcm_offs,
					   oh->clkdm->pwrdm.ptr->prcm_offs,
					   oh->prcm.omap4.rstctrl_offs, 0);
					   oh->prcm.omap4.rstctrl_offs,
					   oh->prcm.omap4.rstctrl_offs +
					   OMAP4_RST_CTRL_ST_OFFSET);
}
}


/**
/**
@@ -3047,27 +3055,6 @@ static int _omap4_is_hardreset_asserted(struct omap_hwmod *oh,
					      oh->prcm.omap4.rstctrl_offs);
					      oh->prcm.omap4.rstctrl_offs);
}
}


/**
 * _am33xx_assert_hardreset - call AM33XX PRM hardreset fn with hwmod args
 * @oh: struct omap_hwmod * to assert hardreset
 * @ohri: hardreset line data
 *
 * Call am33xx_prminst_assert_hardreset() with parameters extracted
 * from the hwmod @oh and the hardreset line data @ohri.  Only
 * intended for use as an soc_ops function pointer.  Passes along the
 * return value from am33xx_prminst_assert_hardreset().  XXX This
 * function is scheduled for removal when the PRM code is moved into
 * drivers/.
 */
static int _am33xx_assert_hardreset(struct omap_hwmod *oh,
				   struct omap_hwmod_rst_info *ohri)

{
	return omap_prm_assert_hardreset(ohri->rst_shift, 0,
					 oh->clkdm->pwrdm.ptr->prcm_offs,
					 oh->prcm.omap4.rstctrl_offs);
}

/**
/**
 * _am33xx_deassert_hardreset - call AM33XX PRM hardreset fn with hwmod args
 * _am33xx_deassert_hardreset - call AM33XX PRM hardreset fn with hwmod args
 * @oh: struct omap_hwmod * to deassert hardreset
 * @oh: struct omap_hwmod * to deassert hardreset
@@ -3083,32 +3070,13 @@ static int _am33xx_assert_hardreset(struct omap_hwmod *oh,
static int _am33xx_deassert_hardreset(struct omap_hwmod *oh,
static int _am33xx_deassert_hardreset(struct omap_hwmod *oh,
				     struct omap_hwmod_rst_info *ohri)
				     struct omap_hwmod_rst_info *ohri)
{
{
	return omap_prm_deassert_hardreset(ohri->rst_shift, ohri->st_shift, 0,
	return omap_prm_deassert_hardreset(ohri->rst_shift, ohri->st_shift,
					   oh->clkdm->pwrdm.ptr->prcm_partition,
					   oh->clkdm->pwrdm.ptr->prcm_offs,
					   oh->clkdm->pwrdm.ptr->prcm_offs,
					   oh->prcm.omap4.rstctrl_offs,
					   oh->prcm.omap4.rstctrl_offs,
					   oh->prcm.omap4.rstst_offs);
					   oh->prcm.omap4.rstst_offs);
}
}


/**
 * _am33xx_is_hardreset_asserted - call AM33XX PRM hardreset fn with hwmod args
 * @oh: struct omap_hwmod * to test hardreset
 * @ohri: hardreset line data
 *
 * Call am33xx_prminst_is_hardreset_asserted() with parameters
 * extracted from the hwmod @oh and the hardreset line data @ohri.
 * Only intended for use as an soc_ops function pointer.  Passes along
 * the return value from am33xx_prminst_is_hardreset_asserted().  XXX
 * This function is scheduled for removal when the PRM code is moved
 * into drivers/.
 */
static int _am33xx_is_hardreset_asserted(struct omap_hwmod *oh,
					struct omap_hwmod_rst_info *ohri)
{
	return omap_prm_is_hardreset_asserted(ohri->rst_shift, 0,
					      oh->clkdm->pwrdm.ptr->prcm_offs,
					      oh->prcm.omap4.rstctrl_offs);
}

/* Public functions */
/* Public functions */


u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs)
u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs)
@@ -3908,21 +3876,13 @@ void __init omap_hwmod_init(void)
		soc_ops.init_clkdm = _init_clkdm;
		soc_ops.init_clkdm = _init_clkdm;
		soc_ops.update_context_lost = _omap4_update_context_lost;
		soc_ops.update_context_lost = _omap4_update_context_lost;
		soc_ops.get_context_lost = _omap4_get_context_lost;
		soc_ops.get_context_lost = _omap4_get_context_lost;
	} else if (soc_is_am43xx()) {
	} else if (cpu_is_ti816x() || soc_is_am33xx() || soc_is_am43xx()) {
		soc_ops.enable_module = _omap4_enable_module;
		soc_ops.enable_module = _omap4_enable_module;
		soc_ops.disable_module = _omap4_disable_module;
		soc_ops.disable_module = _omap4_disable_module;
		soc_ops.wait_target_ready = _omap4_wait_target_ready;
		soc_ops.wait_target_ready = _omap4_wait_target_ready;
		soc_ops.assert_hardreset = _omap4_assert_hardreset;
		soc_ops.assert_hardreset = _omap4_assert_hardreset;
		soc_ops.deassert_hardreset = _omap4_deassert_hardreset;
		soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted;
		soc_ops.init_clkdm = _init_clkdm;
	} else if (cpu_is_ti816x() || soc_is_am33xx()) {
		soc_ops.enable_module = _omap4_enable_module;
		soc_ops.disable_module = _omap4_disable_module;
		soc_ops.wait_target_ready = _omap4_wait_target_ready;
		soc_ops.assert_hardreset = _am33xx_assert_hardreset;
		soc_ops.deassert_hardreset = _am33xx_deassert_hardreset;
		soc_ops.deassert_hardreset = _am33xx_deassert_hardreset;
		soc_ops.is_hardreset_asserted = _am33xx_is_hardreset_asserted;
		soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted;
		soc_ops.init_clkdm = _init_clkdm;
		soc_ops.init_clkdm = _init_clkdm;
	} else {
	} else {
		WARN(1, "omap_hwmod: unknown SoC type\n");
		WARN(1, "omap_hwmod: unknown SoC type\n");
+70 −0
Original line number Original line Diff line number Diff line
@@ -544,6 +544,44 @@ static struct omap_hwmod am43xx_hdq1w_hwmod = {
	},
	},
};
};


static struct omap_hwmod_class_sysconfig am43xx_vpfe_sysc = {
	.rev_offs       = 0x0,
	.sysc_offs      = 0x104,
	.sysc_flags     = SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE,
	.idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
				MSTANDBY_FORCE | MSTANDBY_SMART | MSTANDBY_NO),
	.sysc_fields    = &omap_hwmod_sysc_type2,
};

static struct omap_hwmod_class am43xx_vpfe_hwmod_class = {
	.name           = "vpfe",
	.sysc           = &am43xx_vpfe_sysc,
};

static struct omap_hwmod am43xx_vpfe0_hwmod = {
	.name           = "vpfe0",
	.class          = &am43xx_vpfe_hwmod_class,
	.clkdm_name     = "l3s_clkdm",
	.prcm           = {
		.omap4  = {
			.modulemode     = MODULEMODE_SWCTRL,
			.clkctrl_offs   = AM43XX_CM_PER_VPFE0_CLKCTRL_OFFSET,
		},
	},
};

static struct omap_hwmod am43xx_vpfe1_hwmod = {
	.name           = "vpfe1",
	.class          = &am43xx_vpfe_hwmod_class,
	.clkdm_name     = "l3s_clkdm",
	.prcm           = {
		.omap4  = {
			.modulemode     = MODULEMODE_SWCTRL,
			.clkctrl_offs   = AM43XX_CM_PER_VPFE1_CLKCTRL_OFFSET,
		},
	},
};

/* Interfaces */
/* Interfaces */
static struct omap_hwmod_ocp_if am43xx_l3_main__l4_hs = {
static struct omap_hwmod_ocp_if am43xx_l3_main__l4_hs = {
	.master		= &am33xx_l3_main_hwmod,
	.master		= &am33xx_l3_main_hwmod,
@@ -825,6 +863,34 @@ static struct omap_hwmod_ocp_if am43xx_l4_ls__hdq1w = {
	.user           = OCP_USER_MPU | OCP_USER_SDMA,
	.user           = OCP_USER_MPU | OCP_USER_SDMA,
};
};


static struct omap_hwmod_ocp_if am43xx_l3__vpfe0 = {
	.master         = &am43xx_vpfe0_hwmod,
	.slave          = &am33xx_l3_main_hwmod,
	.clk            = "l3_gclk",
	.user           = OCP_USER_MPU | OCP_USER_SDMA,
};

static struct omap_hwmod_ocp_if am43xx_l3__vpfe1 = {
	.master         = &am43xx_vpfe1_hwmod,
	.slave          = &am33xx_l3_main_hwmod,
	.clk            = "l3_gclk",
	.user           = OCP_USER_MPU | OCP_USER_SDMA,
};

static struct omap_hwmod_ocp_if am43xx_l4_ls__vpfe0 = {
	.master         = &am33xx_l4_ls_hwmod,
	.slave          = &am43xx_vpfe0_hwmod,
	.clk            = "l4ls_gclk",
	.user           = OCP_USER_MPU | OCP_USER_SDMA,
};

static struct omap_hwmod_ocp_if am43xx_l4_ls__vpfe1 = {
	.master         = &am33xx_l4_ls_hwmod,
	.slave          = &am43xx_vpfe1_hwmod,
	.clk            = "l4ls_gclk",
	.user           = OCP_USER_MPU | OCP_USER_SDMA,
};

static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = {
static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = {
	&am33xx_l4_wkup__synctimer,
	&am33xx_l4_wkup__synctimer,
	&am43xx_l4_ls__timer8,
	&am43xx_l4_ls__timer8,
@@ -925,6 +991,10 @@ static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = {
	&am43xx_l4_ls__dss_dispc,
	&am43xx_l4_ls__dss_dispc,
	&am43xx_l4_ls__dss_rfbi,
	&am43xx_l4_ls__dss_rfbi,
	&am43xx_l4_ls__hdq1w,
	&am43xx_l4_ls__hdq1w,
	&am43xx_l3__vpfe0,
	&am43xx_l3__vpfe1,
	&am43xx_l4_ls__vpfe0,
	&am43xx_l4_ls__vpfe1,
	NULL,
	NULL,
};
};


+2 −1
Original line number Original line Diff line number Diff line
@@ -144,5 +144,6 @@
#define AM43XX_CM_PER_USBPHYOCP2SCP1_CLKCTRL_OFFSET	0x05C0
#define AM43XX_CM_PER_USBPHYOCP2SCP1_CLKCTRL_OFFSET	0x05C0
#define AM43XX_CM_PER_DSS_CLKCTRL_OFFSET		0x0a20
#define AM43XX_CM_PER_DSS_CLKCTRL_OFFSET		0x0a20
#define AM43XX_CM_PER_HDQ1W_CLKCTRL_OFFSET		0x04a0
#define AM43XX_CM_PER_HDQ1W_CLKCTRL_OFFSET		0x04a0

#define AM43XX_CM_PER_VPFE0_CLKCTRL_OFFSET		0x0068
#define AM43XX_CM_PER_VPFE1_CLKCTRL_OFFSET		0x0070
#endif
#endif
+7 −13
Original line number Original line Diff line number Diff line
@@ -87,12 +87,6 @@ u32 omap4_prminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, s16 inst,
	return v;
	return v;
}
}


/*
 * Address offset (in bytes) between the reset control and the reset
 * status registers: 4 bytes on OMAP4
 */
#define OMAP4_RST_CTRL_ST_OFFSET		4

/**
/**
 * omap4_prminst_is_hardreset_asserted - read the HW reset line state of
 * omap4_prminst_is_hardreset_asserted - read the HW reset line state of
 * submodules contained in the hwmod module
 * submodules contained in the hwmod module
@@ -141,11 +135,11 @@ int omap4_prminst_assert_hardreset(u8 shift, u8 part, s16 inst,
 * omap4_prminst_deassert_hardreset - deassert a submodule hardreset line and
 * omap4_prminst_deassert_hardreset - deassert a submodule hardreset line and
 * wait
 * wait
 * @shift: register bit shift corresponding to the reset line to deassert
 * @shift: register bit shift corresponding to the reset line to deassert
 * @st_shift: status bit offset, not used for OMAP4+
 * @st_shift: status bit offset corresponding to the reset line
 * @part: PRM partition
 * @part: PRM partition
 * @inst: PRM instance offset
 * @inst: PRM instance offset
 * @rstctrl_offs: reset register offset
 * @rstctrl_offs: reset register offset
 * @st_offs: reset status register offset, not used for OMAP4+
 * @rstst_offs: reset status register offset
 *
 *
 * Some IPs like dsp, ipu or iva contain processors that require an HW
 * Some IPs like dsp, ipu or iva contain processors that require an HW
 * reset line to be asserted / deasserted in order to fully enable the
 * reset line to be asserted / deasserted in order to fully enable the
@@ -157,11 +151,11 @@ int omap4_prminst_assert_hardreset(u8 shift, u8 part, s16 inst,
 * of reset, or -EBUSY if the submodule did not exit reset promptly.
 * of reset, or -EBUSY if the submodule did not exit reset promptly.
 */
 */
int omap4_prminst_deassert_hardreset(u8 shift, u8 st_shift, u8 part, s16 inst,
int omap4_prminst_deassert_hardreset(u8 shift, u8 st_shift, u8 part, s16 inst,
				     u16 rstctrl_offs, u16 st_offs)
				     u16 rstctrl_offs, u16 rstst_offs)
{
{
	int c;
	int c;
	u32 mask = 1 << shift;
	u32 mask = 1 << shift;
	u16 rstst_offs = rstctrl_offs + OMAP4_RST_CTRL_ST_OFFSET;
	u32 st_mask = 1 << st_shift;


	/* Check the current status to avoid de-asserting the line twice */
	/* Check the current status to avoid de-asserting the line twice */
	if (omap4_prminst_is_hardreset_asserted(shift, part, inst,
	if (omap4_prminst_is_hardreset_asserted(shift, part, inst,
@@ -169,13 +163,13 @@ int omap4_prminst_deassert_hardreset(u8 shift, u8 st_shift, u8 part, s16 inst,
		return -EEXIST;
		return -EEXIST;


	/* Clear the reset status by writing 1 to the status bit */
	/* Clear the reset status by writing 1 to the status bit */
	omap4_prminst_rmw_inst_reg_bits(0xffffffff, mask, part, inst,
	omap4_prminst_rmw_inst_reg_bits(0xffffffff, st_mask, part, inst,
					rstst_offs);
					rstst_offs);
	/* de-assert the reset control line */
	/* de-assert the reset control line */
	omap4_prminst_rmw_inst_reg_bits(mask, 0, part, inst, rstctrl_offs);
	omap4_prminst_rmw_inst_reg_bits(mask, 0, part, inst, rstctrl_offs);
	/* wait the status to be set */
	/* wait the status to be set */
	omap_test_timeout(omap4_prminst_is_hardreset_asserted(shift, part, inst,
	omap_test_timeout(omap4_prminst_is_hardreset_asserted(st_shift, part,
							      rstst_offs),
							      inst, rstst_offs),
			  MAX_MODULE_HARDRESET_WAIT, c);
			  MAX_MODULE_HARDRESET_WAIT, c);


	return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0;
	return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0;