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

Commit 8b9c1ac2 authored by Tony Lindgren's avatar Tony Lindgren
Browse files

Merge tag 'omap-devel-a-for-3.8' of...

Merge tag 'omap-devel-a-for-3.8' of git://git.kernel.org/pub/scm/linux/kernel/git/pjw/omap-pending into omap-for-v3.8/devel-pcrm

Some miscellaneous OMAP hwmod changes for 3.8, along with a PRM
change needed for one of the hwmod patches to function.

Basic test logs for this branch on top of Tony's
omap-for-v3.8/clock branch at commit
558a0780 are here:

http://www.pwsan.com/omap/testlogs/hwmod_devel_a_3.8/20121121161522/

However, omap-for-v3.8/clock at 558a0780 does not include some fixes
that are needed for a successful test.  With several reverts,
fixes, and workarounds applied, the following test logs were
obtained:

http://www.pwsan.com/omap/testlogs/TEST_hwmod_devel_a_3.8/20121121162719/

which indicate that the series tests cleanly.
parents 558a0780 c567b058
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -51,6 +51,10 @@
#include "prcm_mpu44xx.h"
#include "prminst44xx.h"
#include "cminst44xx.h"
#include "prm2xxx.h"
#include "prm3xxx.h"
#include "prm44xx.h"

/*
 * The machine specific code may provide the extra mapping besides the
 * default mapping provided here.
@@ -392,6 +396,7 @@ void __init omap2420_init_early(void)
	omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(OMAP2420_PRM_BASE));
	omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP2420_CM_BASE), NULL);
	omap2xxx_check_revision();
	omap2xxx_prm_init();
	omap2xxx_cm_init();
	omap_common_init_early();
	omap2xxx_voltagedomains_init();
@@ -422,6 +427,7 @@ void __init omap2430_init_early(void)
	omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(OMAP2430_PRM_BASE));
	omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP2430_CM_BASE), NULL);
	omap2xxx_check_revision();
	omap2xxx_prm_init();
	omap2xxx_cm_init();
	omap_common_init_early();
	omap2xxx_voltagedomains_init();
@@ -457,6 +463,7 @@ void __init omap3_init_early(void)
	omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP3430_CM_BASE), NULL);
	omap3xxx_check_revision();
	omap3xxx_check_features();
	omap3xxx_prm_init();
	omap3xxx_cm_init();
	omap_common_init_early();
	omap3xxx_voltagedomains_init();
@@ -591,6 +598,7 @@ void __init omap4430_init_early(void)
	omap_cm_base_init();
	omap4xxx_check_revision();
	omap4xxx_check_features();
	omap44xx_prm_init();
	omap_common_init_early();
	omap44xx_voltagedomains_init();
	omap44xx_powerdomains_init();
+55 −32
Original line number Diff line number Diff line
@@ -441,19 +441,21 @@ int omap_device_get_context_loss_count(struct platform_device *pdev)
/**
 * omap_device_count_resources - count number of struct resource entries needed
 * @od: struct omap_device *
 * @flags: Type of resources to include when counting (IRQ/DMA/MEM)
 *
 * Count the number of struct resource entries needed for this
 * omap_device @od.  Used by omap_device_build_ss() to determine how
 * much memory to allocate before calling
 * omap_device_fill_resources().  Returns the count.
 */
