diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-12 11:51:39 -0800 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-12 11:51:39 -0800 | 
| commit | d01e4afdbb65e030fd6f1f96c30a558e2eb0f279 (patch) | |
| tree | 02ef82b2740cf93a98199eded5ef765fa6e03052 /arch/arm/plat-omap/include/plat/dmtimer.h | |
| parent | 8287361abca36504da813638310d2547469283eb (diff) | |
| parent | 794b175fc0c0c4844dbb7b137a73bbfd01f6c608 (diff) | |
| download | olio-linux-3.10-d01e4afdbb65e030fd6f1f96c30a558e2eb0f279.tar.xz olio-linux-3.10-d01e4afdbb65e030fd6f1f96c30a558e2eb0f279.zip  | |
Merge tag 'cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC cleanups on various subarchitectures from Olof Johansson:
 "Cleanup patches for various ARM platforms and some of their associated
  drivers.  There's also a branch in here that enables Freescale i.MX to
  be part of the multiplatform support -- the first "big" SoC that is
  moved over (more multiplatform work comes in a separate branch later
  during the merge window)."
Conflicts fixed as per Olof, including a silent semantic one in
arch/arm/mach-omap2/board-generic.c (omap_prcm_restart() was renamed to
omap3xxx_restart(), and a new user of the old name was added).
* tag 'cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (189 commits)
  ARM: omap: fix typo on timer cleanup
  ARM: EXYNOS: Remove unused regs-mem.h file
  ARM: EXYNOS: Remove unused non-dt support for dwmci controller
  ARM: Kirkwood: Use hw_pci.ops instead of hw_pci.scan
  ARM: OMAP3: cm-t3517: use GPTIMER for system clock
  ARM: OMAP2+: timer: remove CONFIG_OMAP_32K_TIMER
  ARM: SAMSUNG: use devm_ functions for ADC driver
  ARM: EXYNOS: no duplicate mask/unmask in eint0_15
  ARM: S3C24XX: SPI clock channel setup is fixed for S3C2443
  ARM: EXYNOS: Remove i2c0 resource information and setting of device names
  ARM: Kirkwood: checkpatch cleanups
  ARM: Kirkwood: Fix sparse warnings.
  ARM: Kirkwood: Remove unused includes
  ARM: kirkwood: cleanup lsxl board includes
  ARM: integrator: use BUG_ON where possible
  ARM: integrator: push down SC dependencies
  ARM: integrator: delete static UART1 mapping
  ARM: integrator: delete SC mapping on the CP
  ARM: integrator: remove static CP syscon mapping
  ARM: integrator: remove static AP syscon mapping
  ...
