Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/sched_clock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include "timer-of.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #define CLKSRC_OFFSET	0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #define TIMER_STATUS	0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #define TIMER_VALUE	0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #define TIMER_CONTRL	0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #define TIMER_CONFIG	0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #define TIMER_DIV	0x24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #define TIMER_INI	0x28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #define GX6605S_STATUS_CLR	BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #define GX6605S_CONTRL_RST	BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #define GX6605S_CONTRL_START	BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define GX6605S_CONFIG_EN	BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define GX6605S_CONFIG_IRQ_EN	BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) static irqreturn_t gx6605s_timer_interrupt(int irq, void *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	struct clock_event_device *ce = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	void __iomem *base = timer_of_base(to_timer_of(ce));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	writel_relaxed(GX6605S_STATUS_CLR, base + TIMER_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	writel_relaxed(0, base + TIMER_INI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	ce->event_handler(ce);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) static int gx6605s_timer_set_oneshot(struct clock_event_device *ce)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	void __iomem *base = timer_of_base(to_timer_of(ce));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	/* reset and stop counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	writel_relaxed(GX6605S_CONTRL_RST, base + TIMER_CONTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	/* enable with irq and start */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	writel_relaxed(GX6605S_CONFIG_EN | GX6605S_CONFIG_IRQ_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 		       base + TIMER_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) static int gx6605s_timer_set_next_event(unsigned long delta,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 					struct clock_event_device *ce)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	void __iomem *base = timer_of_base(to_timer_of(ce));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	/* use reset to pause timer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	writel_relaxed(GX6605S_CONTRL_RST, base + TIMER_CONTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	/* config next timeout value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	writel_relaxed(ULONG_MAX - delta, base + TIMER_INI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	writel_relaxed(GX6605S_CONTRL_START, base + TIMER_CONTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) static int gx6605s_timer_shutdown(struct clock_event_device *ce)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	void __iomem *base = timer_of_base(to_timer_of(ce));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	writel_relaxed(0, base + TIMER_CONTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	writel_relaxed(0, base + TIMER_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) static struct timer_of to = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	.flags = TIMER_OF_IRQ | TIMER_OF_BASE | TIMER_OF_CLOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	.clkevt = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		.rating			= 300,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		.features		= CLOCK_EVT_FEAT_DYNIRQ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 					  CLOCK_EVT_FEAT_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		.set_state_shutdown	= gx6605s_timer_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		.set_state_oneshot	= gx6605s_timer_set_oneshot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		.set_next_event		= gx6605s_timer_set_next_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		.cpumask		= cpu_possible_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	.of_irq = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		.handler		= gx6605s_timer_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		.flags			= IRQF_TIMER | IRQF_IRQPOLL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) static u64 notrace gx6605s_sched_clock_read(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	base = timer_of_base(&to) + CLKSRC_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	return (u64)readl_relaxed(base + TIMER_VALUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static void gx6605s_clkevt_init(void __iomem *base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	writel_relaxed(0, base + TIMER_DIV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	writel_relaxed(0, base + TIMER_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	clockevents_config_and_register(&to.clkevt, timer_of_rate(&to), 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 					ULONG_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static int gx6605s_clksrc_init(void __iomem *base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	writel_relaxed(0, base + TIMER_DIV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	writel_relaxed(0, base + TIMER_INI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	writel_relaxed(GX6605S_CONTRL_RST, base + TIMER_CONTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	writel_relaxed(GX6605S_CONFIG_EN, base + TIMER_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	writel_relaxed(GX6605S_CONTRL_START, base + TIMER_CONTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	sched_clock_register(gx6605s_sched_clock_read, 32, timer_of_rate(&to));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	return clocksource_mmio_init(base + TIMER_VALUE, "gx6605s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 			timer_of_rate(&to), 200, 32, clocksource_mmio_readl_up);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static int __init gx6605s_timer_init(struct device_node *np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	 * The timer driver is for nationalchip gx6605s SOC and there are two
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	 * same timer in gx6605s. We use one for clkevt and another for clksrc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	 * The timer is mmio map to access, so we need give mmio address in dts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	 * It provides a 32bit countup timer and interrupt will be caused by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	 * count-overflow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	 * So we need set-next-event by ULONG_MAX - delta in TIMER_INI reg.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	 * The counter at 0x0  offset is clock event.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	 * The counter at 0x40 offset is clock source.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	 * They are the same in hardware, just different used by driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	ret = timer_of_init(np, &to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	gx6605s_clkevt_init(timer_of_base(&to));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	return gx6605s_clksrc_init(timer_of_base(&to) + CLKSRC_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) TIMER_OF_DECLARE(csky_gx6605s_timer, "csky,gx6605s-timer", gx6605s_timer_init);