^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* linux/arch/arm/mach-exynos4/mct.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2011 Samsung Electronics Co., Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * http://www.samsung.com
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Exynos4 MCT(Multi-Core Timer) support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/clockchips.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/cpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/percpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/clocksource.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/sched_clock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define EXYNOS4_MCTREG(x) (x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define EXYNOS4_MCT_G_CNT_L EXYNOS4_MCTREG(0x100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define EXYNOS4_MCT_G_CNT_U EXYNOS4_MCTREG(0x104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define EXYNOS4_MCT_G_CNT_WSTAT EXYNOS4_MCTREG(0x110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define EXYNOS4_MCT_G_COMP0_L EXYNOS4_MCTREG(0x200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define EXYNOS4_MCT_G_COMP0_U EXYNOS4_MCTREG(0x204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define EXYNOS4_MCT_G_COMP0_ADD_INCR EXYNOS4_MCTREG(0x208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define EXYNOS4_MCT_G_TCON EXYNOS4_MCTREG(0x240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define EXYNOS4_MCT_G_INT_CSTAT EXYNOS4_MCTREG(0x244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define EXYNOS4_MCT_G_INT_ENB EXYNOS4_MCTREG(0x248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define EXYNOS4_MCT_G_WSTAT EXYNOS4_MCTREG(0x24C)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define _EXYNOS4_MCT_L_BASE EXYNOS4_MCTREG(0x300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define EXYNOS4_MCT_L_BASE(x) (_EXYNOS4_MCT_L_BASE + (0x100 * x))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define EXYNOS4_MCT_L_MASK (0xffffff00)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define MCT_L_TCNTB_OFFSET (0x00)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define MCT_L_ICNTB_OFFSET (0x08)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define MCT_L_TCON_OFFSET (0x20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define MCT_L_INT_CSTAT_OFFSET (0x30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define MCT_L_INT_ENB_OFFSET (0x34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define MCT_L_WSTAT_OFFSET (0x40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define MCT_G_TCON_START (1 << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define MCT_G_TCON_COMP0_AUTO_INC (1 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define MCT_G_TCON_COMP0_ENABLE (1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define MCT_L_TCON_INTERVAL_MODE (1 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define MCT_L_TCON_INT_START (1 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define MCT_L_TCON_TIMER_START (1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define TICK_BASE_CNT 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) MCT_INT_SPI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) MCT_INT_PPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) MCT_G0_IRQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) MCT_G1_IRQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) MCT_G2_IRQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) MCT_G3_IRQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) MCT_L0_IRQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) MCT_L1_IRQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) MCT_L2_IRQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) MCT_L3_IRQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) MCT_L4_IRQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) MCT_L5_IRQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) MCT_L6_IRQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) MCT_L7_IRQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) MCT_NR_IRQS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) static void __iomem *reg_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static unsigned long clk_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static unsigned int mct_int_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) static int mct_irqs[MCT_NR_IRQS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct mct_clock_event_device {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct clock_event_device evt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) unsigned long base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) char name[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) static void exynos4_mct_write(unsigned int value, unsigned long offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) unsigned long stat_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) u32 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) writel_relaxed(value, reg_base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (likely(offset >= EXYNOS4_MCT_L_BASE(0))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) stat_addr = (offset & EXYNOS4_MCT_L_MASK) + MCT_L_WSTAT_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) switch (offset & ~EXYNOS4_MCT_L_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) case MCT_L_TCON_OFFSET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) mask = 1 << 3; /* L_TCON write status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) case MCT_L_ICNTB_OFFSET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) mask = 1 << 1; /* L_ICNTB write status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) case MCT_L_TCNTB_OFFSET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) mask = 1 << 0; /* L_TCNTB write status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) switch (offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) case EXYNOS4_MCT_G_TCON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) stat_addr = EXYNOS4_MCT_G_WSTAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) mask = 1 << 16; /* G_TCON write status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) case EXYNOS4_MCT_G_COMP0_L:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) stat_addr = EXYNOS4_MCT_G_WSTAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) mask = 1 << 0; /* G_COMP0_L write status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) case EXYNOS4_MCT_G_COMP0_U:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) stat_addr = EXYNOS4_MCT_G_WSTAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) mask = 1 << 1; /* G_COMP0_U write status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) case EXYNOS4_MCT_G_COMP0_ADD_INCR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) stat_addr = EXYNOS4_MCT_G_WSTAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) mask = 1 << 2; /* G_COMP0_ADD_INCR w status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) case EXYNOS4_MCT_G_CNT_L:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) stat_addr = EXYNOS4_MCT_G_CNT_WSTAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) mask = 1 << 0; /* G_CNT_L write status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) case EXYNOS4_MCT_G_CNT_U:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) stat_addr = EXYNOS4_MCT_G_CNT_WSTAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) mask = 1 << 1; /* G_CNT_U write status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /* Wait maximum 1 ms until written values are applied */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) for (i = 0; i < loops_per_jiffy / 1000 * HZ; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) if (readl_relaxed(reg_base + stat_addr) & mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) writel_relaxed(mask, reg_base + stat_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) panic("MCT hangs after writing %d (offset:0x%lx)\n", value, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) /* Clocksource handling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static void exynos4_mct_frc_start(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) reg = readl_relaxed(reg_base + EXYNOS4_MCT_G_TCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) reg |= MCT_G_TCON_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) exynos4_mct_write(reg, EXYNOS4_MCT_G_TCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * exynos4_read_count_64 - Read all 64-bits of the global counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * This will read all 64-bits of the global counter taking care to make sure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * that the upper and lower half match. Note that reading the MCT can be quite
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * slow (hundreds of nanoseconds) so you should use the 32-bit (lower half
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) * only) version when possible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * Returns the number of cycles in the global counter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static u64 exynos4_read_count_64(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) unsigned int lo, hi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) u32 hi2 = readl_relaxed(reg_base + EXYNOS4_MCT_G_CNT_U);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) hi = hi2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) lo = readl_relaxed(reg_base + EXYNOS4_MCT_G_CNT_L);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) hi2 = readl_relaxed(reg_base + EXYNOS4_MCT_G_CNT_U);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) } while (hi != hi2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return ((u64)hi << 32) | lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) * exynos4_read_count_32 - Read the lower 32-bits of the global counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * This will read just the lower 32-bits of the global counter. This is marked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * as notrace so it can be used by the scheduler clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * Returns the number of cycles in the global counter (lower 32 bits).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) static u32 notrace exynos4_read_count_32(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) return readl_relaxed(reg_base + EXYNOS4_MCT_G_CNT_L);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) static u64 exynos4_frc_read(struct clocksource *cs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) return exynos4_read_count_32();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) static void exynos4_frc_resume(struct clocksource *cs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) exynos4_mct_frc_start();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) static struct clocksource mct_frc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) .name = "mct-frc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) .rating = 450, /* use value higher than ARM arch timer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) .read = exynos4_frc_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) .mask = CLOCKSOURCE_MASK(32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) .flags = CLOCK_SOURCE_IS_CONTINUOUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) .resume = exynos4_frc_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) static u64 notrace exynos4_read_sched_clock(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) return exynos4_read_count_32();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) #if defined(CONFIG_ARM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) static struct delay_timer exynos4_delay_timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) static cycles_t exynos4_read_current_timer(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) BUILD_BUG_ON_MSG(sizeof(cycles_t) != sizeof(u32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) "cycles_t needs to move to 32-bit for ARM64 usage");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return exynos4_read_count_32();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) static int __init exynos4_clocksource_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) exynos4_mct_frc_start();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) #if defined(CONFIG_ARM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) exynos4_delay_timer.read_current_timer = &exynos4_read_current_timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) exynos4_delay_timer.freq = clk_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) register_current_timer_delay(&exynos4_delay_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (clocksource_register_hz(&mct_frc, clk_rate))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) panic("%s: can't register clocksource\n", mct_frc.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) sched_clock_register(exynos4_read_sched_clock, 32, clk_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) static void exynos4_mct_comp0_stop(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) unsigned int tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) tcon = readl_relaxed(reg_base + EXYNOS4_MCT_G_TCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) tcon &= ~(MCT_G_TCON_COMP0_ENABLE | MCT_G_TCON_COMP0_AUTO_INC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) exynos4_mct_write(tcon, EXYNOS4_MCT_G_TCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) exynos4_mct_write(0, EXYNOS4_MCT_G_INT_ENB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) static void exynos4_mct_comp0_start(bool periodic, unsigned long cycles)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) unsigned int tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) u64 comp_cycle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) tcon = readl_relaxed(reg_base + EXYNOS4_MCT_G_TCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) if (periodic) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) tcon |= MCT_G_TCON_COMP0_AUTO_INC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) exynos4_mct_write(cycles, EXYNOS4_MCT_G_COMP0_ADD_INCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) comp_cycle = exynos4_read_count_64() + cycles;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) exynos4_mct_write((u32)comp_cycle, EXYNOS4_MCT_G_COMP0_L);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) exynos4_mct_write((u32)(comp_cycle >> 32), EXYNOS4_MCT_G_COMP0_U);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) exynos4_mct_write(0x1, EXYNOS4_MCT_G_INT_ENB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) tcon |= MCT_G_TCON_COMP0_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) exynos4_mct_write(tcon , EXYNOS4_MCT_G_TCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) static int exynos4_comp_set_next_event(unsigned long cycles,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) struct clock_event_device *evt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) exynos4_mct_comp0_start(false, cycles);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) static int mct_set_state_shutdown(struct clock_event_device *evt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) exynos4_mct_comp0_stop();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) static int mct_set_state_periodic(struct clock_event_device *evt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) unsigned long cycles_per_jiffy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) cycles_per_jiffy = (((unsigned long long)NSEC_PER_SEC / HZ * evt->mult)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) >> evt->shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) exynos4_mct_comp0_stop();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) exynos4_mct_comp0_start(true, cycles_per_jiffy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) static struct clock_event_device mct_comp_device = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) .name = "mct-comp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) .features = CLOCK_EVT_FEAT_PERIODIC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) CLOCK_EVT_FEAT_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) .rating = 250,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) .set_next_event = exynos4_comp_set_next_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) .set_state_periodic = mct_set_state_periodic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) .set_state_shutdown = mct_set_state_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) .set_state_oneshot = mct_set_state_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) .set_state_oneshot_stopped = mct_set_state_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) .tick_resume = mct_set_state_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) static irqreturn_t exynos4_mct_comp_isr(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) struct clock_event_device *evt = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) exynos4_mct_write(0x1, EXYNOS4_MCT_G_INT_CSTAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) evt->event_handler(evt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) static int exynos4_clockevent_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) mct_comp_device.cpumask = cpumask_of(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) clockevents_config_and_register(&mct_comp_device, clk_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 0xf, 0xffffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (request_irq(mct_irqs[MCT_G0_IRQ], exynos4_mct_comp_isr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) IRQF_TIMER | IRQF_IRQPOLL, "mct_comp_irq",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) &mct_comp_device))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) pr_err("%s: request_irq() failed\n", "mct_comp_irq");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) static DEFINE_PER_CPU(struct mct_clock_event_device, percpu_mct_tick);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) /* Clock event handling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) static void exynos4_mct_tick_stop(struct mct_clock_event_device *mevt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) unsigned long tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) unsigned long mask = MCT_L_TCON_INT_START | MCT_L_TCON_TIMER_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) unsigned long offset = mevt->base + MCT_L_TCON_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) tmp = readl_relaxed(reg_base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) if (tmp & mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) tmp &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) exynos4_mct_write(tmp, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) static void exynos4_mct_tick_start(unsigned long cycles,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) struct mct_clock_event_device *mevt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) unsigned long tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) exynos4_mct_tick_stop(mevt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) tmp = (1 << 31) | cycles; /* MCT_L_UPDATE_ICNTB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) /* update interrupt count buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) exynos4_mct_write(tmp, mevt->base + MCT_L_ICNTB_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) /* enable MCT tick interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) exynos4_mct_write(0x1, mevt->base + MCT_L_INT_ENB_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) tmp = readl_relaxed(reg_base + mevt->base + MCT_L_TCON_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) tmp |= MCT_L_TCON_INT_START | MCT_L_TCON_TIMER_START |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) MCT_L_TCON_INTERVAL_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) exynos4_mct_write(tmp, mevt->base + MCT_L_TCON_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) static void exynos4_mct_tick_clear(struct mct_clock_event_device *mevt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) /* Clear the MCT tick interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) if (readl_relaxed(reg_base + mevt->base + MCT_L_INT_CSTAT_OFFSET) & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) exynos4_mct_write(0x1, mevt->base + MCT_L_INT_CSTAT_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) static int exynos4_tick_set_next_event(unsigned long cycles,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) struct clock_event_device *evt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) struct mct_clock_event_device *mevt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) mevt = container_of(evt, struct mct_clock_event_device, evt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) exynos4_mct_tick_start(cycles, mevt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) static int set_state_shutdown(struct clock_event_device *evt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) struct mct_clock_event_device *mevt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) mevt = container_of(evt, struct mct_clock_event_device, evt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) exynos4_mct_tick_stop(mevt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) exynos4_mct_tick_clear(mevt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) static int set_state_periodic(struct clock_event_device *evt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) struct mct_clock_event_device *mevt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) unsigned long cycles_per_jiffy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) mevt = container_of(evt, struct mct_clock_event_device, evt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) cycles_per_jiffy = (((unsigned long long)NSEC_PER_SEC / HZ * evt->mult)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) >> evt->shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) exynos4_mct_tick_stop(mevt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) exynos4_mct_tick_start(cycles_per_jiffy, mevt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) static irqreturn_t exynos4_mct_tick_isr(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) struct mct_clock_event_device *mevt = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) struct clock_event_device *evt = &mevt->evt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) * This is for supporting oneshot mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) * Mct would generate interrupt periodically
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) * without explicit stopping.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) if (!clockevent_state_periodic(&mevt->evt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) exynos4_mct_tick_stop(mevt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) exynos4_mct_tick_clear(mevt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) evt->event_handler(evt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) static int exynos4_mct_starting_cpu(unsigned int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) struct mct_clock_event_device *mevt =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) per_cpu_ptr(&percpu_mct_tick, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) struct clock_event_device *evt = &mevt->evt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) mevt->base = EXYNOS4_MCT_L_BASE(cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) snprintf(mevt->name, sizeof(mevt->name), "mct_tick%d", cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) evt->name = mevt->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) evt->cpumask = cpumask_of(cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) evt->set_next_event = exynos4_tick_set_next_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) evt->set_state_periodic = set_state_periodic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) evt->set_state_shutdown = set_state_shutdown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) evt->set_state_oneshot = set_state_shutdown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) evt->set_state_oneshot_stopped = set_state_shutdown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) evt->tick_resume = set_state_shutdown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) evt->rating = 500; /* use value higher than ARM arch timer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) exynos4_mct_write(TICK_BASE_CNT, mevt->base + MCT_L_TCNTB_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) if (mct_int_type == MCT_INT_SPI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (evt->irq == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) irq_force_affinity(evt->irq, cpumask_of(cpu));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) enable_irq(evt->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) enable_percpu_irq(mct_irqs[MCT_L0_IRQ], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) clockevents_config_and_register(evt, clk_rate / (TICK_BASE_CNT + 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 0xf, 0x7fffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) static int exynos4_mct_dying_cpu(unsigned int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) struct mct_clock_event_device *mevt =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) per_cpu_ptr(&percpu_mct_tick, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) struct clock_event_device *evt = &mevt->evt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) evt->set_state_shutdown(evt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (mct_int_type == MCT_INT_SPI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (evt->irq != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) disable_irq_nosync(evt->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) exynos4_mct_write(0x1, mevt->base + MCT_L_INT_CSTAT_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) disable_percpu_irq(mct_irqs[MCT_L0_IRQ]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) static int __init exynos4_timer_resources(struct device_node *np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) struct clk *mct_clk, *tick_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) reg_base = of_iomap(np, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (!reg_base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) panic("%s: unable to ioremap mct address space\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) tick_clk = of_clk_get_by_name(np, "fin_pll");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) if (IS_ERR(tick_clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) panic("%s: unable to determine tick clock rate\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) clk_rate = clk_get_rate(tick_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) mct_clk = of_clk_get_by_name(np, "mct");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) if (IS_ERR(mct_clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) panic("%s: unable to retrieve mct clock instance\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) clk_prepare_enable(mct_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) static int __init exynos4_timer_interrupts(struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) unsigned int int_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) int nr_irqs, i, err, cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) mct_int_type = int_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) /* This driver uses only one global timer interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) mct_irqs[MCT_G0_IRQ] = irq_of_parse_and_map(np, MCT_G0_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) * Find out the number of local irqs specified. The local
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) * timer irqs are specified after the four global timer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) * irqs are specified.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) nr_irqs = of_irq_count(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) if (nr_irqs > ARRAY_SIZE(mct_irqs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) pr_err("exynos-mct: too many (%d) interrupts configured in DT\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) nr_irqs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) nr_irqs = ARRAY_SIZE(mct_irqs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) for (i = MCT_L0_IRQ; i < nr_irqs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) mct_irqs[i] = irq_of_parse_and_map(np, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) if (mct_int_type == MCT_INT_PPI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) err = request_percpu_irq(mct_irqs[MCT_L0_IRQ],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) exynos4_mct_tick_isr, "MCT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) &percpu_mct_tick);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) WARN(err, "MCT: can't request IRQ %d (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) mct_irqs[MCT_L0_IRQ], err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) for_each_possible_cpu(cpu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) int mct_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) struct mct_clock_event_device *pcpu_mevt =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) per_cpu_ptr(&percpu_mct_tick, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) pcpu_mevt->evt.irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) if (MCT_L0_IRQ + cpu >= ARRAY_SIZE(mct_irqs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) mct_irq = mct_irqs[MCT_L0_IRQ + cpu];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) irq_set_status_flags(mct_irq, IRQ_NOAUTOEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) if (request_irq(mct_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) exynos4_mct_tick_isr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) IRQF_TIMER | IRQF_NOBALANCING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) pcpu_mevt->name, pcpu_mevt)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) pr_err("exynos-mct: cannot register IRQ (cpu%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) pcpu_mevt->evt.irq = mct_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) /* Install hotplug callbacks which configure the timer on this CPU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) err = cpuhp_setup_state(CPUHP_AP_EXYNOS4_MCT_TIMER_STARTING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) "clockevents/exynos4/mct_timer:starting",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) exynos4_mct_starting_cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) exynos4_mct_dying_cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) goto out_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) out_irq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) if (mct_int_type == MCT_INT_PPI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) free_percpu_irq(mct_irqs[MCT_L0_IRQ], &percpu_mct_tick);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) for_each_possible_cpu(cpu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) struct mct_clock_event_device *pcpu_mevt =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) per_cpu_ptr(&percpu_mct_tick, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) if (pcpu_mevt->evt.irq != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) free_irq(pcpu_mevt->evt.irq, pcpu_mevt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) pcpu_mevt->evt.irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) static int __init mct_init_dt(struct device_node *np, unsigned int int_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) ret = exynos4_timer_resources(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) ret = exynos4_timer_interrupts(np, int_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) ret = exynos4_clocksource_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) return exynos4_clockevent_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) static int __init mct_init_spi(struct device_node *np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) return mct_init_dt(np, MCT_INT_SPI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) static int __init mct_init_ppi(struct device_node *np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) return mct_init_dt(np, MCT_INT_PPI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) TIMER_OF_DECLARE(exynos4210, "samsung,exynos4210-mct", mct_init_spi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) TIMER_OF_DECLARE(exynos4412, "samsung,exynos4412-mct", mct_init_ppi);