^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Renesas Clock Pulse Generator / Module Standby and Software Reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2015 Glider bvba
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Based on clk-mstp.c, clk-rcar-gen2.c, and clk-rcar-gen3.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (C) 2013 Ideas On Board SPRL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Copyright (C) 2015 Renesas Electronics Corp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^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/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/clk/renesas.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/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/mod_devicetable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/pm_clock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/pm_domain.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/psci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/reset-controller.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <dt-bindings/clock/renesas-cpg-mssr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include "renesas-cpg-mssr.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include "clk-div6.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define WARN_DEBUG(x) WARN_ON(x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define WARN_DEBUG(x) do { } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * Module Standby and Software Reset register offets.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * If the registers exist, these are valid for SH-Mobile, R-Mobile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * R-Car Gen2, R-Car Gen3, and RZ/G1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * These are NOT valid for R-Car Gen1 and RZ/A1!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) */
^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) * Module Stop Status Register offsets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static const u16 mstpsr[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) 0x030, 0x038, 0x040, 0x048, 0x04C, 0x03C, 0x1C0, 0x1C4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) 0x9A0, 0x9A4, 0x9A8, 0x9AC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static const u16 mstpsr_for_v3u[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) 0x2E00, 0x2E04, 0x2E08, 0x2E0C, 0x2E10, 0x2E14, 0x2E18, 0x2E1C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) 0x2E20, 0x2E24, 0x2E28, 0x2E2C, 0x2E30, 0x2E34, 0x2E38,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * System Module Stop Control Register offsets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static const u16 smstpcr[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) 0x130, 0x134, 0x138, 0x13C, 0x140, 0x144, 0x148, 0x14C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) 0x990, 0x994, 0x998, 0x99C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static const u16 mstpcr_for_v3u[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) 0x2D00, 0x2D04, 0x2D08, 0x2D0C, 0x2D10, 0x2D14, 0x2D18, 0x2D1C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) 0x2D20, 0x2D24, 0x2D28, 0x2D2C, 0x2D30, 0x2D34, 0x2D38,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * Standby Control Register offsets (RZ/A)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * Base address is FRQCR register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) static const u16 stbcr[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) 0xFFFF/*dummy*/, 0x010, 0x014, 0x410, 0x414, 0x418, 0x41C, 0x420,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) 0x424, 0x428, 0x42C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * Software Reset Register offsets
^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) static const u16 srcr[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) 0x0A0, 0x0A8, 0x0B0, 0x0B8, 0x0BC, 0x0C4, 0x1C8, 0x1CC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) 0x920, 0x924, 0x928, 0x92C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) static const u16 srcr_for_v3u[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) 0x2C00, 0x2C04, 0x2C08, 0x2C0C, 0x2C10, 0x2C14, 0x2C18, 0x2C1C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 0x2C20, 0x2C24, 0x2C28, 0x2C2C, 0x2C30, 0x2C34, 0x2C38,
^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) /* Realtime Module Stop Control Register offsets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define RMSTPCR(i) (smstpcr[i] - 0x20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /* Modem Module Stop Control Register offsets (r8a73a4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define MMSTPCR(i) (smstpcr[i] + 0x20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) /* Software Reset Clearing Register offsets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static const u16 srstclr[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 0x940, 0x944, 0x948, 0x94C, 0x950, 0x954, 0x958, 0x95C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 0x960, 0x964, 0x968, 0x96C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static const u16 srstclr_for_v3u[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 0x2C80, 0x2C84, 0x2C88, 0x2C8C, 0x2C90, 0x2C94, 0x2C98, 0x2C9C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 0x2CA0, 0x2CA4, 0x2CA8, 0x2CAC, 0x2CB0, 0x2CB4, 0x2CB8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * Clock Pulse Generator / Module Standby and Software Reset Private Data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * @rcdev: Optional reset controller entity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * @dev: CPG/MSSR device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * @base: CPG/MSSR register block base address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * @reg_layout: CPG/MSSR register layout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * @rmw_lock: protects RMW register accesses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * @np: Device node in DT for this CPG/MSSR module
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * @num_core_clks: Number of Core Clocks in clks[]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * @num_mod_clks: Number of Module Clocks in clks[]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * @last_dt_core_clk: ID of the last Core Clock exported to DT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * @notifiers: Notifier chain to save/restore clock state for system resume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * @status_regs: Pointer to status registers array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * @control_regs: Pointer to control registers array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * @reset_regs: Pointer to reset registers array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * @reset_clear_regs: Pointer to reset clearing registers array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * @smstpcr_saved[].mask: Mask of SMSTPCR[] bits under our control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * @smstpcr_saved[].val: Saved values of SMSTPCR[]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * @clks: Array containing all Core and Module Clocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct cpg_mssr_priv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #ifdef CONFIG_RESET_CONTROLLER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) struct reset_controller_dev rcdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) enum clk_reg_layout reg_layout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) spinlock_t rmw_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) unsigned int num_core_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) unsigned int num_mod_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) unsigned int last_dt_core_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) struct raw_notifier_head notifiers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) const u16 *status_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) const u16 *control_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) const u16 *reset_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) const u16 *reset_clear_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) u32 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) } smstpcr_saved[ARRAY_SIZE(mstpsr_for_v3u)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) struct clk *clks[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static struct cpg_mssr_priv *cpg_mssr_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * struct mstp_clock - MSTP gating clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * @hw: handle between common and hardware-specific interfaces
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * @index: MSTP clock number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * @priv: CPG/MSSR private data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) struct mstp_clock {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) struct clk_hw hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) u32 index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) struct cpg_mssr_priv *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) #define to_mstp_clock(_hw) container_of(_hw, struct mstp_clock, hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) struct mstp_clock *clock = to_mstp_clock(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) struct cpg_mssr_priv *priv = clock->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) unsigned int reg = clock->index / 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) unsigned int bit = clock->index % 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) struct device *dev = priv->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) u32 bitmask = BIT(bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) dev_dbg(dev, "MSTP %u%02u/%pC %s\n", reg, bit, hw->clk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) enable ? "ON" : "OFF");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) spin_lock_irqsave(&priv->rmw_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) value = readb(priv->base + priv->control_regs[reg]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) value &= ~bitmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) value |= bitmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) writeb(value, priv->base + priv->control_regs[reg]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) /* dummy read to ensure write has completed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) readb(priv->base + priv->control_regs[reg]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) barrier_data(priv->base + priv->control_regs[reg]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) value = readl(priv->base + priv->control_regs[reg]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) value &= ~bitmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) value |= bitmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) writel(value, priv->base + priv->control_regs[reg]);
^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) spin_unlock_irqrestore(&priv->rmw_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (!enable || priv->reg_layout == CLK_REG_LAYOUT_RZ_A)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) for (i = 1000; i > 0; --i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (!(readl(priv->base + priv->status_regs[reg]) & bitmask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (!i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) dev_err(dev, "Failed to enable SMSTP %p[%d]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) priv->base + priv->control_regs[reg], bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static int cpg_mstp_clock_enable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return cpg_mstp_clock_endisable(hw, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) static void cpg_mstp_clock_disable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) cpg_mstp_clock_endisable(hw, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) static int cpg_mstp_clock_is_enabled(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) struct mstp_clock *clock = to_mstp_clock(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) struct cpg_mssr_priv *priv = clock->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) value = readb(priv->base + priv->control_regs[clock->index / 32]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) value = readl(priv->base + priv->status_regs[clock->index / 32]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) return !(value & BIT(clock->index % 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static const struct clk_ops cpg_mstp_clock_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) .enable = cpg_mstp_clock_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) .disable = cpg_mstp_clock_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) .is_enabled = cpg_mstp_clock_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) struct clk *cpg_mssr_clk_src_twocell_get(struct of_phandle_args *clkspec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) unsigned int clkidx = clkspec->args[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) struct cpg_mssr_priv *priv = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) struct device *dev = priv->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) unsigned int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) const char *type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) int range_check;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) switch (clkspec->args[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) case CPG_CORE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) type = "core";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (clkidx > priv->last_dt_core_clk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) dev_err(dev, "Invalid %s clock index %u\n", type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) clkidx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) clk = priv->clks[clkidx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) case CPG_MOD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) type = "module";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) idx = MOD_CLK_PACK_10(clkidx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) range_check = 7 - (clkidx % 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) idx = MOD_CLK_PACK(clkidx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) range_check = 31 - (clkidx % 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (range_check < 0 || idx >= priv->num_mod_clks) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) dev_err(dev, "Invalid %s clock index %u\n", type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) clkidx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) clk = priv->clks[priv->num_core_clks + idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) dev_err(dev, "Invalid CPG clock type %u\n", clkspec->args[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (IS_ERR(clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) dev_err(dev, "Cannot get %s clock %u: %ld", type, clkidx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) PTR_ERR(clk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) dev_dbg(dev, "clock (%u, %u) is %pC at %lu Hz\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) clkspec->args[0], clkspec->args[1], clk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) clk_get_rate(clk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) return clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) const struct cpg_mssr_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) struct cpg_mssr_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) struct clk *clk = ERR_PTR(-ENOTSUPP), *parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) struct device *dev = priv->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) unsigned int id = core->id, div = core->div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) const char *parent_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) WARN_DEBUG(id >= priv->num_core_clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (!core->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) /* Skip NULLified clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) switch (core->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) case CLK_TYPE_IN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) clk = of_clk_get_by_name(priv->np, core->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) case CLK_TYPE_FF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) case CLK_TYPE_DIV6P1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) case CLK_TYPE_DIV6_RO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) WARN_DEBUG(core->parent >= priv->num_core_clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) parent = priv->clks[core->parent];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (IS_ERR(parent)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) clk = parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) parent_name = __clk_get_name(parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (core->type == CLK_TYPE_DIV6_RO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) /* Multiply with the DIV6 register value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) div *= (readl(priv->base + core->offset) & 0x3f) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (core->type == CLK_TYPE_DIV6P1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) clk = cpg_div6_register(core->name, 1, &parent_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) priv->base + core->offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) &priv->notifiers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) clk = clk_register_fixed_factor(NULL, core->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) parent_name, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) core->mult, div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) case CLK_TYPE_FR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) clk = clk_register_fixed_rate(NULL, core->name, NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) core->mult);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (info->cpg_clk_register)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) clk = info->cpg_clk_register(dev, core, info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) priv->clks, priv->base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) &priv->notifiers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) dev_err(dev, "%s has unsupported core clock type %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) core->name, core->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (IS_ERR_OR_NULL(clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) priv->clks[id] = clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) dev_err(dev, "Failed to register %s clock %s: %ld\n", "core",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) core->name, PTR_ERR(clk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) static void __init cpg_mssr_register_mod_clk(const struct mssr_mod_clk *mod,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) const struct cpg_mssr_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) struct cpg_mssr_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) struct mstp_clock *clock = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) struct device *dev = priv->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) unsigned int id = mod->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) struct clk_init_data init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) struct clk *parent, *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) const char *parent_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) WARN_DEBUG(id < priv->num_core_clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) WARN_DEBUG(id >= priv->num_core_clks + priv->num_mod_clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) WARN_DEBUG(mod->parent >= priv->num_core_clks + priv->num_mod_clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) if (!mod->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) /* Skip NULLified clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) parent = priv->clks[mod->parent];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (IS_ERR(parent)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) clk = parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) clock = kzalloc(sizeof(*clock), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) if (!clock) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) clk = ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) init.name = mod->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) init.ops = &cpg_mstp_clock_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) init.flags = CLK_SET_RATE_PARENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) parent_name = __clk_get_name(parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) init.parent_names = &parent_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) init.num_parents = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) clock->index = id - priv->num_core_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) clock->priv = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) clock->hw.init = &init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) for (i = 0; i < info->num_crit_mod_clks; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) if (id == info->crit_mod_clks[i] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) cpg_mstp_clock_is_enabled(&clock->hw)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) dev_dbg(dev, "MSTP %s setting CLK_IS_CRITICAL\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) mod->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) init.flags |= CLK_IS_CRITICAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) clk = clk_register(NULL, &clock->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) if (IS_ERR(clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) dev_dbg(dev, "Module clock %pC at %lu Hz\n", clk, clk_get_rate(clk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) priv->clks[id] = clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) priv->smstpcr_saved[clock->index / 32].mask |= BIT(clock->index % 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) dev_err(dev, "Failed to register %s clock %s: %ld\n", "module",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) mod->name, PTR_ERR(clk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) kfree(clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) struct cpg_mssr_clk_domain {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) struct generic_pm_domain genpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) unsigned int num_core_pm_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) unsigned int core_pm_clks[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) static struct cpg_mssr_clk_domain *cpg_mssr_clk_domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) static bool cpg_mssr_is_pm_clk(const struct of_phandle_args *clkspec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) struct cpg_mssr_clk_domain *pd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) if (clkspec->np != pd->genpd.dev.of_node || clkspec->args_count != 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) switch (clkspec->args[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) case CPG_CORE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) for (i = 0; i < pd->num_core_pm_clks; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (clkspec->args[1] == pd->core_pm_clks[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) case CPG_MOD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) int cpg_mssr_attach_dev(struct generic_pm_domain *unused, struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) struct cpg_mssr_clk_domain *pd = cpg_mssr_clk_domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) struct device_node *np = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) struct of_phandle_args clkspec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) if (!pd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) dev_dbg(dev, "CPG/MSSR clock domain not yet available\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) return -EPROBE_DEFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) &clkspec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) if (cpg_mssr_is_pm_clk(&clkspec, pd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) of_node_put(clkspec.np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) clk = of_clk_get_from_provider(&clkspec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) of_node_put(clkspec.np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) if (IS_ERR(clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) return PTR_ERR(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) error = pm_clk_create(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) goto fail_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) error = pm_clk_add_clk(dev, clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) goto fail_destroy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) fail_destroy:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) pm_clk_destroy(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) fail_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) clk_put(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) void cpg_mssr_detach_dev(struct generic_pm_domain *unused, struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) if (!pm_clk_no_clocks(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) pm_clk_destroy(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) static int __init cpg_mssr_add_clk_domain(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) const unsigned int *core_pm_clks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) unsigned int num_core_pm_clks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) struct device_node *np = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) struct generic_pm_domain *genpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) struct cpg_mssr_clk_domain *pd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) size_t pm_size = num_core_pm_clks * sizeof(core_pm_clks[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) pd = devm_kzalloc(dev, sizeof(*pd) + pm_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (!pd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) pd->num_core_pm_clks = num_core_pm_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) memcpy(pd->core_pm_clks, core_pm_clks, pm_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) genpd = &pd->genpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) genpd->name = np->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) genpd->flags = GENPD_FLAG_PM_CLK | GENPD_FLAG_ALWAYS_ON |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) GENPD_FLAG_ACTIVE_WAKEUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) genpd->attach_dev = cpg_mssr_attach_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) genpd->detach_dev = cpg_mssr_detach_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) pm_genpd_init(genpd, &pm_domain_always_on_gov, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) cpg_mssr_clk_domain = pd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) of_genpd_add_provider_simple(np, genpd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) #ifdef CONFIG_RESET_CONTROLLER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) #define rcdev_to_priv(x) container_of(x, struct cpg_mssr_priv, rcdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) static int cpg_mssr_reset(struct reset_controller_dev *rcdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) unsigned long id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) unsigned int reg = id / 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) unsigned int bit = id % 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) u32 bitmask = BIT(bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) dev_dbg(priv->dev, "reset %u%02u\n", reg, bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) /* Reset module */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) writel(bitmask, priv->base + priv->reset_regs[reg]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) /* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) udelay(35);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) /* Release module from reset state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) writel(bitmask, priv->base + priv->reset_clear_regs[reg]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) static int cpg_mssr_assert(struct reset_controller_dev *rcdev, unsigned long id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) unsigned int reg = id / 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) unsigned int bit = id % 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) u32 bitmask = BIT(bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) dev_dbg(priv->dev, "assert %u%02u\n", reg, bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) writel(bitmask, priv->base + priv->reset_regs[reg]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) return 0;
^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 cpg_mssr_deassert(struct reset_controller_dev *rcdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) unsigned long id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) unsigned int reg = id / 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) unsigned int bit = id % 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) u32 bitmask = BIT(bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) dev_dbg(priv->dev, "deassert %u%02u\n", reg, bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) writel(bitmask, priv->base + priv->reset_clear_regs[reg]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) static int cpg_mssr_status(struct reset_controller_dev *rcdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) unsigned long id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) unsigned int reg = id / 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) unsigned int bit = id % 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) u32 bitmask = BIT(bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) return !!(readl(priv->base + priv->reset_regs[reg]) & bitmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) static const struct reset_control_ops cpg_mssr_reset_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) .reset = cpg_mssr_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) .assert = cpg_mssr_assert,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) .deassert = cpg_mssr_deassert,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) .status = cpg_mssr_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) static int cpg_mssr_reset_xlate(struct reset_controller_dev *rcdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) const struct of_phandle_args *reset_spec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) unsigned int unpacked = reset_spec->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) unsigned int idx = MOD_CLK_PACK(unpacked);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) if (unpacked % 100 > 31 || idx >= rcdev->nr_resets) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) dev_err(priv->dev, "Invalid reset index %u\n", unpacked);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) return idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) static int cpg_mssr_reset_controller_register(struct cpg_mssr_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) priv->rcdev.ops = &cpg_mssr_reset_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) priv->rcdev.of_node = priv->dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) priv->rcdev.of_reset_n_cells = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) priv->rcdev.of_xlate = cpg_mssr_reset_xlate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) priv->rcdev.nr_resets = priv->num_mod_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) return devm_reset_controller_register(priv->dev, &priv->rcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) #else /* !CONFIG_RESET_CONTROLLER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) static inline int cpg_mssr_reset_controller_register(struct cpg_mssr_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) #endif /* !CONFIG_RESET_CONTROLLER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) static const struct of_device_id cpg_mssr_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) #ifdef CONFIG_CLK_R7S9210
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) .compatible = "renesas,r7s9210-cpg-mssr",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) .data = &r7s9210_cpg_mssr_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) #ifdef CONFIG_CLK_R8A7742
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) .compatible = "renesas,r8a7742-cpg-mssr",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) .data = &r8a7742_cpg_mssr_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) #ifdef CONFIG_CLK_R8A7743
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) .compatible = "renesas,r8a7743-cpg-mssr",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) .data = &r8a7743_cpg_mssr_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) /* RZ/G1N is (almost) identical to RZ/G1M w.r.t. clocks. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) .compatible = "renesas,r8a7744-cpg-mssr",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) .data = &r8a7743_cpg_mssr_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) #ifdef CONFIG_CLK_R8A7745
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) .compatible = "renesas,r8a7745-cpg-mssr",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) .data = &r8a7745_cpg_mssr_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) #ifdef CONFIG_CLK_R8A77470
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) .compatible = "renesas,r8a77470-cpg-mssr",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) .data = &r8a77470_cpg_mssr_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) #ifdef CONFIG_CLK_R8A774A1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) .compatible = "renesas,r8a774a1-cpg-mssr",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) .data = &r8a774a1_cpg_mssr_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) #ifdef CONFIG_CLK_R8A774B1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) .compatible = "renesas,r8a774b1-cpg-mssr",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) .data = &r8a774b1_cpg_mssr_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) #ifdef CONFIG_CLK_R8A774C0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) .compatible = "renesas,r8a774c0-cpg-mssr",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) .data = &r8a774c0_cpg_mssr_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) #ifdef CONFIG_CLK_R8A774E1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) .compatible = "renesas,r8a774e1-cpg-mssr",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) .data = &r8a774e1_cpg_mssr_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) #ifdef CONFIG_CLK_R8A7790
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) .compatible = "renesas,r8a7790-cpg-mssr",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) .data = &r8a7790_cpg_mssr_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) #ifdef CONFIG_CLK_R8A7791
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) .compatible = "renesas,r8a7791-cpg-mssr",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) .data = &r8a7791_cpg_mssr_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) /* R-Car M2-N is (almost) identical to R-Car M2-W w.r.t. clocks. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) .compatible = "renesas,r8a7793-cpg-mssr",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) .data = &r8a7791_cpg_mssr_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) #ifdef CONFIG_CLK_R8A7792
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) .compatible = "renesas,r8a7792-cpg-mssr",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) .data = &r8a7792_cpg_mssr_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) #ifdef CONFIG_CLK_R8A7794
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) .compatible = "renesas,r8a7794-cpg-mssr",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) .data = &r8a7794_cpg_mssr_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) #ifdef CONFIG_CLK_R8A7795
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) .compatible = "renesas,r8a7795-cpg-mssr",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) .data = &r8a7795_cpg_mssr_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) #ifdef CONFIG_CLK_R8A77960
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) .compatible = "renesas,r8a7796-cpg-mssr",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) .data = &r8a7796_cpg_mssr_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) #ifdef CONFIG_CLK_R8A77961
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) .compatible = "renesas,r8a77961-cpg-mssr",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) .data = &r8a7796_cpg_mssr_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) #ifdef CONFIG_CLK_R8A77965
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) .compatible = "renesas,r8a77965-cpg-mssr",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) .data = &r8a77965_cpg_mssr_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) #ifdef CONFIG_CLK_R8A77970
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) .compatible = "renesas,r8a77970-cpg-mssr",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) .data = &r8a77970_cpg_mssr_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) #ifdef CONFIG_CLK_R8A77980
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) .compatible = "renesas,r8a77980-cpg-mssr",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) .data = &r8a77980_cpg_mssr_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) #ifdef CONFIG_CLK_R8A77990
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) .compatible = "renesas,r8a77990-cpg-mssr",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) .data = &r8a77990_cpg_mssr_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) #ifdef CONFIG_CLK_R8A77995
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) .compatible = "renesas,r8a77995-cpg-mssr",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) .data = &r8a77995_cpg_mssr_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) #ifdef CONFIG_CLK_R8A779A0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) .compatible = "renesas,r8a779a0-cpg-mssr",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) .data = &r8a779a0_cpg_mssr_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) { /* sentinel */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) static void cpg_mssr_del_clk_provider(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) of_clk_del_provider(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM_PSCI_FW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) static int cpg_mssr_suspend_noirq(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) struct cpg_mssr_priv *priv = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) unsigned int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) /* This is the best we can do to check for the presence of PSCI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) if (!psci_ops.cpu_suspend)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) /* Save module registers with bits under our control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) for (reg = 0; reg < ARRAY_SIZE(priv->smstpcr_saved); reg++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) if (priv->smstpcr_saved[reg].mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) priv->smstpcr_saved[reg].val =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) priv->reg_layout == CLK_REG_LAYOUT_RZ_A ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) readb(priv->base + priv->control_regs[reg]) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) readl(priv->base + priv->control_regs[reg]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) /* Save core clocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) raw_notifier_call_chain(&priv->notifiers, PM_EVENT_SUSPEND, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) static int cpg_mssr_resume_noirq(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) struct cpg_mssr_priv *priv = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) unsigned int reg, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) u32 mask, oldval, newval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) /* This is the best we can do to check for the presence of PSCI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) if (!psci_ops.cpu_suspend)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) /* Restore core clocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) raw_notifier_call_chain(&priv->notifiers, PM_EVENT_RESUME, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) /* Restore module clocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) for (reg = 0; reg < ARRAY_SIZE(priv->smstpcr_saved); reg++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) mask = priv->smstpcr_saved[reg].mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) if (!mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) oldval = readb(priv->base + priv->control_regs[reg]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) oldval = readl(priv->base + priv->control_regs[reg]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) newval = oldval & ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) newval |= priv->smstpcr_saved[reg].val & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) if (newval == oldval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) writeb(newval, priv->base + priv->control_regs[reg]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) /* dummy read to ensure write has completed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) readb(priv->base + priv->control_regs[reg]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) barrier_data(priv->base + priv->control_regs[reg]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) writel(newval, priv->base + priv->control_regs[reg]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) /* Wait until enabled clocks are really enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) mask &= ~priv->smstpcr_saved[reg].val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) if (!mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) for (i = 1000; i > 0; --i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) oldval = readl(priv->base + priv->status_regs[reg]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) if (!(oldval & mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) if (!i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) dev_warn(dev, "Failed to enable %s%u[0x%x]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) priv->reg_layout == CLK_REG_LAYOUT_RZ_A ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) "STB" : "SMSTP", reg, oldval & mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) static const struct dev_pm_ops cpg_mssr_pm = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(cpg_mssr_suspend_noirq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) cpg_mssr_resume_noirq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) #define DEV_PM_OPS &cpg_mssr_pm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) #define DEV_PM_OPS NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) #endif /* CONFIG_PM_SLEEP && CONFIG_ARM_PSCI_FW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) static int __init cpg_mssr_common_init(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) const struct cpg_mssr_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) struct cpg_mssr_priv *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) unsigned int nclks, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) if (info->init) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) error = info->init(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) nclks = info->num_total_core_clks + info->num_hw_mod_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) priv = kzalloc(struct_size(priv, clks, nclks), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) if (!priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) priv->np = np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) priv->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) spin_lock_init(&priv->rmw_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) priv->base = of_iomap(np, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) if (!priv->base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) cpg_mssr_priv = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) priv->num_core_clks = info->num_total_core_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) priv->num_mod_clks = info->num_hw_mod_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) priv->last_dt_core_clk = info->last_dt_core_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) RAW_INIT_NOTIFIER_HEAD(&priv->notifiers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) priv->reg_layout = info->reg_layout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) if (priv->reg_layout == CLK_REG_LAYOUT_RCAR_GEN2_AND_GEN3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) priv->status_regs = mstpsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) priv->control_regs = smstpcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) priv->reset_regs = srcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) priv->reset_clear_regs = srstclr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) } else if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) priv->control_regs = stbcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) } else if (priv->reg_layout == CLK_REG_LAYOUT_RCAR_V3U) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) priv->status_regs = mstpsr_for_v3u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) priv->control_regs = mstpcr_for_v3u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) priv->reset_regs = srcr_for_v3u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) priv->reset_clear_regs = srstclr_for_v3u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) for (i = 0; i < nclks; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) priv->clks[i] = ERR_PTR(-ENOENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) error = of_clk_add_provider(np, cpg_mssr_clk_src_twocell_get, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) if (priv->base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) iounmap(priv->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) kfree(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) void __init cpg_mssr_early_init(struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) const struct cpg_mssr_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) error = cpg_mssr_common_init(NULL, np, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) for (i = 0; i < info->num_early_core_clks; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) cpg_mssr_register_core_clk(&info->early_core_clks[i], info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) cpg_mssr_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) for (i = 0; i < info->num_early_mod_clks; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) cpg_mssr_register_mod_clk(&info->early_mod_clks[i], info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) cpg_mssr_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) static int __init cpg_mssr_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) struct device_node *np = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) const struct cpg_mssr_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) struct cpg_mssr_priv *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) info = of_device_get_match_data(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) if (!cpg_mssr_priv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) error = cpg_mssr_common_init(dev, dev->of_node, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) priv = cpg_mssr_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) priv->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) dev_set_drvdata(dev, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) for (i = 0; i < info->num_core_clks; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) cpg_mssr_register_core_clk(&info->core_clks[i], info, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) for (i = 0; i < info->num_mod_clks; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) cpg_mssr_register_mod_clk(&info->mod_clks[i], info, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) error = devm_add_action_or_reset(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) cpg_mssr_del_clk_provider,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) error = cpg_mssr_add_clk_domain(dev, info->core_pm_clks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) info->num_core_pm_clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) /* Reset Controller not supported for Standby Control SoCs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) error = cpg_mssr_reset_controller_register(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) static struct platform_driver cpg_mssr_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) .name = "renesas-cpg-mssr",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) .of_match_table = cpg_mssr_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) .pm = DEV_PM_OPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) static int __init cpg_mssr_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) return platform_driver_probe(&cpg_mssr_driver, cpg_mssr_probe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) subsys_initcall(cpg_mssr_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) void __init cpg_core_nullify_range(struct cpg_core_clk *core_clks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) unsigned int num_core_clks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) unsigned int first_clk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) unsigned int last_clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) for (i = 0; i < num_core_clks; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) if (core_clks[i].id >= first_clk &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) core_clks[i].id <= last_clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) core_clks[i].name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) void __init mssr_mod_nullify(struct mssr_mod_clk *mod_clks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) unsigned int num_mod_clks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) const unsigned int *clks, unsigned int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) unsigned int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) for (i = 0, j = 0; i < num_mod_clks && j < n; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) if (mod_clks[i].id == clks[j]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) mod_clks[i].name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) j++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) void __init mssr_mod_reparent(struct mssr_mod_clk *mod_clks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) unsigned int num_mod_clks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) const struct mssr_mod_reparent *clks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) unsigned int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) unsigned int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) for (i = 0, j = 0; i < num_mod_clks && j < n; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) if (mod_clks[i].id == clks[j].clk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) mod_clks[i].parent = clks[j].parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) j++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) MODULE_DESCRIPTION("Renesas CPG/MSSR Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) MODULE_LICENSE("GPL v2");