Diffstat (limited to 'arch/arm/plat-omap/include/plat/dmtimer.h')
| -rw-r--r-- | arch/arm/plat-omap/include/plat/dmtimer.h | 143 | 
1 files changed, 70 insertions, 73 deletions
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h index 3f5b9cfd9c0..a3fbc48c332 100644 --- a/arch/arm/plat-omap/include/plat/dmtimer.h +++ b/arch/arm/plat-omap/include/plat/dmtimer.h @@ -32,7 +32,6 @@   * 675 Mass Ave, Cambridge, MA 02139, USA.   */ -#include <linux/clk.h>  #include <linux/delay.h>  #include <linux/io.h>  #include <linux/platform_device.h> @@ -55,6 +54,10 @@  #define OMAP_TIMER_TRIGGER_OVERFLOW		0x01  #define OMAP_TIMER_TRIGGER_OVERFLOW_AND_COMPARE	0x02 +/* posted mode types */ +#define OMAP_TIMER_NONPOSTED			0x00 +#define OMAP_TIMER_POSTED			0x01 +  /* timer capabilities used in hwmod database */  #define OMAP_TIMER_SECURE				0x80000000  #define OMAP_TIMER_ALWON				0x40000000 @@ -62,16 +65,22 @@  #define OMAP_TIMER_NEEDS_RESET				0x10000000  #define OMAP_TIMER_HAS_DSP_IRQ				0x08000000 +/* + * timer errata flags + * + * Errata i103/i767 impacts all OMAP3/4/5 devices including AM33xx. This + * errata prevents us from using posted mode on these devices, unless the + * timer counter register is never read. For more details please refer to + * the OMAP3/4/5 errata documents. + */ +#define OMAP_TIMER_ERRATA_I103_I767			0x80000000 +  struct omap_timer_capability_dev_attr {  	u32 timer_capability;  }; -struct omap_dm_timer; -  struct timer_regs {  	u32 tidr; -	u32 tistat; -	u32 tisr;  	u32 tier;  	u32 twer;  	u32 tclr; @@ -90,16 +99,35 @@ struct timer_regs {  	u32 towr;  }; -struct dmtimer_platform_data { -	/* set_timer_src - Only used for OMAP1 devices */ -	int (*set_timer_src)(struct platform_device *pdev, int source); -	u32 timer_capability; +struct omap_dm_timer { +	int id; +	int irq; +	struct clk *fclk; + +	void __iomem	*io_base; +	void __iomem	*irq_stat;	/* TISR/IRQSTATUS interrupt status */ +	void __iomem	*irq_ena;	/* irq enable */ +	void __iomem	*irq_dis;	/* irq disable, only on v2 ip */ +	void __iomem	*pend;		/* write pending */ +	void __iomem	*func_base;	/* function register base */ + +	unsigned long rate; +	unsigned reserved:1; +	unsigned posted:1; +	struct timer_regs context;  	int (*get_context_loss_count)(struct device *); +	int ctx_loss_count; +	int revision; +	u32 capability; +	u32 errata; +	struct platform_device *pdev; +	struct list_head node;  };  int omap_dm_timer_reserve_systimer(int id);  struct omap_dm_timer *omap_dm_timer_request(void);  struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id); +struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap);  int omap_dm_timer_free(struct omap_dm_timer *timer);  void omap_dm_timer_enable(struct omap_dm_timer *timer);  void omap_dm_timer_disable(struct omap_dm_timer *timer); @@ -121,6 +149,7 @@ int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on, int toggle, i  int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler);  int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, unsigned int value); +int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask);  unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer);  int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value); @@ -246,34 +275,6 @@ int omap_dm_timers_active(void);  #define OMAP_TIMER_TICK_INT_MASK_COUNT_REG				\  		(_OMAP_TIMER_TICK_INT_MASK_COUNT_OFFSET | (WP_TOWR << WPSHIFT)) -struct omap_dm_timer { -	unsigned long phys_base; -	int id; -	int irq; -	struct clk *fclk; - -	void __iomem	*io_base; -	void __iomem	*sys_stat;	/* TISTAT timer status */ -	void __iomem	*irq_stat;	/* TISR/IRQSTATUS interrupt status */ -	void __iomem	*irq_ena;	/* irq enable */ -	void __iomem	*irq_dis;	/* irq disable, only on v2 ip */ -	void __iomem	*pend;		/* write pending */ -	void __iomem	*func_base;	/* function register base */ - -	unsigned long rate; -	unsigned reserved:1; -	unsigned posted:1; -	struct timer_regs context; -	int (*get_context_loss_count)(struct device *); -	int ctx_loss_count; -	int revision; -	u32 capability; -	struct platform_device *pdev; -	struct list_head node; -}; - -int omap_dm_timer_prepare(struct omap_dm_timer *timer); -  static inline u32 __omap_dm_timer_read(struct omap_dm_timer *timer, u32 reg,  						int posted)  { @@ -302,16 +303,13 @@ static inline void __omap_dm_timer_init_regs(struct omap_dm_timer *timer)  	tidr = __raw_readl(timer->io_base);  	if (!(tidr >> 16)) {  		timer->revision = 1; -		timer->sys_stat = timer->io_base + -				OMAP_TIMER_V1_SYS_STAT_OFFSET;  		timer->irq_stat = timer->io_base + OMAP_TIMER_V1_STAT_OFFSET;  		timer->irq_ena = timer->io_base + OMAP_TIMER_V1_INT_EN_OFFSET; -		timer->irq_dis = NULL; +		timer->irq_dis = timer->io_base + OMAP_TIMER_V1_INT_EN_OFFSET;  		timer->pend = timer->io_base + _OMAP_TIMER_WRITE_PEND_OFFSET;  		timer->func_base = timer->io_base;  	} else {  		timer->revision = 2; -		timer->sys_stat = NULL;  		timer->irq_stat = timer->io_base + OMAP_TIMER_V2_IRQSTATUS;  		timer->irq_ena = timer->io_base + OMAP_TIMER_V2_IRQENABLE_SET;  		timer->irq_dis = timer->io_base + OMAP_TIMER_V2_IRQENABLE_CLR; @@ -322,45 +320,44 @@ static inline void __omap_dm_timer_init_regs(struct omap_dm_timer *timer)  	}  } -/* Assumes the source clock has been set by caller */ -static inline void __omap_dm_timer_reset(struct omap_dm_timer *timer, -					int autoidle, int wakeup) +/* + * __omap_dm_timer_enable_posted - enables write posted mode + * @timer:      pointer to timer instance handle + * + * Enables the write posted mode for the timer. When posted mode is enabled + * writes to certain timer registers are immediately acknowledged by the + * internal bus and hence prevents stalling the CPU waiting for the write to + * complete. Enabling this feature can improve performance for writing to the + * timer registers. + */ +static inline void __omap_dm_timer_enable_posted(struct omap_dm_timer *timer)  { -	u32 l; +	if (timer->posted) +		return; -	l = __raw_readl(timer->io_base + OMAP_TIMER_OCP_CFG_OFFSET); -	l |= 0x02 << 3;  /* Set to smart-idle mode */ -	l |= 0x2 << 8;   /* Set clock activity to perserve f-clock on idle */ +	if (timer->errata & OMAP_TIMER_ERRATA_I103_I767) +		return; -	if (autoidle) -		l |= 0x1 << 0; - -	if (wakeup) -		l |= 1 << 2; - -	__raw_writel(l, timer->io_base + OMAP_TIMER_OCP_CFG_OFFSET); - -	/* Match hardware reset default of posted mode */  	__omap_dm_timer_write(timer, OMAP_TIMER_IF_CTRL_REG, -					OMAP_TIMER_CTRL_POSTED, 0); +			      OMAP_TIMER_CTRL_POSTED, 0); +	timer->context.tsicr = OMAP_TIMER_CTRL_POSTED; +	timer->posted = OMAP_TIMER_POSTED;  } -static inline int __omap_dm_timer_set_source(struct clk *timer_fck, -						struct clk *parent) +/** + * __omap_dm_timer_override_errata - override errata flags for a timer + * @timer:      pointer to timer handle + * @errata:	errata flags to be ignored + * + * For a given timer, override a timer errata by clearing the flags + * specified by the errata argument. A specific erratum should only be + * overridden for a timer if the timer is used in such a way the erratum + * has no impact. + */ +static inline void __omap_dm_timer_override_errata(struct omap_dm_timer *timer, +						   u32 errata)  { -	int ret; - -	clk_disable(timer_fck); -	ret = clk_set_parent(timer_fck, parent); -	clk_enable(timer_fck); - -	/* -	 * When the functional clock disappears, too quick writes seem -	 * to cause an abort. XXX Is this still necessary? -	 */ -	__delay(300000); - -	return ret; +	timer->errata &= ~errata;  }  static inline void __omap_dm_timer_stop(struct omap_dm_timer *timer,  |