linux/drivers/clocksource/timer-ti-dm.c

// SPDX-License-Identifier: GPL-2.0+
/*
 * linux/arch/arm/plat-omap/dmtimer.c
 *
 * OMAP Dual-Mode Timers
 *
 * Copyright (C) 2010 Texas Instruments Incorporated - https://www.ti.com/
 * Tarun Kanti DebBarma <[email protected]>
 * Thara Gopinath <[email protected]>
 *
 * dmtimer adaptation to platform_driver.
 *
 * Copyright (C) 2005 Nokia Corporation
 * OMAP2 support by Juha Yrjola
 * API improvements and OMAP2 clock framework support by Timo Teras
 *
 * Copyright (C) 2009 Texas Instruments
 * Added OMAP4 support - Santosh Shilimkar <[email protected]>
 */

#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/cpu_pm.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/pm_runtime.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/platform_data/dmtimer-omap.h>

#include <clocksource/timer-ti-dm.h>

/*
 * 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

/* posted mode types */
#define OMAP_TIMER_NONPOSTED
#define OMAP_TIMER_POSTED

/* register offsets with the write pending bit encoded */
#define WPSHIFT

#define OMAP_TIMER_WAKEUP_EN_REG

#define OMAP_TIMER_CTRL_REG

#define OMAP_TIMER_COUNTER_REG

#define OMAP_TIMER_LOAD_REG

#define OMAP_TIMER_TRIGGER_REG

#define OMAP_TIMER_WRITE_PEND_REG

#define OMAP_TIMER_MATCH_REG

#define OMAP_TIMER_CAPTURE_REG

#define OMAP_TIMER_IF_CTRL_REG

#define OMAP_TIMER_CAPTURE2_REG

#define OMAP_TIMER_TICK_POS_REG

#define OMAP_TIMER_TICK_NEG_REG

#define OMAP_TIMER_TICK_COUNT_REG

#define OMAP_TIMER_TICK_INT_MASK_SET_REG

#define OMAP_TIMER_TICK_INT_MASK_COUNT_REG

struct timer_regs {};

struct dmtimer {};

static u32 omap_reserved_systimers;
static LIST_HEAD(omap_timer_list);
static DEFINE_SPINLOCK(dm_timer_lock);

enum {};

/**
 * dmtimer_read - read timer registers in posted and non-posted mode
 * @timer:	timer pointer over which read operation to perform
 * @reg:	lowest byte holds the register offset
 *
 * The posted mode bit is encoded in reg. Note that in posted mode, write
 * pending bit must be checked. Otherwise a read of a non completed write
 * will produce an error.
 */
static inline u32 dmtimer_read(struct dmtimer *timer, u32 reg)
{}

/**
 * dmtimer_write - write timer registers in posted and non-posted mode
 * @timer:      timer pointer over which write operation is to perform
 * @reg:        lowest byte holds the register offset
 * @val:        data to write into the register
 *
 * The posted mode bit is encoded in reg. Note that in posted mode, the write
 * pending bit must be checked. Otherwise a write on a register which has a
 * pending write will be lost.
 */
static inline void dmtimer_write(struct dmtimer *timer, u32 reg, u32 val)
{}

static inline void __omap_dm_timer_init_regs(struct dmtimer *timer)
{}

/*
 * __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 dmtimer *timer)
{}

static inline void __omap_dm_timer_stop(struct dmtimer *timer)
{}

static inline void __omap_dm_timer_int_enable(struct dmtimer *timer,
					      unsigned int value)
{}

static inline unsigned int
__omap_dm_timer_read_counter(struct dmtimer *timer)
{}

static inline void __omap_dm_timer_write_status(struct dmtimer *timer,
						unsigned int value)
{}

static void omap_timer_restore_context(struct dmtimer *timer)
{}

static void omap_timer_save_context(struct dmtimer *timer)
{}

static int omap_timer_context_notifier(struct notifier_block *nb,
				       unsigned long cmd, void *v)
{}

static int omap_timer_fclk_notifier(struct notifier_block *nb,
				    unsigned long event, void *data)
{}

static int omap_dm_timer_reset(struct dmtimer *timer)
{}

/*
 * Functions exposed to PWM and remoteproc drivers via platform_data.
 * Do not use these in the driver, these will get deprecated and will
 * will be replaced by Linux generic framework functions such as
 * chained interrupts and clock framework.
 */
static struct dmtimer *to_dmtimer(struct omap_dm_timer *cookie)
{}

static int omap_dm_timer_set_source(struct omap_dm_timer *cookie, int source)
{}

static void omap_dm_timer_enable(struct omap_dm_timer *cookie)
{}

static void omap_dm_timer_disable(struct omap_dm_timer *cookie)
{}

static int omap_dm_timer_prepare(struct dmtimer *timer)
{}

static inline u32 omap_dm_timer_reserved_systimer(int id)
{}