static int omap_device_count_resources(struct omap_device *od)
static int omap_device_count_resources(struct omap_device *od,
				       unsigned long flags)
{
	int c = 0;
	int i;

	for (i = 0; i < od->hwmods_cnt; i++)
		c += omap_hwmod_count_resources(od->hwmods[i]);
		c += omap_hwmod_count_resources(od->hwmods[i], flags);

	pr_debug("omap_device: %s: counted %d total resources across %d hwmods\n",
		 od->pdev->name, c, od->hwmods_cnt);
@@ -557,43 +559,64 @@ struct omap_device *omap_device_alloc(struct platform_device *pdev,
	od->hwmods = hwmods;
	od->pdev = pdev;

	res_count = omap_device_count_resources(od);
	/*
	 * Non-DT Boot:
	 *   Here, pdev->num_resources = 0, and we should get all the
	 *   resources from hwmod.
	 *
	 * DT Boot:
	 *   OF framework will construct the resource structure (currently
	 *   does for MEM & IRQ resource) and we should respect/use these
	 *   resources, killing hwmod dependency.
	 *   If pdev->num_resources > 0, we assume that MEM & IRQ resources
	 *   have been allocated by OF layer already (through DTB).
	 *
	 * Non-DT Boot:
	 *   Here, pdev->num_resources = 0, and we should get all the
	 *   resources from hwmod.
	 *   As preparation for the future we examine the OF provided resources
	 *   to see if we have DMA resources provided already. In this case
	 *   there is no need to update the resources for the device, we use the
	 *   OF provided ones.
	 *
	 * TODO: Once DMA resource is available from OF layer, we should
	 *   kill filling any resources from hwmod.
	 */
	if (res_count > pdev->num_resources) {
	if (!pdev->num_resources) {
		/* Count all resources for the device */
		res_count = omap_device_count_resources(od, IORESOURCE_IRQ |
							    IORESOURCE_DMA |
							    IORESOURCE_MEM);
	} else {
		/* Take a look if we already have DMA resource via DT */
		for (i = 0; i < pdev->num_resources; i++) {
			struct resource *r = &pdev->resource[i];

			/* We have it, no need to touch the resources */
			if (r->flags == IORESOURCE_DMA)
				goto have_everything;
		}
		/* Count only DMA resources for the device */
		res_count = omap_device_count_resources(od, IORESOURCE_DMA);
		/* The device has no DMA resource, no need for update */
		if (!res_count)
			goto have_everything;

		res_count += pdev->num_resources;
	}

	/* Allocate resources memory to account for new resources */
	res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL);
	if (!res)
		goto oda_exit3;

		/*
		 * If pdev->num_resources > 0, then assume that,
		 * MEM and IRQ resources will only come from DT and only
		 * fill DMA resource from hwmod layer.
		 */
		if (pdev->num_resources && pdev->resource) {
			dev_dbg(&pdev->dev, "%s(): resources already allocated %d\n",
	if (!pdev->num_resources) {
		dev_dbg(&pdev->dev, "%s: using %d resources from hwmod\n",
			__func__, res_count);
		omap_device_fill_resources(od, res);
	} else {
		dev_dbg(&pdev->dev,
			"%s: appending %d DMA resources from hwmod\n",
			__func__, res_count - pdev->num_resources);
		memcpy(res, pdev->resource,
		       sizeof(struct resource) * pdev->num_resources);
		_od_fill_dma_resources(od, &res[pdev->num_resources]);
		} else {
			dev_dbg(&pdev->dev, "%s(): using resources from hwmod %d\n",
				__func__, res_count);
			omap_device_fill_resources(od, res);
	}

	ret = platform_device_add_resources(pdev, res, res_count);
@@ -601,8 +624,8 @@ struct omap_device *omap_device_alloc(struct platform_device *pdev,

	if (ret)
		goto oda_exit3;
	}

have_everything:
	if (!pm_lats) {
		pm_lats = omap_default_latency;
		pm_lats_cnt = ARRAY_SIZE(omap_default_latency);
+67 −15
Original line number Diff line number Diff line
@@ -187,6 +187,8 @@ struct omap_hwmod_soc_ops {
	int (*is_hardreset_asserted)(struct omap_hwmod *oh,
				     struct omap_hwmod_rst_info *ohri);
	int (*init_clkdm)(struct omap_hwmod *oh);
	void (*update_context_lost)(struct omap_hwmod *oh);
	int (*get_context_lost)(struct omap_hwmod *oh);
};

/* soc_ops: adapts the omap_hwmod code to the currently-booted SoC */
@@ -1982,6 +1984,42 @@ static void _reconfigure_io_chain(void)
	spin_unlock_irqrestore(&io_chain_lock, flags);
}

/**
 * _omap4_update_context_lost - increment hwmod context loss counter if
 * hwmod context was lost, and clear hardware context loss reg
 * @oh: hwmod to check for context loss
 *
 * If the PRCM indicates that the hwmod @oh lost context, increment
 * our in-memory context loss counter, and clear the RM_*_CONTEXT
 * bits. No return value.
 */
static void _omap4_update_context_lost(struct omap_hwmod *oh)
{
	if (oh->prcm.omap4.flags & HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT)
		return;

	if (!prm_was_any_context_lost_old(oh->clkdm->pwrdm.ptr->prcm_partition,
					  oh->clkdm->pwrdm.ptr->prcm_offs,
					  oh->prcm.omap4.context_offs))
		return;

	oh->prcm.omap4.context_lost_counter++;
	prm_clear_context_loss_flags_old(oh->clkdm->pwrdm.ptr->prcm_partition,
					 oh->clkdm->pwrdm.ptr->prcm_offs,
					 oh->prcm.omap4.context_offs);
}

/**
 * _omap4_get_context_lost - get context loss counter for a hwmod
 * @oh: hwmod to get context loss counter for
 *
 * Returns the in-memory context loss counter for a hwmod.
 */
static int _omap4_get_context_lost(struct omap_hwmod *oh)
{
	return oh->prcm.omap4.context_lost_counter;
}

/**
 * _enable - enable an omap_hwmod
 * @oh: struct omap_hwmod *
@@ -2065,6 +2103,9 @@ static int _enable(struct omap_hwmod *oh)
	if (soc_ops.enable_module)
		soc_ops.enable_module(oh);

	if (soc_ops.update_context_lost)
		soc_ops.update_context_lost(oh);

	r = (soc_ops.wait_target_ready) ? soc_ops.wait_target_ready(oh) :
		-EINVAL;
	if (!r) {
@@ -3386,7 +3427,7 @@ int omap_hwmod_reset(struct omap_hwmod *oh)
/**
 * omap_hwmod_count_resources - count number of struct resources needed by hwmod
 * @oh: struct omap_hwmod *
 * @res: pointer to the first element of an array of struct resource to fill
 * @flags: Type of resources to include when counting (IRQ/DMA/MEM)
 *
 * Count the number of struct resource array elements necessary to
 * contain omap_hwmod @oh resources.  Intended to be called by code
@@ -3399,21 +3440,26 @@ int omap_hwmod_reset(struct omap_hwmod *oh)
 * resource IDs.
 *
 */
int omap_hwmod_count_resources(struct omap_hwmod *oh)
int omap_hwmod_count_resources(struct omap_hwmod *oh, unsigned long flags)
{
	struct omap_hwmod_ocp_if *os;
	struct list_head *p;
	int ret;
	int i = 0;
	int ret = 0;

	ret = _count_mpu_irqs(oh) + _count_sdma_reqs(oh);
	if (flags & IORESOURCE_IRQ)
		ret += _count_mpu_irqs(oh);

	p = oh->slave_ports.next;
	if (flags & IORESOURCE_DMA)
		ret += _count_sdma_reqs(oh);

	if (flags & IORESOURCE_MEM) {
		int i = 0;
		struct omap_hwmod_ocp_if *os;
		struct list_head *p = oh->slave_ports.next;

		while (i < oh->slaves_cnt) {
			os = _fetch_next_ocp_if(&p, &i);
			ret += _count_ocp_if_addr_spaces(os);
		}
	}

	return ret;
}
@@ -3907,17 +3953,21 @@ int omap_hwmod_set_postsetup_state(struct omap_hwmod *oh, u8 state)
 * omap_hwmod_get_context_loss_count - get lost context count
 * @oh: struct omap_hwmod *
 *
 * Query the powerdomain of of @oh to get the context loss
 * count for this device.
 * Returns the context loss count of associated @oh
 * upon success, or zero if no context loss data is available.
 *
 * Returns the context loss count of the powerdomain assocated with @oh
 * upon success, or zero if no powerdomain exists for @oh.
 * On OMAP4, this queries the per-hwmod context loss register,
 * assuming one exists.  If not, or on OMAP2/3, this queries the
 * enclosing powerdomain context loss count.
 */
int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh)
{
	struct powerdomain *pwrdm;
	int ret = 0;

	if (soc_ops.get_context_lost)
		return soc_ops.get_context_lost(oh);

	pwrdm = omap_hwmod_get_pwrdm(oh);
	if (pwrdm)
		ret = pwrdm_get_context_loss_count(pwrdm);
@@ -4032,6 +4082,8 @@ void __init omap_hwmod_init(void)
		soc_ops.deassert_hardreset = _omap4_deassert_hardreset;
		soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted;
		soc_ops.init_clkdm = _init_clkdm;
		soc_ops.update_context_lost = _omap4_update_context_lost;
		soc_ops.get_context_lost = _omap4_get_context_lost;
	} else if (soc_is_am33xx()) {
		soc_ops.enable_module = _am33xx_enable_module;
		soc_ops.disable_module = _am33xx_disable_module;
+8 −4
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
 * omap_hwmod macros, structures
 *
 * Copyright (C) 2009-2011 Nokia Corporation
 * Copyright (C) 2012 Texas Instruments, Inc.
 * Copyright (C) 2011-2012 Texas Instruments, Inc.
 * Paul Walmsley
 *
 * Created in collaboration with (alphabetical order): Benoît Cousson,
@@ -394,12 +394,15 @@ struct omap_hwmod_omap2_prcm {

/**
 * struct omap_hwmod_omap4_prcm - OMAP4-specific PRCM data
 * @clkctrl_reg: PRCM address of the clock control register
 * @rstctrl_reg: address of the XXX_RSTCTRL register located in the PRM
 * @clkctrl_offs: offset of the PRCM clock control register
 * @rstctrl_offs: offset of the XXX_RSTCTRL register located in the PRM
 * @context_offs: offset of the RM_*_CONTEXT register
 * @lostcontext_mask: bitmask for selecting bits from RM_*_CONTEXT register
 * @rstst_reg: (AM33XX only) address of the XXX_RSTST register in the PRM
 * @submodule_wkdep_bit: bit shift of the WKDEP range
 * @flags: PRCM register capabilities for this IP block
 * @modulemode: allowable modulemodes
 * @context_lost_counter: Count of module level context lost
 *
 * If @lostcontext_mask is not defined, context loss check code uses
 * whole register without masking. @lostcontext_mask should only be
@@ -415,6 +418,7 @@ struct omap_hwmod_omap4_prcm {
	u8		submodule_wkdep_bit;
	u8		modulemode;
	u8		flags;
	int		context_lost_counter;
};


@@ -627,7 +631,7 @@ void omap_hwmod_write(u32 v, struct omap_hwmod *oh, u16 reg_offs);
u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs);
int omap_hwmod_softreset(struct omap_hwmod *oh);

int omap_hwmod_count_resources(struct omap_hwmod *oh);
int omap_hwmod_count_resources(struct omap_hwmod *oh, unsigned long flags);
int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res);
int omap_hwmod_fill_dma_resources(struct omap_hwmod *oh, struct resource *res);
int omap_hwmod_get_resource_byname(struct omap_hwmod *oh, unsigned int type,
+10 −1
Original line number Diff line number Diff line
@@ -114,16 +114,25 @@ struct prm_reset_src_map {

/**
 * struct prm_ll_data - fn ptrs to per-SoC PRM function implementations
 * @read_reset_sources: ptr to the Soc PRM-specific get_reset_source impl
 * @read_reset_sources: ptr to the SoC PRM-specific get_reset_source impl
 * @was_any_context_lost_old: ptr to the SoC PRM context loss test fn
 * @clear_context_loss_flags_old: ptr to the SoC PRM context loss flag clear fn
 *
 * XXX @was_any_context_lost_old and @clear_context_loss_flags_old are
 * deprecated.
 */
struct prm_ll_data {
	u32 (*read_reset_sources)(void);
	bool (*was_any_context_lost_old)(u8 part, s16 inst, u16 idx);
	void (*clear_context_loss_flags_old)(u8 part, s16 inst, u16 idx);
};

extern int prm_register(struct prm_ll_data *pld);
extern int prm_unregister(struct prm_ll_data *pld);

extern u32 prm_read_reset_sources(void);
extern bool prm_was_any_context_lost_old(u8 part, s16 inst, u16 idx);
extern void prm_clear_context_loss_flags_old(u8 part, s16 inst, u16 idx);

#endif

Loading