static struct dmtimer *_omap_dm_timer_request(int req_type, void *data)
{}

static struct omap_dm_timer *omap_dm_timer_request(void)
{}

static struct omap_dm_timer *omap_dm_timer_request_specific(int id)
{}

/**
 * omap_dm_timer_request_by_node - Request a timer by device-tree node
 * @np:		Pointer to device-tree timer node
 *
 * Request a timer based upon a device node pointer. Returns pointer to
 * timer handle on success and a NULL pointer on failure.
 */
static struct omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *np)
{}

static int omap_dm_timer_free(struct omap_dm_timer *cookie)
{}

static int omap_dm_timer_get_irq(struct omap_dm_timer *cookie)
{}

#if defined(CONFIG_ARCH_OMAP1)
#include <linux/soc/ti/omap1-io.h>

static struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *cookie)
{
	return NULL;
}

/**
 * omap_dm_timer_modify_idlect_mask - Check if any running timers use ARMXOR
 * @inputmask: current value of idlect mask
 */
__u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
{
	int i = 0;
	struct dmtimer *timer = NULL;
	unsigned long flags;

	/* If ARMXOR cannot be idled this function call is unnecessary */
	if (!(inputmask & (1 << 1)))
		return inputmask;

	/* If any active timer is using ARMXOR return modified mask */
	spin_lock_irqsave(&dm_timer_lock, flags);
	list_for_each_entry(timer, &omap_timer_list, node) {
		u32 l;

		l = dmtimer_read(timer, OMAP_TIMER_CTRL_REG);
		if (l & OMAP_TIMER_CTRL_ST) {
			if (((omap_readl(MOD_CONF_CTRL_1) >> (i * 2)) & 0x03) == 0)
				inputmask &= ~(1 << 1);
			else
				inputmask &= ~(1 << 2);
		}
		i++;
	}
	spin_unlock_irqrestore(&dm_timer_lock, flags);

	return inputmask;
}

#else

static struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *cookie)
{}

__u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
{}

#endif

static int omap_dm_timer_start(struct omap_dm_timer *cookie)
{}

static int omap_dm_timer_stop(struct omap_dm_timer *cookie)
{}

static int omap_dm_timer_set_load(struct omap_dm_timer *cookie,
				  unsigned int load)
{}

static int omap_dm_timer_set_match(struct omap_dm_timer *cookie, int enable,
				   unsigned int match)
{}

static int omap_dm_timer_set_pwm(struct omap_dm_timer *cookie, int def_on,
				 int toggle, int trigger, int autoreload)
{}

static int omap_dm_timer_get_pwm_status(struct omap_dm_timer *cookie)
{}

static int omap_dm_timer_set_prescaler(struct omap_dm_timer *cookie,
				       int prescaler)
{}

static int omap_dm_timer_set_int_enable(struct omap_dm_timer *cookie,
					unsigned int value)
{}

/**
 * omap_dm_timer_set_int_disable - disable timer interrupts
 * @cookie:	pointer to timer cookie
 * @mask:	bit mask of interrupts to be disabled
 *
 * Disables the specified timer interrupts for a timer.
 */
static int omap_dm_timer_set_int_disable(struct omap_dm_timer *cookie, u32 mask)
{}

static unsigned int omap_dm_timer_read_status(struct omap_dm_timer *cookie)
{}

static int omap_dm_timer_write_status(struct omap_dm_timer *cookie, unsigned int value)
{}

static unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *cookie)
{}

static int omap_dm_timer_write_counter(struct omap_dm_timer *cookie, unsigned int value)
{}

static int __maybe_unused omap_dm_timer_runtime_suspend(struct device *dev)
{}

static int __maybe_unused omap_dm_timer_runtime_resume(struct device *dev)
{}

static const struct dev_pm_ops omap_dm_timer_pm_ops =;

static const struct of_device_id omap_timer_match[];

/**
 * omap_dm_timer_probe - probe function called for every registered device
 * @pdev:	pointer to current timer platform device
 *
 * Called by driver framework at the end of device registration for all
 * timer devices.
 */
static int omap_dm_timer_probe(struct platform_device *pdev)
{}

/**
 * omap_dm_timer_remove - cleanup a registered timer device
 * @pdev:	pointer to current timer platform device
 *
 * Called by driver framework whenever a timer device is unregistered.
 * In addition to freeing platform resources it also deletes the timer
 * entry from the local list.
 */
static void omap_dm_timer_remove(struct platform_device *pdev)
{}

static const struct omap_dm_timer_ops dmtimer_ops =;

static const struct dmtimer_platform_data omap3plus_pdata =;

static const struct dmtimer_platform_data am6_pdata =;

static const struct of_device_id omap_timer_match[] =;
MODULE_DEVICE_TABLE(of, omap_timer_match);

static struct platform_driver omap_dm_timer_driver =;

module_platform_driver();

MODULE_DESCRIPTION();
MODULE_AUTHOR();