Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

clk: baikal-t1: Remove not-going-to-be-supported code for Baikal SoC

As noticed in the discussion [1] the Baikal SoC and platforms
are not going to be finalized, hence remove stale code.

Reviewed-by: Brian Masney <bmasney@redhat.com>
Link: https://lore.kernel.org/lkml/22b92ddf-6321-41b5-8073-f9c7064d3432@infradead.org/ [1]
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Rob Herring (Arm) <robh@kernel.org>
Reviewed-by: Randy Dunlap <rdunlap@infradead.org>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>

authored by

Andy Shevchenko and committed by
Stephen Boyd
5d6c4776 4d0f627a

-2920
-196
Documentation/devicetree/bindings/clock/baikal,bt1-ccu-div.yaml
··· 1 - # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 - # Copyright (C) 2020 BAIKAL ELECTRONICS, JSC 3 - %YAML 1.2 4 - --- 5 - $id: http://devicetree.org/schemas/clock/baikal,bt1-ccu-div.yaml# 6 - $schema: http://devicetree.org/meta-schemas/core.yaml# 7 - 8 - title: Baikal-T1 Clock Control Unit Dividers 9 - 10 - maintainers: 11 - - Serge Semin <fancer.lancer@gmail.com> 12 - 13 - description: | 14 - Clocks Control Unit is the core of Baikal-T1 SoC System Controller 15 - responsible for the chip subsystems clocking and resetting. The CCU is 16 - connected with an external fixed rate oscillator, which signal is transformed 17 - into clocks of various frequencies and then propagated to either individual 18 - IP-blocks or to groups of blocks (clock domains). The transformation is done 19 - by means of an embedded into CCU PLLs and gateable/non-gateable dividers. The 20 - later ones are described in this binding. Each clock domain can be also 21 - individually reset by using the domain clocks divider configuration 22 - registers. Baikal-T1 CCU is logically divided into the next components: 23 - 1) External oscillator (normally XTAL's 25 MHz crystal oscillator, but 24 - in general can provide any frequency supported by the CCU PLLs). 25 - 2) PLLs clocks generators (PLLs). 26 - 3) AXI-bus clock dividers (AXI) - described in this binding file. 27 - 4) System devices reference clock dividers (SYS) - described in this binding 28 - file. 29 - which are connected with each other as shown on the next figure: 30 - 31 - +---------------+ 32 - | Baikal-T1 CCU | 33 - | +----+------|- MIPS P5600 cores 34 - | +-|PLLs|------|- DDR controller 35 - | | +----+ | 36 - +----+ | | | | | 37 - |XTAL|--|-+ | | +---+-| 38 - +----+ | | | +-|AXI|-|- AXI-bus 39 - | | | +---+-| 40 - | | | | 41 - | | +----+---+-|- APB-bus 42 - | +-------|SYS|-|- Low-speed Devices 43 - | +---+-|- High-speed Devices 44 - +---------------+ 45 - 46 - Each sub-block is represented as a separate DT node and has an individual 47 - driver to be bound with. 48 - 49 - In order to create signals of wide range frequencies the external oscillator 50 - output is primarily connected to a set of CCU PLLs. Some of PLLs CLKOUT are 51 - then passed over CCU dividers to create signals required for the target clock 52 - domain (like AXI-bus or System Device consumers). The dividers have the 53 - following structure: 54 - 55 - +--------------+ 56 - CLKIN --|->+----+ 1|\ | 57 - SETCLK--|--|/DIV|->| | | 58 - CLKDIV--|--| | | |-|->CLKLOUT 59 - LOCK----|--+----+ | | | 60 - | |/ | 61 - | | | 62 - EN------|-----------+ | 63 - RST-----|--------------|->RSTOUT 64 - +--------------+ 65 - 66 - where CLKIN is the reference clock coming either from CCU PLLs or from an 67 - external clock oscillator, SETCLK - a command to update the output clock in 68 - accordance with a set divider, CLKDIV - clocks divider, LOCK - a signal of 69 - the output clock stabilization, EN - enable/disable the divider block, 70 - RST/RSTOUT - reset clocks domain signal. Depending on the consumer IP-core 71 - peculiarities the dividers may lack of some functionality depicted on the 72 - figure above (like EN, CLKDIV/LOCK/SETCLK). In this case the corresponding 73 - clock provider just doesn't expose either switching functions, or the rate 74 - configuration, or both of them. 75 - 76 - The clock dividers, which output clock is then consumed by the SoC individual 77 - devices, are united into a single clocks provider called System Devices CCU. 78 - Similarly the dividers with output clocks utilized as AXI-bus reference clocks 79 - are called AXI-bus CCU. Both of them use the common clock bindings with no 80 - custom properties. The list of exported clocks and reset signals can be found 81 - in the files: 'include/dt-bindings/clock/bt1-ccu.h' and 82 - 'include/dt-bindings/reset/bt1-ccu.h'. Since System Devices and AXI-bus CCU 83 - are a part of the Baikal-T1 SoC System Controller their DT nodes are supposed 84 - to be a children of later one. 85 - 86 - if: 87 - properties: 88 - compatible: 89 - contains: 90 - const: baikal,bt1-ccu-axi 91 - 92 - then: 93 - properties: 94 - clocks: 95 - items: 96 - - description: CCU SATA PLL output clock 97 - - description: CCU PCIe PLL output clock 98 - - description: CCU Ethernet PLL output clock 99 - 100 - clock-names: 101 - items: 102 - - const: sata_clk 103 - - const: pcie_clk 104 - - const: eth_clk 105 - 106 - else: 107 - properties: 108 - clocks: 109 - items: 110 - - description: External reference clock 111 - - description: CCU SATA PLL output clock 112 - - description: CCU PCIe PLL output clock 113 - - description: CCU Ethernet PLL output clock 114 - 115 - clock-names: 116 - items: 117 - - const: ref_clk 118 - - const: sata_clk 119 - - const: pcie_clk 120 - - const: eth_clk 121 - 122 - properties: 123 - compatible: 124 - enum: 125 - - baikal,bt1-ccu-axi 126 - - baikal,bt1-ccu-sys 127 - 128 - reg: 129 - maxItems: 1 130 - 131 - "#clock-cells": 132 - const: 1 133 - 134 - "#reset-cells": 135 - const: 1 136 - 137 - clocks: 138 - minItems: 3 139 - maxItems: 4 140 - 141 - clock-names: 142 - minItems: 3 143 - maxItems: 4 144 - 145 - additionalProperties: false 146 - 147 - required: 148 - - compatible 149 - - "#clock-cells" 150 - - clocks 151 - - clock-names 152 - 153 - examples: 154 - # AXI-bus Clock Control Unit node: 155 - - | 156 - #include <dt-bindings/clock/bt1-ccu.h> 157 - 158 - clock-controller@1f04d030 { 159 - compatible = "baikal,bt1-ccu-axi"; 160 - reg = <0x1f04d030 0x030>; 161 - #clock-cells = <1>; 162 - #reset-cells = <1>; 163 - 164 - clocks = <&ccu_pll CCU_SATA_PLL>, 165 - <&ccu_pll CCU_PCIE_PLL>, 166 - <&ccu_pll CCU_ETH_PLL>; 167 - clock-names = "sata_clk", "pcie_clk", "eth_clk"; 168 - }; 169 - # System Devices Clock Control Unit node: 170 - - | 171 - #include <dt-bindings/clock/bt1-ccu.h> 172 - 173 - clock-controller@1f04d060 { 174 - compatible = "baikal,bt1-ccu-sys"; 175 - reg = <0x1f04d060 0x0a0>; 176 - #clock-cells = <1>; 177 - #reset-cells = <1>; 178 - 179 - clocks = <&clk25m>, 180 - <&ccu_pll CCU_SATA_PLL>, 181 - <&ccu_pll CCU_PCIE_PLL>, 182 - <&ccu_pll CCU_ETH_PLL>; 183 - clock-names = "ref_clk", "sata_clk", "pcie_clk", 184 - "eth_clk"; 185 - }; 186 - # Required Clock Control Unit PLL node: 187 - - | 188 - ccu_pll: clock-controller@1f04d000 { 189 - compatible = "baikal,bt1-ccu-pll"; 190 - reg = <0x1f04d000 0x028>; 191 - #clock-cells = <1>; 192 - 193 - clocks = <&clk25m>; 194 - clock-names = "ref_clk"; 195 - }; 196 - ...
-131
Documentation/devicetree/bindings/clock/baikal,bt1-ccu-pll.yaml
··· 1 - # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 - # Copyright (C) 2020 BAIKAL ELECTRONICS, JSC 3 - %YAML 1.2 4 - --- 5 - $id: http://devicetree.org/schemas/clock/baikal,bt1-ccu-pll.yaml# 6 - $schema: http://devicetree.org/meta-schemas/core.yaml# 7 - 8 - title: Baikal-T1 Clock Control Unit PLL 9 - 10 - maintainers: 11 - - Serge Semin <fancer.lancer@gmail.com> 12 - 13 - description: | 14 - Clocks Control Unit is the core of Baikal-T1 SoC System Controller 15 - responsible for the chip subsystems clocking and resetting. The CCU is 16 - connected with an external fixed rate oscillator, which signal is transformed 17 - into clocks of various frequencies and then propagated to either individual 18 - IP-blocks or to groups of blocks (clock domains). The transformation is done 19 - by means of PLLs and gateable/non-gateable dividers embedded into the CCU. 20 - It's logically divided into the next components: 21 - 1) External oscillator (normally XTAL's 25 MHz crystal oscillator, but 22 - in general can provide any frequency supported by the CCU PLLs). 23 - 2) PLLs clocks generators (PLLs) - described in this binding file. 24 - 3) AXI-bus clock dividers (AXI). 25 - 4) System devices reference clock dividers (SYS). 26 - which are connected with each other as shown on the next figure: 27 - 28 - +---------------+ 29 - | Baikal-T1 CCU | 30 - | +----+------|- MIPS P5600 cores 31 - | +-|PLLs|------|- DDR controller 32 - | | +----+ | 33 - +----+ | | | | | 34 - |XTAL|--|-+ | | +---+-| 35 - +----+ | | | +-|AXI|-|- AXI-bus 36 - | | | +---+-| 37 - | | | | 38 - | | +----+---+-|- APB-bus 39 - | +-------|SYS|-|- Low-speed Devices 40 - | +---+-|- High-speed Devices 41 - +---------------+ 42 - 43 - Each CCU sub-block is represented as a separate dts-node and has an 44 - individual driver to be bound with. 45 - 46 - In order to create signals of wide range frequencies the external oscillator 47 - output is primarily connected to a set of CCU PLLs. There are five PLLs 48 - to create a clock for the MIPS P5600 cores, the embedded DDR controller, 49 - SATA, Ethernet and PCIe domains. The last three domains though named by the 50 - biggest system interfaces in fact include nearly all of the rest SoC 51 - peripherals. Each of the PLLs is based on True Circuits TSMC CLN28HPM core 52 - with an interface wrapper (so called safe PLL' clocks switcher) to simplify 53 - the PLL configuration procedure. The PLLs work as depicted on the next 54 - diagram: 55 - 56 - +--------------------------+ 57 - | | 58 - +-->+---+ +---+ +---+ | +---+ 0|\ 59 - CLKF--->|/NF|--->|PFD|...|VCO|-+->|/OD|--->| | 60 - +---+ +->+---+ +---+ /->+---+ | |--->CLKOUT 61 - CLKOD---------C----------------+ 1| | 62 - +--------C--------------------------->|/ 63 - | | ^ 64 - Rclk-+->+---+ | | 65 - CLKR--->|/NR|-+ | 66 - +---+ | 67 - BYPASS--------------------------------------+ 68 - BWADJ---> 69 - 70 - where Rclk is the reference clock coming from XTAL, NR - reference clock 71 - divider, NF - PLL clock multiplier, OD - VCO output clock divider, CLKOUT - 72 - output clock, BWADJ is the PLL bandwidth adjustment parameter. At this moment 73 - the binding supports the PLL dividers configuration in accordance with a 74 - requested rate, while bypassing and bandwidth adjustment settings can be 75 - added in future if it gets to be necessary. 76 - 77 - The PLLs CLKOUT is then either directly connected with the corresponding 78 - clocks consumer (like P5600 cores or DDR controller) or passed over a CCU 79 - divider to create a signal required for the clock domain. 80 - 81 - The CCU PLL dts-node uses the common clock bindings with no custom 82 - parameters. The list of exported clocks can be found in 83 - 'include/dt-bindings/clock/bt1-ccu.h'. Since CCU PLL is a part of the 84 - Baikal-T1 SoC System Controller its DT node is supposed to be a child of 85 - later one. 86 - 87 - properties: 88 - compatible: 89 - const: baikal,bt1-ccu-pll 90 - 91 - reg: 92 - maxItems: 1 93 - 94 - "#clock-cells": 95 - const: 1 96 - 97 - clocks: 98 - description: External reference clock 99 - maxItems: 1 100 - 101 - clock-names: 102 - const: ref_clk 103 - 104 - additionalProperties: false 105 - 106 - required: 107 - - compatible 108 - - "#clock-cells" 109 - - clocks 110 - - clock-names 111 - 112 - examples: 113 - # Clock Control Unit PLL node: 114 - - | 115 - clock-controller@1f04d000 { 116 - compatible = "baikal,bt1-ccu-pll"; 117 - reg = <0x1f04d000 0x028>; 118 - #clock-cells = <1>; 119 - 120 - clocks = <&clk25m>; 121 - clock-names = "ref_clk"; 122 - }; 123 - # Required external oscillator: 124 - - | 125 - clk25m: clock-oscillator-25m { 126 - compatible = "fixed-clock"; 127 - #clock-cells = <0>; 128 - clock-frequency = <25000000>; 129 - clock-output-names = "clk25m"; 130 - }; 131 - ...
-1
drivers/clk/Kconfig
··· 502 502 source "drivers/clk/actions/Kconfig" 503 503 source "drivers/clk/analogbits/Kconfig" 504 504 source "drivers/clk/aspeed/Kconfig" 505 - source "drivers/clk/baikal-t1/Kconfig" 506 505 source "drivers/clk/bcm/Kconfig" 507 506 source "drivers/clk/hisilicon/Kconfig" 508 507 source "drivers/clk/imgtec/Kconfig"
-1
drivers/clk/Makefile
··· 116 116 obj-$(CONFIG_COMMON_CLK_AT91) += at91/ 117 117 obj-$(CONFIG_ARCH_ARTPEC) += axis/ 118 118 obj-$(CONFIG_ARC_PLAT_AXS10X) += axs10x/ 119 - obj-$(CONFIG_CLK_BAIKAL_T1) += baikal-t1/ 120 119 obj-y += bcm/ 121 120 obj-$(CONFIG_ARCH_BERLIN) += berlin/ 122 121 obj-$(CONFIG_ARCH_DAVINCI) += davinci/
-52
drivers/clk/baikal-t1/Kconfig
··· 1 - # SPDX-License-Identifier: GPL-2.0-only 2 - config CLK_BAIKAL_T1 3 - bool "Baikal-T1 Clocks Control Unit interface" 4 - depends on (MIPS_BAIKAL_T1 && OF) || COMPILE_TEST 5 - default MIPS_BAIKAL_T1 6 - help 7 - Clocks Control Unit is the core of Baikal-T1 SoC System Controller 8 - responsible for the chip subsystems clocking and resetting. It 9 - consists of multiple global clock domains, which can be reset by 10 - means of the CCU control registers. These domains and devices placed 11 - in them are fed with clocks generated by a hierarchy of PLLs, 12 - configurable and fixed clock dividers. Enable this option to be able 13 - to select Baikal-T1 CCU PLLs and Dividers drivers. 14 - 15 - if CLK_BAIKAL_T1 16 - 17 - config CLK_BT1_CCU_PLL 18 - bool "Baikal-T1 CCU PLLs support" 19 - select MFD_SYSCON 20 - default MIPS_BAIKAL_T1 21 - help 22 - Enable this to support the PLLs embedded into the Baikal-T1 SoC 23 - System Controller. These are five PLLs placed at the root of the 24 - clocks hierarchy, right after an external reference oscillator 25 - (normally of 25MHz). They are used to generate high frequency 26 - signals, which are either directly wired to the consumers (like 27 - CPUs, DDR, etc.) or passed over the clock dividers to be only 28 - then used as an individual reference clock of a target device. 29 - 30 - config CLK_BT1_CCU_DIV 31 - bool "Baikal-T1 CCU Dividers support" 32 - select MFD_SYSCON 33 - default MIPS_BAIKAL_T1 34 - help 35 - Enable this to support the CCU dividers used to distribute clocks 36 - between AXI-bus and system devices coming from CCU PLLs of Baikal-T1 37 - SoC. CCU dividers can be either configurable or with fixed divider, 38 - either gateable or ungateable. Some of the CCU dividers can be as well 39 - used to reset the domains they're supplying clock to. 40 - 41 - config CLK_BT1_CCU_RST 42 - bool "Baikal-T1 CCU Resets support" 43 - select RESET_CONTROLLER 44 - select MFD_SYSCON 45 - default MIPS_BAIKAL_T1 46 - help 47 - Enable this to support the CCU reset blocks responsible for the 48 - AXI-bus and some subsystems reset. These are mainly the 49 - self-deasserted reset controls but there are several lines which 50 - can be directly asserted/de-asserted (PCIe and DDR sub-domains). 51 - 52 - endif
-4
drivers/clk/baikal-t1/Makefile
··· 1 - # SPDX-License-Identifier: GPL-2.0-only 2 - obj-$(CONFIG_CLK_BT1_CCU_PLL) += ccu-pll.o clk-ccu-pll.o 3 - obj-$(CONFIG_CLK_BT1_CCU_DIV) += ccu-div.o clk-ccu-div.o 4 - obj-$(CONFIG_CLK_BT1_CCU_RST) += ccu-rst.o
-653
drivers/clk/baikal-t1/ccu-div.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC 4 - * 5 - * Authors: 6 - * Serge Semin <Sergey.Semin@baikalelectronics.ru> 7 - * Dmitry Dunaev <dmitry.dunaev@baikalelectronics.ru> 8 - * 9 - * Baikal-T1 CCU Dividers interface driver 10 - */ 11 - 12 - #define pr_fmt(fmt) "bt1-ccu-div: " fmt 13 - 14 - #include <linux/kernel.h> 15 - #include <linux/printk.h> 16 - #include <linux/bits.h> 17 - #include <linux/bitfield.h> 18 - #include <linux/slab.h> 19 - #include <linux/clk-provider.h> 20 - #include <linux/of.h> 21 - #include <linux/spinlock.h> 22 - #include <linux/regmap.h> 23 - #include <linux/delay.h> 24 - #include <linux/time64.h> 25 - #include <linux/debugfs.h> 26 - 27 - #include "ccu-div.h" 28 - 29 - #define CCU_DIV_CTL 0x00 30 - #define CCU_DIV_CTL_EN BIT(0) 31 - #define CCU_DIV_CTL_RST BIT(1) 32 - #define CCU_DIV_CTL_SET_CLKDIV BIT(2) 33 - #define CCU_DIV_CTL_CLKDIV_FLD 4 34 - #define CCU_DIV_CTL_CLKDIV_MASK(_width) \ 35 - GENMASK((_width) + CCU_DIV_CTL_CLKDIV_FLD - 1, CCU_DIV_CTL_CLKDIV_FLD) 36 - #define CCU_DIV_CTL_LOCK_SHIFTED BIT(27) 37 - #define CCU_DIV_CTL_GATE_REF_BUF BIT(28) 38 - #define CCU_DIV_CTL_LOCK_NORMAL BIT(31) 39 - 40 - #define CCU_DIV_LOCK_CHECK_RETRIES 50 41 - 42 - #define CCU_DIV_CLKDIV_MIN 0 43 - #define CCU_DIV_CLKDIV_MAX(_mask) \ 44 - ((_mask) >> CCU_DIV_CTL_CLKDIV_FLD) 45 - 46 - /* 47 - * Use the next two methods until there are generic field setter and 48 - * getter available with non-constant mask support. 49 - */ 50 - static inline u32 ccu_div_get(u32 mask, u32 val) 51 - { 52 - return (val & mask) >> CCU_DIV_CTL_CLKDIV_FLD; 53 - } 54 - 55 - static inline u32 ccu_div_prep(u32 mask, u32 val) 56 - { 57 - return (val << CCU_DIV_CTL_CLKDIV_FLD) & mask; 58 - } 59 - 60 - static inline unsigned long ccu_div_lock_delay_ns(unsigned long ref_clk, 61 - unsigned long div) 62 - { 63 - u64 ns = 4ULL * (div ?: 1) * NSEC_PER_SEC; 64 - 65 - do_div(ns, ref_clk); 66 - 67 - return ns; 68 - } 69 - 70 - static inline unsigned long ccu_div_calc_freq(unsigned long ref_clk, 71 - unsigned long div) 72 - { 73 - return ref_clk / (div ?: 1); 74 - } 75 - 76 - static int ccu_div_var_update_clkdiv(struct ccu_div *div, 77 - unsigned long parent_rate, 78 - unsigned long divider) 79 - { 80 - unsigned long nd; 81 - u32 val = 0; 82 - u32 lock; 83 - int count; 84 - 85 - nd = ccu_div_lock_delay_ns(parent_rate, divider); 86 - 87 - if (div->features & CCU_DIV_LOCK_SHIFTED) 88 - lock = CCU_DIV_CTL_LOCK_SHIFTED; 89 - else 90 - lock = CCU_DIV_CTL_LOCK_NORMAL; 91 - 92 - regmap_update_bits(div->sys_regs, div->reg_ctl, 93 - CCU_DIV_CTL_SET_CLKDIV, CCU_DIV_CTL_SET_CLKDIV); 94 - 95 - /* 96 - * Until there is nsec-version of readl_poll_timeout() is available 97 - * we have to implement the next polling loop. 98 - */ 99 - count = CCU_DIV_LOCK_CHECK_RETRIES; 100 - do { 101 - ndelay(nd); 102 - regmap_read(div->sys_regs, div->reg_ctl, &val); 103 - if (val & lock) 104 - return 0; 105 - } while (--count); 106 - 107 - return -ETIMEDOUT; 108 - } 109 - 110 - static int ccu_div_var_enable(struct clk_hw *hw) 111 - { 112 - struct clk_hw *parent_hw = clk_hw_get_parent(hw); 113 - struct ccu_div *div = to_ccu_div(hw); 114 - unsigned long flags; 115 - u32 val = 0; 116 - int ret; 117 - 118 - if (!parent_hw) { 119 - pr_err("Can't enable '%s' with no parent", clk_hw_get_name(hw)); 120 - return -EINVAL; 121 - } 122 - 123 - regmap_read(div->sys_regs, div->reg_ctl, &val); 124 - if (val & CCU_DIV_CTL_EN) 125 - return 0; 126 - 127 - spin_lock_irqsave(&div->lock, flags); 128 - ret = ccu_div_var_update_clkdiv(div, clk_hw_get_rate(parent_hw), 129 - ccu_div_get(div->mask, val)); 130 - if (!ret) 131 - regmap_update_bits(div->sys_regs, div->reg_ctl, 132 - CCU_DIV_CTL_EN, CCU_DIV_CTL_EN); 133 - spin_unlock_irqrestore(&div->lock, flags); 134 - if (ret) 135 - pr_err("Divider '%s' lock timed out\n", clk_hw_get_name(hw)); 136 - 137 - return ret; 138 - } 139 - 140 - static int ccu_div_gate_enable(struct clk_hw *hw) 141 - { 142 - struct ccu_div *div = to_ccu_div(hw); 143 - unsigned long flags; 144 - 145 - spin_lock_irqsave(&div->lock, flags); 146 - regmap_update_bits(div->sys_regs, div->reg_ctl, 147 - CCU_DIV_CTL_EN, CCU_DIV_CTL_EN); 148 - spin_unlock_irqrestore(&div->lock, flags); 149 - 150 - return 0; 151 - } 152 - 153 - static void ccu_div_gate_disable(struct clk_hw *hw) 154 - { 155 - struct ccu_div *div = to_ccu_div(hw); 156 - unsigned long flags; 157 - 158 - spin_lock_irqsave(&div->lock, flags); 159 - regmap_update_bits(div->sys_regs, div->reg_ctl, CCU_DIV_CTL_EN, 0); 160 - spin_unlock_irqrestore(&div->lock, flags); 161 - } 162 - 163 - static int ccu_div_gate_is_enabled(struct clk_hw *hw) 164 - { 165 - struct ccu_div *div = to_ccu_div(hw); 166 - u32 val = 0; 167 - 168 - regmap_read(div->sys_regs, div->reg_ctl, &val); 169 - 170 - return !!(val & CCU_DIV_CTL_EN); 171 - } 172 - 173 - static int ccu_div_buf_enable(struct clk_hw *hw) 174 - { 175 - struct ccu_div *div = to_ccu_div(hw); 176 - unsigned long flags; 177 - 178 - spin_lock_irqsave(&div->lock, flags); 179 - regmap_update_bits(div->sys_regs, div->reg_ctl, 180 - CCU_DIV_CTL_GATE_REF_BUF, 0); 181 - spin_unlock_irqrestore(&div->lock, flags); 182 - 183 - return 0; 184 - } 185 - 186 - static void ccu_div_buf_disable(struct clk_hw *hw) 187 - { 188 - struct ccu_div *div = to_ccu_div(hw); 189 - unsigned long flags; 190 - 191 - spin_lock_irqsave(&div->lock, flags); 192 - regmap_update_bits(div->sys_regs, div->reg_ctl, 193 - CCU_DIV_CTL_GATE_REF_BUF, CCU_DIV_CTL_GATE_REF_BUF); 194 - spin_unlock_irqrestore(&div->lock, flags); 195 - } 196 - 197 - static int ccu_div_buf_is_enabled(struct clk_hw *hw) 198 - { 199 - struct ccu_div *div = to_ccu_div(hw); 200 - u32 val = 0; 201 - 202 - regmap_read(div->sys_regs, div->reg_ctl, &val); 203 - 204 - return !(val & CCU_DIV_CTL_GATE_REF_BUF); 205 - } 206 - 207 - static unsigned long ccu_div_var_recalc_rate(struct clk_hw *hw, 208 - unsigned long parent_rate) 209 - { 210 - struct ccu_div *div = to_ccu_div(hw); 211 - unsigned long divider; 212 - u32 val = 0; 213 - 214 - regmap_read(div->sys_regs, div->reg_ctl, &val); 215 - divider = ccu_div_get(div->mask, val); 216 - 217 - return ccu_div_calc_freq(parent_rate, divider); 218 - } 219 - 220 - static inline unsigned long ccu_div_var_calc_divider(unsigned long rate, 221 - unsigned long parent_rate, 222 - unsigned int mask) 223 - { 224 - unsigned long divider; 225 - 226 - divider = parent_rate / rate; 227 - return clamp_t(unsigned long, divider, CCU_DIV_CLKDIV_MIN, 228 - CCU_DIV_CLKDIV_MAX(mask)); 229 - } 230 - 231 - static int ccu_div_var_determine_rate(struct clk_hw *hw, 232 - struct clk_rate_request *req) 233 - { 234 - struct ccu_div *div = to_ccu_div(hw); 235 - unsigned long divider; 236 - 237 - divider = ccu_div_var_calc_divider(req->rate, req->best_parent_rate, 238 - div->mask); 239 - 240 - req->rate = ccu_div_calc_freq(req->best_parent_rate, divider); 241 - 242 - return 0; 243 - } 244 - 245 - /* 246 - * This method is used for the clock divider blocks, which support the 247 - * on-the-fly rate change. So due to lacking the EN bit functionality 248 - * they can't be gated before the rate adjustment. 249 - */ 250 - static int ccu_div_var_set_rate_slow(struct clk_hw *hw, unsigned long rate, 251 - unsigned long parent_rate) 252 - { 253 - struct ccu_div *div = to_ccu_div(hw); 254 - unsigned long flags, divider; 255 - u32 val; 256 - int ret; 257 - 258 - divider = ccu_div_var_calc_divider(rate, parent_rate, div->mask); 259 - if (divider == 1 && div->features & CCU_DIV_SKIP_ONE) { 260 - divider = 0; 261 - } else if (div->features & CCU_DIV_SKIP_ONE_TO_THREE) { 262 - if (divider == 1 || divider == 2) 263 - divider = 0; 264 - else if (divider == 3) 265 - divider = 4; 266 - } 267 - 268 - val = ccu_div_prep(div->mask, divider); 269 - 270 - spin_lock_irqsave(&div->lock, flags); 271 - regmap_update_bits(div->sys_regs, div->reg_ctl, div->mask, val); 272 - ret = ccu_div_var_update_clkdiv(div, parent_rate, divider); 273 - spin_unlock_irqrestore(&div->lock, flags); 274 - if (ret) 275 - pr_err("Divider '%s' lock timed out\n", clk_hw_get_name(hw)); 276 - 277 - return ret; 278 - } 279 - 280 - /* 281 - * This method is used for the clock divider blocks, which don't support 282 - * the on-the-fly rate change. 283 - */ 284 - static int ccu_div_var_set_rate_fast(struct clk_hw *hw, unsigned long rate, 285 - unsigned long parent_rate) 286 - { 287 - struct ccu_div *div = to_ccu_div(hw); 288 - unsigned long flags, divider; 289 - u32 val; 290 - 291 - divider = ccu_div_var_calc_divider(rate, parent_rate, div->mask); 292 - val = ccu_div_prep(div->mask, divider); 293 - 294 - /* 295 - * Also disable the clock divider block if it was enabled by default 296 - * or by the bootloader. 297 - */ 298 - spin_lock_irqsave(&div->lock, flags); 299 - regmap_update_bits(div->sys_regs, div->reg_ctl, 300 - div->mask | CCU_DIV_CTL_EN, val); 301 - spin_unlock_irqrestore(&div->lock, flags); 302 - 303 - return 0; 304 - } 305 - 306 - static unsigned long ccu_div_fixed_recalc_rate(struct clk_hw *hw, 307 - unsigned long parent_rate) 308 - { 309 - struct ccu_div *div = to_ccu_div(hw); 310 - 311 - return ccu_div_calc_freq(parent_rate, div->divider); 312 - } 313 - 314 - static int ccu_div_fixed_determine_rate(struct clk_hw *hw, 315 - struct clk_rate_request *req) 316 - { 317 - struct ccu_div *div = to_ccu_div(hw); 318 - 319 - req->rate = ccu_div_calc_freq(req->best_parent_rate, div->divider); 320 - 321 - return 0; 322 - } 323 - 324 - static int ccu_div_fixed_set_rate(struct clk_hw *hw, unsigned long rate, 325 - unsigned long parent_rate) 326 - { 327 - return 0; 328 - } 329 - 330 - #ifdef CONFIG_DEBUG_FS 331 - 332 - struct ccu_div_dbgfs_bit { 333 - struct ccu_div *div; 334 - const char *name; 335 - u32 mask; 336 - }; 337 - 338 - #define CCU_DIV_DBGFS_BIT_ATTR(_name, _mask) { \ 339 - .name = _name, \ 340 - .mask = _mask \ 341 - } 342 - 343 - static const struct ccu_div_dbgfs_bit ccu_div_bits[] = { 344 - CCU_DIV_DBGFS_BIT_ATTR("div_en", CCU_DIV_CTL_EN), 345 - CCU_DIV_DBGFS_BIT_ATTR("div_rst", CCU_DIV_CTL_RST), 346 - CCU_DIV_DBGFS_BIT_ATTR("div_bypass", CCU_DIV_CTL_SET_CLKDIV), 347 - CCU_DIV_DBGFS_BIT_ATTR("div_buf", CCU_DIV_CTL_GATE_REF_BUF), 348 - CCU_DIV_DBGFS_BIT_ATTR("div_lock", CCU_DIV_CTL_LOCK_NORMAL) 349 - }; 350 - 351 - #define CCU_DIV_DBGFS_BIT_NUM ARRAY_SIZE(ccu_div_bits) 352 - 353 - /* 354 - * It can be dangerous to change the Divider settings behind clock framework 355 - * back, therefore we don't provide any kernel config based compile time option 356 - * for this feature to enable. 357 - */ 358 - #undef CCU_DIV_ALLOW_WRITE_DEBUGFS 359 - #ifdef CCU_DIV_ALLOW_WRITE_DEBUGFS 360 - 361 - static int ccu_div_dbgfs_bit_set(void *priv, u64 val) 362 - { 363 - const struct ccu_div_dbgfs_bit *bit = priv; 364 - struct ccu_div *div = bit->div; 365 - unsigned long flags; 366 - 367 - spin_lock_irqsave(&div->lock, flags); 368 - regmap_update_bits(div->sys_regs, div->reg_ctl, 369 - bit->mask, val ? bit->mask : 0); 370 - spin_unlock_irqrestore(&div->lock, flags); 371 - 372 - return 0; 373 - } 374 - 375 - static int ccu_div_dbgfs_var_clkdiv_set(void *priv, u64 val) 376 - { 377 - struct ccu_div *div = priv; 378 - unsigned long flags; 379 - u32 data; 380 - 381 - val = clamp_t(u64, val, CCU_DIV_CLKDIV_MIN, 382 - CCU_DIV_CLKDIV_MAX(div->mask)); 383 - data = ccu_div_prep(div->mask, val); 384 - 385 - spin_lock_irqsave(&div->lock, flags); 386 - regmap_update_bits(div->sys_regs, div->reg_ctl, div->mask, data); 387 - spin_unlock_irqrestore(&div->lock, flags); 388 - 389 - return 0; 390 - } 391 - 392 - #define ccu_div_dbgfs_mode 0644 393 - 394 - #else /* !CCU_DIV_ALLOW_WRITE_DEBUGFS */ 395 - 396 - #define ccu_div_dbgfs_bit_set NULL 397 - #define ccu_div_dbgfs_var_clkdiv_set NULL 398 - #define ccu_div_dbgfs_mode 0444 399 - 400 - #endif /* !CCU_DIV_ALLOW_WRITE_DEBUGFS */ 401 - 402 - static int ccu_div_dbgfs_bit_get(void *priv, u64 *val) 403 - { 404 - const struct ccu_div_dbgfs_bit *bit = priv; 405 - struct ccu_div *div = bit->div; 406 - u32 data = 0; 407 - 408 - regmap_read(div->sys_regs, div->reg_ctl, &data); 409 - *val = !!(data & bit->mask); 410 - 411 - return 0; 412 - } 413 - DEFINE_DEBUGFS_ATTRIBUTE(ccu_div_dbgfs_bit_fops, 414 - ccu_div_dbgfs_bit_get, ccu_div_dbgfs_bit_set, "%llu\n"); 415 - 416 - static int ccu_div_dbgfs_var_clkdiv_get(void *priv, u64 *val) 417 - { 418 - struct ccu_div *div = priv; 419 - u32 data = 0; 420 - 421 - regmap_read(div->sys_regs, div->reg_ctl, &data); 422 - *val = ccu_div_get(div->mask, data); 423 - 424 - return 0; 425 - } 426 - DEFINE_DEBUGFS_ATTRIBUTE(ccu_div_dbgfs_var_clkdiv_fops, 427 - ccu_div_dbgfs_var_clkdiv_get, ccu_div_dbgfs_var_clkdiv_set, "%llu\n"); 428 - 429 - static int ccu_div_dbgfs_fixed_clkdiv_get(void *priv, u64 *val) 430 - { 431 - struct ccu_div *div = priv; 432 - 433 - *val = div->divider; 434 - 435 - return 0; 436 - } 437 - DEFINE_DEBUGFS_ATTRIBUTE(ccu_div_dbgfs_fixed_clkdiv_fops, 438 - ccu_div_dbgfs_fixed_clkdiv_get, NULL, "%llu\n"); 439 - 440 - static void ccu_div_var_debug_init(struct clk_hw *hw, struct dentry *dentry) 441 - { 442 - struct ccu_div *div = to_ccu_div(hw); 443 - struct ccu_div_dbgfs_bit *bits; 444 - int didx, bidx, num = 2; 445 - const char *name; 446 - 447 - num += !!(div->flags & CLK_SET_RATE_GATE) + 448 - !!(div->features & CCU_DIV_RESET_DOMAIN); 449 - 450 - bits = kzalloc_objs(*bits, num); 451 - if (!bits) 452 - return; 453 - 454 - for (didx = 0, bidx = 0; bidx < CCU_DIV_DBGFS_BIT_NUM; ++bidx) { 455 - name = ccu_div_bits[bidx].name; 456 - if (!(div->flags & CLK_SET_RATE_GATE) && 457 - !strcmp("div_en", name)) { 458 - continue; 459 - } 460 - 461 - if (!(div->features & CCU_DIV_RESET_DOMAIN) && 462 - !strcmp("div_rst", name)) { 463 - continue; 464 - } 465 - 466 - if (!strcmp("div_buf", name)) 467 - continue; 468 - 469 - bits[didx] = ccu_div_bits[bidx]; 470 - bits[didx].div = div; 471 - 472 - if (div->features & CCU_DIV_LOCK_SHIFTED && 473 - !strcmp("div_lock", name)) { 474 - bits[didx].mask = CCU_DIV_CTL_LOCK_SHIFTED; 475 - } 476 - 477 - debugfs_create_file_unsafe(bits[didx].name, ccu_div_dbgfs_mode, 478 - dentry, &bits[didx], 479 - &ccu_div_dbgfs_bit_fops); 480 - ++didx; 481 - } 482 - 483 - debugfs_create_file_unsafe("div_clkdiv", ccu_div_dbgfs_mode, dentry, 484 - div, &ccu_div_dbgfs_var_clkdiv_fops); 485 - } 486 - 487 - static void ccu_div_gate_debug_init(struct clk_hw *hw, struct dentry *dentry) 488 - { 489 - struct ccu_div *div = to_ccu_div(hw); 490 - struct ccu_div_dbgfs_bit *bit; 491 - 492 - bit = kmalloc_obj(*bit); 493 - if (!bit) 494 - return; 495 - 496 - *bit = ccu_div_bits[0]; 497 - bit->div = div; 498 - debugfs_create_file_unsafe(bit->name, ccu_div_dbgfs_mode, dentry, bit, 499 - &ccu_div_dbgfs_bit_fops); 500 - 501 - debugfs_create_file_unsafe("div_clkdiv", 0400, dentry, div, 502 - &ccu_div_dbgfs_fixed_clkdiv_fops); 503 - } 504 - 505 - static void ccu_div_buf_debug_init(struct clk_hw *hw, struct dentry *dentry) 506 - { 507 - struct ccu_div *div = to_ccu_div(hw); 508 - struct ccu_div_dbgfs_bit *bit; 509 - 510 - bit = kmalloc_obj(*bit); 511 - if (!bit) 512 - return; 513 - 514 - *bit = ccu_div_bits[3]; 515 - bit->div = div; 516 - debugfs_create_file_unsafe(bit->name, ccu_div_dbgfs_mode, dentry, bit, 517 - &ccu_div_dbgfs_bit_fops); 518 - } 519 - 520 - static void ccu_div_fixed_debug_init(struct clk_hw *hw, struct dentry *dentry) 521 - { 522 - struct ccu_div *div = to_ccu_div(hw); 523 - 524 - debugfs_create_file_unsafe("div_clkdiv", 0400, dentry, div, 525 - &ccu_div_dbgfs_fixed_clkdiv_fops); 526 - } 527 - 528 - #else /* !CONFIG_DEBUG_FS */ 529 - 530 - #define ccu_div_var_debug_init NULL 531 - #define ccu_div_gate_debug_init NULL 532 - #define ccu_div_buf_debug_init NULL 533 - #define ccu_div_fixed_debug_init NULL 534 - 535 - #endif /* !CONFIG_DEBUG_FS */ 536 - 537 - static const struct clk_ops ccu_div_var_gate_to_set_ops = { 538 - .enable = ccu_div_var_enable, 539 - .disable = ccu_div_gate_disable, 540 - .is_enabled = ccu_div_gate_is_enabled, 541 - .recalc_rate = ccu_div_var_recalc_rate, 542 - .determine_rate = ccu_div_var_determine_rate, 543 - .set_rate = ccu_div_var_set_rate_fast, 544 - .debug_init = ccu_div_var_debug_init 545 - }; 546 - 547 - static const struct clk_ops ccu_div_var_nogate_ops = { 548 - .recalc_rate = ccu_div_var_recalc_rate, 549 - .determine_rate = ccu_div_var_determine_rate, 550 - .set_rate = ccu_div_var_set_rate_slow, 551 - .debug_init = ccu_div_var_debug_init 552 - }; 553 - 554 - static const struct clk_ops ccu_div_gate_ops = { 555 - .enable = ccu_div_gate_enable, 556 - .disable = ccu_div_gate_disable, 557 - .is_enabled = ccu_div_gate_is_enabled, 558 - .recalc_rate = ccu_div_fixed_recalc_rate, 559 - .determine_rate = ccu_div_fixed_determine_rate, 560 - .set_rate = ccu_div_fixed_set_rate, 561 - .debug_init = ccu_div_gate_debug_init 562 - }; 563 - 564 - static const struct clk_ops ccu_div_buf_ops = { 565 - .enable = ccu_div_buf_enable, 566 - .disable = ccu_div_buf_disable, 567 - .is_enabled = ccu_div_buf_is_enabled, 568 - .debug_init = ccu_div_buf_debug_init 569 - }; 570 - 571 - static const struct clk_ops ccu_div_fixed_ops = { 572 - .recalc_rate = ccu_div_fixed_recalc_rate, 573 - .determine_rate = ccu_div_fixed_determine_rate, 574 - .set_rate = ccu_div_fixed_set_rate, 575 - .debug_init = ccu_div_fixed_debug_init 576 - }; 577 - 578 - struct ccu_div *ccu_div_hw_register(const struct ccu_div_init_data *div_init) 579 - { 580 - struct clk_parent_data parent_data = { }; 581 - struct clk_init_data hw_init = { }; 582 - struct ccu_div *div; 583 - int ret; 584 - 585 - if (!div_init) 586 - return ERR_PTR(-EINVAL); 587 - 588 - div = kzalloc_obj(*div); 589 - if (!div) 590 - return ERR_PTR(-ENOMEM); 591 - 592 - /* 593 - * Note since Baikal-T1 System Controller registers are MMIO-backed 594 - * we won't check the regmap IO operations return status, because it 595 - * must be zero anyway. 596 - */ 597 - div->hw.init = &hw_init; 598 - div->id = div_init->id; 599 - div->reg_ctl = div_init->base + CCU_DIV_CTL; 600 - div->sys_regs = div_init->sys_regs; 601 - div->flags = div_init->flags; 602 - div->features = div_init->features; 603 - spin_lock_init(&div->lock); 604 - 605 - hw_init.name = div_init->name; 606 - hw_init.flags = div_init->flags; 607 - 608 - if (div_init->type == CCU_DIV_VAR) { 609 - if (hw_init.flags & CLK_SET_RATE_GATE) 610 - hw_init.ops = &ccu_div_var_gate_to_set_ops; 611 - else 612 - hw_init.ops = &ccu_div_var_nogate_ops; 613 - div->mask = CCU_DIV_CTL_CLKDIV_MASK(div_init->width); 614 - } else if (div_init->type == CCU_DIV_GATE) { 615 - hw_init.ops = &ccu_div_gate_ops; 616 - div->divider = div_init->divider; 617 - } else if (div_init->type == CCU_DIV_BUF) { 618 - hw_init.ops = &ccu_div_buf_ops; 619 - } else if (div_init->type == CCU_DIV_FIXED) { 620 - hw_init.ops = &ccu_div_fixed_ops; 621 - div->divider = div_init->divider; 622 - } else { 623 - ret = -EINVAL; 624 - goto err_free_div; 625 - } 626 - 627 - if (!div_init->parent_name) { 628 - ret = -EINVAL; 629 - goto err_free_div; 630 - } 631 - parent_data.fw_name = div_init->parent_name; 632 - parent_data.name = div_init->parent_name; 633 - hw_init.parent_data = &parent_data; 634 - hw_init.num_parents = 1; 635 - 636 - ret = of_clk_hw_register(div_init->np, &div->hw); 637 - if (ret) 638 - goto err_free_div; 639 - 640 - return div; 641 - 642 - err_free_div: 643 - kfree(div); 644 - 645 - return ERR_PTR(ret); 646 - } 647 - 648 - void ccu_div_hw_unregister(struct ccu_div *div) 649 - { 650 - clk_hw_unregister(&div->hw); 651 - 652 - kfree(div); 653 - }
-121
drivers/clk/baikal-t1/ccu-div.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* 3 - * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC 4 - * 5 - * Baikal-T1 CCU Dividers interface driver 6 - */ 7 - #ifndef __CLK_BT1_CCU_DIV_H__ 8 - #define __CLK_BT1_CCU_DIV_H__ 9 - 10 - #include <linux/clk-provider.h> 11 - #include <linux/spinlock.h> 12 - #include <linux/regmap.h> 13 - #include <linux/bits.h> 14 - #include <linux/of.h> 15 - 16 - /* 17 - * CCU Divider private clock IDs 18 - * @CCU_SYS_SATA_CLK: CCU SATA internal clock 19 - * @CCU_SYS_XGMAC_CLK: CCU XGMAC internal clock 20 - */ 21 - #define CCU_SYS_SATA_CLK -1 22 - #define CCU_SYS_XGMAC_CLK -2 23 - 24 - /* 25 - * CCU Divider private flags 26 - * @CCU_DIV_BASIC: Basic divider clock required by the kernel as early as 27 - * possible. 28 - * @CCU_DIV_SKIP_ONE: Due to some reason divider can't be set to 1. 29 - * It can be 0 though, which is functionally the same. 30 - * @CCU_DIV_SKIP_ONE_TO_THREE: For some reason divider can't be within [1,3]. 31 - * It can be either 0 or greater than 3. 32 - * @CCU_DIV_LOCK_SHIFTED: Find lock-bit at non-standard position. 33 - * @CCU_DIV_RESET_DOMAIN: There is a clock domain reset handle. 34 - */ 35 - #define CCU_DIV_BASIC BIT(0) 36 - #define CCU_DIV_SKIP_ONE BIT(1) 37 - #define CCU_DIV_SKIP_ONE_TO_THREE BIT(2) 38 - #define CCU_DIV_LOCK_SHIFTED BIT(3) 39 - #define CCU_DIV_RESET_DOMAIN BIT(4) 40 - 41 - /* 42 - * enum ccu_div_type - CCU Divider types 43 - * @CCU_DIV_VAR: Clocks gate with variable divider. 44 - * @CCU_DIV_GATE: Clocks gate with fixed divider. 45 - * @CCU_DIV_BUF: Clock gate with no divider. 46 - * @CCU_DIV_FIXED: Ungateable clock with fixed divider. 47 - */ 48 - enum ccu_div_type { 49 - CCU_DIV_VAR, 50 - CCU_DIV_GATE, 51 - CCU_DIV_BUF, 52 - CCU_DIV_FIXED 53 - }; 54 - 55 - /* 56 - * struct ccu_div_init_data - CCU Divider initialization data 57 - * @id: Clocks private identifier. 58 - * @name: Clocks name. 59 - * @parent_name: Parent clocks name in a fw node. 60 - * @base: Divider register base address with respect to the sys_regs base. 61 - * @sys_regs: Baikal-T1 System Controller registers map. 62 - * @np: Pointer to the node describing the CCU Dividers. 63 - * @type: CCU divider type (variable, fixed with and without gate). 64 - * @width: Divider width if it's variable. 65 - * @divider: Divider fixed value. 66 - * @flags: CCU Divider clock flags. 67 - * @features: CCU Divider private features. 68 - */ 69 - struct ccu_div_init_data { 70 - unsigned int id; 71 - const char *name; 72 - const char *parent_name; 73 - unsigned int base; 74 - struct regmap *sys_regs; 75 - struct device_node *np; 76 - enum ccu_div_type type; 77 - union { 78 - unsigned int width; 79 - unsigned int divider; 80 - }; 81 - unsigned long flags; 82 - unsigned long features; 83 - }; 84 - 85 - /* 86 - * struct ccu_div - CCU Divider descriptor 87 - * @hw: clk_hw of the divider. 88 - * @id: Clock private identifier. 89 - * @reg_ctl: Divider control register base address. 90 - * @sys_regs: Baikal-T1 System Controller registers map. 91 - * @lock: Divider state change spin-lock. 92 - * @mask: Divider field mask. 93 - * @divider: Divider fixed value. 94 - * @flags: Divider clock flags. 95 - * @features: CCU Divider private features. 96 - */ 97 - struct ccu_div { 98 - struct clk_hw hw; 99 - unsigned int id; 100 - unsigned int reg_ctl; 101 - struct regmap *sys_regs; 102 - spinlock_t lock; 103 - union { 104 - u32 mask; 105 - unsigned int divider; 106 - }; 107 - unsigned long flags; 108 - unsigned long features; 109 - }; 110 - #define to_ccu_div(_hw) container_of(_hw, struct ccu_div, hw) 111 - 112 - static inline struct clk_hw *ccu_div_get_clk_hw(struct ccu_div *div) 113 - { 114 - return div ? &div->hw : NULL; 115 - } 116 - 117 - struct ccu_div *ccu_div_hw_register(const struct ccu_div_init_data *init); 118 - 119 - void ccu_div_hw_unregister(struct ccu_div *div); 120 - 121 - #endif /* __CLK_BT1_CCU_DIV_H__ */
-560
drivers/clk/baikal-t1/ccu-pll.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC 4 - * 5 - * Authors: 6 - * Serge Semin <Sergey.Semin@baikalelectronics.ru> 7 - * Dmitry Dunaev <dmitry.dunaev@baikalelectronics.ru> 8 - * 9 - * Baikal-T1 CCU PLL interface driver 10 - */ 11 - 12 - #define pr_fmt(fmt) "bt1-ccu-pll: " fmt 13 - 14 - #include <linux/kernel.h> 15 - #include <linux/printk.h> 16 - #include <linux/limits.h> 17 - #include <linux/bits.h> 18 - #include <linux/bitfield.h> 19 - #include <linux/slab.h> 20 - #include <linux/clk-provider.h> 21 - #include <linux/of.h> 22 - #include <linux/spinlock.h> 23 - #include <linux/regmap.h> 24 - #include <linux/iopoll.h> 25 - #include <linux/time64.h> 26 - #include <linux/rational.h> 27 - #include <linux/debugfs.h> 28 - 29 - #include "ccu-pll.h" 30 - 31 - #define CCU_PLL_CTL 0x000 32 - #define CCU_PLL_CTL_EN BIT(0) 33 - #define CCU_PLL_CTL_RST BIT(1) 34 - #define CCU_PLL_CTL_CLKR_FLD 2 35 - #define CCU_PLL_CTL_CLKR_MASK GENMASK(7, CCU_PLL_CTL_CLKR_FLD) 36 - #define CCU_PLL_CTL_CLKF_FLD 8 37 - #define CCU_PLL_CTL_CLKF_MASK GENMASK(20, CCU_PLL_CTL_CLKF_FLD) 38 - #define CCU_PLL_CTL_CLKOD_FLD 21 39 - #define CCU_PLL_CTL_CLKOD_MASK GENMASK(24, CCU_PLL_CTL_CLKOD_FLD) 40 - #define CCU_PLL_CTL_BYPASS BIT(30) 41 - #define CCU_PLL_CTL_LOCK BIT(31) 42 - #define CCU_PLL_CTL1 0x004 43 - #define CCU_PLL_CTL1_BWADJ_FLD 3 44 - #define CCU_PLL_CTL1_BWADJ_MASK GENMASK(14, CCU_PLL_CTL1_BWADJ_FLD) 45 - 46 - #define CCU_PLL_LOCK_CHECK_RETRIES 50 47 - 48 - #define CCU_PLL_NR_MAX \ 49 - ((CCU_PLL_CTL_CLKR_MASK >> CCU_PLL_CTL_CLKR_FLD) + 1) 50 - #define CCU_PLL_NF_MAX \ 51 - ((CCU_PLL_CTL_CLKF_MASK >> (CCU_PLL_CTL_CLKF_FLD + 1)) + 1) 52 - #define CCU_PLL_OD_MAX \ 53 - ((CCU_PLL_CTL_CLKOD_MASK >> CCU_PLL_CTL_CLKOD_FLD) + 1) 54 - #define CCU_PLL_NB_MAX \ 55 - ((CCU_PLL_CTL1_BWADJ_MASK >> CCU_PLL_CTL1_BWADJ_FLD) + 1) 56 - #define CCU_PLL_FDIV_MIN 427000UL 57 - #define CCU_PLL_FDIV_MAX 3500000000UL 58 - #define CCU_PLL_FOUT_MIN 200000000UL 59 - #define CCU_PLL_FOUT_MAX 2500000000UL 60 - #define CCU_PLL_FVCO_MIN 700000000UL 61 - #define CCU_PLL_FVCO_MAX 3500000000UL 62 - #define CCU_PLL_CLKOD_FACTOR 2 63 - 64 - static inline unsigned long ccu_pll_lock_delay_us(unsigned long ref_clk, 65 - unsigned long nr) 66 - { 67 - u64 us = 500ULL * nr * USEC_PER_SEC; 68 - 69 - do_div(us, ref_clk); 70 - 71 - return us; 72 - } 73 - 74 - static inline unsigned long ccu_pll_calc_freq(unsigned long ref_clk, 75 - unsigned long nr, 76 - unsigned long nf, 77 - unsigned long od) 78 - { 79 - u64 tmp = ref_clk; 80 - 81 - do_div(tmp, nr); 82 - tmp *= nf; 83 - do_div(tmp, od); 84 - 85 - return tmp; 86 - } 87 - 88 - static int ccu_pll_reset(struct ccu_pll *pll, unsigned long ref_clk, 89 - unsigned long nr) 90 - { 91 - unsigned long ud, ut; 92 - u32 val; 93 - 94 - ud = ccu_pll_lock_delay_us(ref_clk, nr); 95 - ut = ud * CCU_PLL_LOCK_CHECK_RETRIES; 96 - 97 - regmap_update_bits(pll->sys_regs, pll->reg_ctl, 98 - CCU_PLL_CTL_RST, CCU_PLL_CTL_RST); 99 - 100 - return regmap_read_poll_timeout_atomic(pll->sys_regs, pll->reg_ctl, val, 101 - val & CCU_PLL_CTL_LOCK, ud, ut); 102 - } 103 - 104 - static int ccu_pll_enable(struct clk_hw *hw) 105 - { 106 - struct clk_hw *parent_hw = clk_hw_get_parent(hw); 107 - struct ccu_pll *pll = to_ccu_pll(hw); 108 - unsigned long flags; 109 - u32 val = 0; 110 - int ret; 111 - 112 - if (!parent_hw) { 113 - pr_err("Can't enable '%s' with no parent", clk_hw_get_name(hw)); 114 - return -EINVAL; 115 - } 116 - 117 - regmap_read(pll->sys_regs, pll->reg_ctl, &val); 118 - if (val & CCU_PLL_CTL_EN) 119 - return 0; 120 - 121 - spin_lock_irqsave(&pll->lock, flags); 122 - regmap_write(pll->sys_regs, pll->reg_ctl, val | CCU_PLL_CTL_EN); 123 - ret = ccu_pll_reset(pll, clk_hw_get_rate(parent_hw), 124 - FIELD_GET(CCU_PLL_CTL_CLKR_MASK, val) + 1); 125 - spin_unlock_irqrestore(&pll->lock, flags); 126 - if (ret) 127 - pr_err("PLL '%s' reset timed out\n", clk_hw_get_name(hw)); 128 - 129 - return ret; 130 - } 131 - 132 - static void ccu_pll_disable(struct clk_hw *hw) 133 - { 134 - struct ccu_pll *pll = to_ccu_pll(hw); 135 - unsigned long flags; 136 - 137 - spin_lock_irqsave(&pll->lock, flags); 138 - regmap_update_bits(pll->sys_regs, pll->reg_ctl, CCU_PLL_CTL_EN, 0); 139 - spin_unlock_irqrestore(&pll->lock, flags); 140 - } 141 - 142 - static int ccu_pll_is_enabled(struct clk_hw *hw) 143 - { 144 - struct ccu_pll *pll = to_ccu_pll(hw); 145 - u32 val = 0; 146 - 147 - regmap_read(pll->sys_regs, pll->reg_ctl, &val); 148 - 149 - return !!(val & CCU_PLL_CTL_EN); 150 - } 151 - 152 - static unsigned long ccu_pll_recalc_rate(struct clk_hw *hw, 153 - unsigned long parent_rate) 154 - { 155 - struct ccu_pll *pll = to_ccu_pll(hw); 156 - unsigned long nr, nf, od; 157 - u32 val = 0; 158 - 159 - regmap_read(pll->sys_regs, pll->reg_ctl, &val); 160 - nr = FIELD_GET(CCU_PLL_CTL_CLKR_MASK, val) + 1; 161 - nf = FIELD_GET(CCU_PLL_CTL_CLKF_MASK, val) + 1; 162 - od = FIELD_GET(CCU_PLL_CTL_CLKOD_MASK, val) + 1; 163 - 164 - return ccu_pll_calc_freq(parent_rate, nr, nf, od); 165 - } 166 - 167 - static void ccu_pll_calc_factors(unsigned long rate, unsigned long parent_rate, 168 - unsigned long *nr, unsigned long *nf, 169 - unsigned long *od) 170 - { 171 - unsigned long err, freq, min_err = ULONG_MAX; 172 - unsigned long num, denom, n1, d1, nri; 173 - unsigned long nr_max, nf_max, od_max; 174 - 175 - /* 176 - * Make sure PLL is working with valid input signal (Fdiv). If 177 - * you want to speed the function up just reduce CCU_PLL_NR_MAX. 178 - * This will cause a worse approximation though. 179 - */ 180 - nri = (parent_rate / CCU_PLL_FDIV_MAX) + 1; 181 - nr_max = min(parent_rate / CCU_PLL_FDIV_MIN, CCU_PLL_NR_MAX); 182 - 183 - /* 184 - * Find a closest [nr;nf;od] vector taking into account the 185 - * limitations like: 1) 700MHz <= Fvco <= 3.5GHz, 2) PLL Od is 186 - * either 1 or even number within the acceptable range (alas 1s 187 - * is also excluded by the next loop). 188 - */ 189 - for (; nri <= nr_max; ++nri) { 190 - /* Use Od factor to fulfill the limitation 2). */ 191 - num = CCU_PLL_CLKOD_FACTOR * rate; 192 - denom = parent_rate / nri; 193 - 194 - /* 195 - * Make sure Fvco is within the acceptable range to fulfill 196 - * the condition 1). Note due to the CCU_PLL_CLKOD_FACTOR value 197 - * the actual upper limit is also divided by that factor. 198 - * It's not big problem for us since practically there is no 199 - * need in clocks with that high frequency. 200 - */ 201 - nf_max = min(CCU_PLL_FVCO_MAX / denom, CCU_PLL_NF_MAX); 202 - od_max = CCU_PLL_OD_MAX / CCU_PLL_CLKOD_FACTOR; 203 - 204 - /* 205 - * Bypass the out-of-bound values, which can't be properly 206 - * handled by the rational fraction approximation algorithm. 207 - */ 208 - if (num / denom >= nf_max) { 209 - n1 = nf_max; 210 - d1 = 1; 211 - } else if (denom / num >= od_max) { 212 - n1 = 1; 213 - d1 = od_max; 214 - } else { 215 - rational_best_approximation(num, denom, nf_max, od_max, 216 - &n1, &d1); 217 - } 218 - 219 - /* Select the best approximation of the target rate. */ 220 - freq = ccu_pll_calc_freq(parent_rate, nri, n1, d1); 221 - err = abs((int64_t)freq - num); 222 - if (err < min_err) { 223 - min_err = err; 224 - *nr = nri; 225 - *nf = n1; 226 - *od = CCU_PLL_CLKOD_FACTOR * d1; 227 - } 228 - } 229 - } 230 - 231 - static int ccu_pll_determine_rate(struct clk_hw *hw, 232 - struct clk_rate_request *req) 233 - { 234 - unsigned long nr = 1, nf = 1, od = 1; 235 - 236 - ccu_pll_calc_factors(req->rate, req->best_parent_rate, &nr, &nf, &od); 237 - 238 - req->rate = ccu_pll_calc_freq(req->best_parent_rate, nr, nf, od); 239 - 240 - return 0; 241 - } 242 - 243 - /* 244 - * This method is used for PLLs, which support the on-the-fly dividers 245 - * adjustment. So there is no need in gating such clocks. 246 - */ 247 - static int ccu_pll_set_rate_reset(struct clk_hw *hw, unsigned long rate, 248 - unsigned long parent_rate) 249 - { 250 - struct ccu_pll *pll = to_ccu_pll(hw); 251 - unsigned long nr, nf, od; 252 - unsigned long flags; 253 - u32 mask, val; 254 - int ret; 255 - 256 - ccu_pll_calc_factors(rate, parent_rate, &nr, &nf, &od); 257 - 258 - mask = CCU_PLL_CTL_CLKR_MASK | CCU_PLL_CTL_CLKF_MASK | 259 - CCU_PLL_CTL_CLKOD_MASK; 260 - val = FIELD_PREP(CCU_PLL_CTL_CLKR_MASK, nr - 1) | 261 - FIELD_PREP(CCU_PLL_CTL_CLKF_MASK, nf - 1) | 262 - FIELD_PREP(CCU_PLL_CTL_CLKOD_MASK, od - 1); 263 - 264 - spin_lock_irqsave(&pll->lock, flags); 265 - regmap_update_bits(pll->sys_regs, pll->reg_ctl, mask, val); 266 - ret = ccu_pll_reset(pll, parent_rate, nr); 267 - spin_unlock_irqrestore(&pll->lock, flags); 268 - if (ret) 269 - pr_err("PLL '%s' reset timed out\n", clk_hw_get_name(hw)); 270 - 271 - return ret; 272 - } 273 - 274 - /* 275 - * This method is used for PLLs, which don't support the on-the-fly dividers 276 - * adjustment. So the corresponding clocks are supposed to be gated first. 277 - */ 278 - static int ccu_pll_set_rate_norst(struct clk_hw *hw, unsigned long rate, 279 - unsigned long parent_rate) 280 - { 281 - struct ccu_pll *pll = to_ccu_pll(hw); 282 - unsigned long nr, nf, od; 283 - unsigned long flags; 284 - u32 mask, val; 285 - 286 - ccu_pll_calc_factors(rate, parent_rate, &nr, &nf, &od); 287 - 288 - /* 289 - * Disable PLL if it was enabled by default or left enabled by the 290 - * system bootloader. 291 - */ 292 - mask = CCU_PLL_CTL_CLKR_MASK | CCU_PLL_CTL_CLKF_MASK | 293 - CCU_PLL_CTL_CLKOD_MASK | CCU_PLL_CTL_EN; 294 - val = FIELD_PREP(CCU_PLL_CTL_CLKR_MASK, nr - 1) | 295 - FIELD_PREP(CCU_PLL_CTL_CLKF_MASK, nf - 1) | 296 - FIELD_PREP(CCU_PLL_CTL_CLKOD_MASK, od - 1); 297 - 298 - spin_lock_irqsave(&pll->lock, flags); 299 - regmap_update_bits(pll->sys_regs, pll->reg_ctl, mask, val); 300 - spin_unlock_irqrestore(&pll->lock, flags); 301 - 302 - return 0; 303 - } 304 - 305 - #ifdef CONFIG_DEBUG_FS 306 - 307 - struct ccu_pll_dbgfs_bit { 308 - struct ccu_pll *pll; 309 - const char *name; 310 - unsigned int reg; 311 - u32 mask; 312 - }; 313 - 314 - struct ccu_pll_dbgfs_fld { 315 - struct ccu_pll *pll; 316 - const char *name; 317 - unsigned int reg; 318 - unsigned int lsb; 319 - u32 mask; 320 - u32 min; 321 - u32 max; 322 - }; 323 - 324 - #define CCU_PLL_DBGFS_BIT_ATTR(_name, _reg, _mask) \ 325 - { \ 326 - .name = _name, \ 327 - .reg = _reg, \ 328 - .mask = _mask \ 329 - } 330 - 331 - #define CCU_PLL_DBGFS_FLD_ATTR(_name, _reg, _lsb, _mask, _min, _max) \ 332 - { \ 333 - .name = _name, \ 334 - .reg = _reg, \ 335 - .lsb = _lsb, \ 336 - .mask = _mask, \ 337 - .min = _min, \ 338 - .max = _max \ 339 - } 340 - 341 - static const struct ccu_pll_dbgfs_bit ccu_pll_bits[] = { 342 - CCU_PLL_DBGFS_BIT_ATTR("pll_en", CCU_PLL_CTL, CCU_PLL_CTL_EN), 343 - CCU_PLL_DBGFS_BIT_ATTR("pll_rst", CCU_PLL_CTL, CCU_PLL_CTL_RST), 344 - CCU_PLL_DBGFS_BIT_ATTR("pll_bypass", CCU_PLL_CTL, CCU_PLL_CTL_BYPASS), 345 - CCU_PLL_DBGFS_BIT_ATTR("pll_lock", CCU_PLL_CTL, CCU_PLL_CTL_LOCK) 346 - }; 347 - 348 - #define CCU_PLL_DBGFS_BIT_NUM ARRAY_SIZE(ccu_pll_bits) 349 - 350 - static const struct ccu_pll_dbgfs_fld ccu_pll_flds[] = { 351 - CCU_PLL_DBGFS_FLD_ATTR("pll_nr", CCU_PLL_CTL, CCU_PLL_CTL_CLKR_FLD, 352 - CCU_PLL_CTL_CLKR_MASK, 1, CCU_PLL_NR_MAX), 353 - CCU_PLL_DBGFS_FLD_ATTR("pll_nf", CCU_PLL_CTL, CCU_PLL_CTL_CLKF_FLD, 354 - CCU_PLL_CTL_CLKF_MASK, 1, CCU_PLL_NF_MAX), 355 - CCU_PLL_DBGFS_FLD_ATTR("pll_od", CCU_PLL_CTL, CCU_PLL_CTL_CLKOD_FLD, 356 - CCU_PLL_CTL_CLKOD_MASK, 1, CCU_PLL_OD_MAX), 357 - CCU_PLL_DBGFS_FLD_ATTR("pll_nb", CCU_PLL_CTL1, CCU_PLL_CTL1_BWADJ_FLD, 358 - CCU_PLL_CTL1_BWADJ_MASK, 1, CCU_PLL_NB_MAX) 359 - }; 360 - 361 - #define CCU_PLL_DBGFS_FLD_NUM ARRAY_SIZE(ccu_pll_flds) 362 - 363 - /* 364 - * It can be dangerous to change the PLL settings behind clock framework back, 365 - * therefore we don't provide any kernel config based compile time option for 366 - * this feature to enable. 367 - */ 368 - #undef CCU_PLL_ALLOW_WRITE_DEBUGFS 369 - #ifdef CCU_PLL_ALLOW_WRITE_DEBUGFS 370 - 371 - static int ccu_pll_dbgfs_bit_set(void *priv, u64 val) 372 - { 373 - const struct ccu_pll_dbgfs_bit *bit = priv; 374 - struct ccu_pll *pll = bit->pll; 375 - unsigned long flags; 376 - 377 - spin_lock_irqsave(&pll->lock, flags); 378 - regmap_update_bits(pll->sys_regs, pll->reg_ctl + bit->reg, 379 - bit->mask, val ? bit->mask : 0); 380 - spin_unlock_irqrestore(&pll->lock, flags); 381 - 382 - return 0; 383 - } 384 - 385 - static int ccu_pll_dbgfs_fld_set(void *priv, u64 val) 386 - { 387 - struct ccu_pll_dbgfs_fld *fld = priv; 388 - struct ccu_pll *pll = fld->pll; 389 - unsigned long flags; 390 - u32 data; 391 - 392 - val = clamp_t(u64, val, fld->min, fld->max); 393 - data = ((val - 1) << fld->lsb) & fld->mask; 394 - 395 - spin_lock_irqsave(&pll->lock, flags); 396 - regmap_update_bits(pll->sys_regs, pll->reg_ctl + fld->reg, fld->mask, 397 - data); 398 - spin_unlock_irqrestore(&pll->lock, flags); 399 - 400 - return 0; 401 - } 402 - 403 - #define ccu_pll_dbgfs_mode 0644 404 - 405 - #else /* !CCU_PLL_ALLOW_WRITE_DEBUGFS */ 406 - 407 - #define ccu_pll_dbgfs_bit_set NULL 408 - #define ccu_pll_dbgfs_fld_set NULL 409 - #define ccu_pll_dbgfs_mode 0444 410 - 411 - #endif /* !CCU_PLL_ALLOW_WRITE_DEBUGFS */ 412 - 413 - static int ccu_pll_dbgfs_bit_get(void *priv, u64 *val) 414 - { 415 - struct ccu_pll_dbgfs_bit *bit = priv; 416 - struct ccu_pll *pll = bit->pll; 417 - u32 data = 0; 418 - 419 - regmap_read(pll->sys_regs, pll->reg_ctl + bit->reg, &data); 420 - *val = !!(data & bit->mask); 421 - 422 - return 0; 423 - } 424 - DEFINE_DEBUGFS_ATTRIBUTE(ccu_pll_dbgfs_bit_fops, 425 - ccu_pll_dbgfs_bit_get, ccu_pll_dbgfs_bit_set, "%llu\n"); 426 - 427 - static int ccu_pll_dbgfs_fld_get(void *priv, u64 *val) 428 - { 429 - struct ccu_pll_dbgfs_fld *fld = priv; 430 - struct ccu_pll *pll = fld->pll; 431 - u32 data = 0; 432 - 433 - regmap_read(pll->sys_regs, pll->reg_ctl + fld->reg, &data); 434 - *val = ((data & fld->mask) >> fld->lsb) + 1; 435 - 436 - return 0; 437 - } 438 - DEFINE_DEBUGFS_ATTRIBUTE(ccu_pll_dbgfs_fld_fops, 439 - ccu_pll_dbgfs_fld_get, ccu_pll_dbgfs_fld_set, "%llu\n"); 440 - 441 - static void ccu_pll_debug_init(struct clk_hw *hw, struct dentry *dentry) 442 - { 443 - struct ccu_pll *pll = to_ccu_pll(hw); 444 - struct ccu_pll_dbgfs_bit *bits; 445 - struct ccu_pll_dbgfs_fld *flds; 446 - int idx; 447 - 448 - bits = kzalloc_objs(*bits, CCU_PLL_DBGFS_BIT_NUM); 449 - if (!bits) 450 - return; 451 - 452 - for (idx = 0; idx < CCU_PLL_DBGFS_BIT_NUM; ++idx) { 453 - bits[idx] = ccu_pll_bits[idx]; 454 - bits[idx].pll = pll; 455 - 456 - debugfs_create_file_unsafe(bits[idx].name, ccu_pll_dbgfs_mode, 457 - dentry, &bits[idx], 458 - &ccu_pll_dbgfs_bit_fops); 459 - } 460 - 461 - flds = kzalloc_objs(*flds, CCU_PLL_DBGFS_FLD_NUM); 462 - if (!flds) 463 - return; 464 - 465 - for (idx = 0; idx < CCU_PLL_DBGFS_FLD_NUM; ++idx) { 466 - flds[idx] = ccu_pll_flds[idx]; 467 - flds[idx].pll = pll; 468 - 469 - debugfs_create_file_unsafe(flds[idx].name, ccu_pll_dbgfs_mode, 470 - dentry, &flds[idx], 471 - &ccu_pll_dbgfs_fld_fops); 472 - } 473 - } 474 - 475 - #else /* !CONFIG_DEBUG_FS */ 476 - 477 - #define ccu_pll_debug_init NULL 478 - 479 - #endif /* !CONFIG_DEBUG_FS */ 480 - 481 - static const struct clk_ops ccu_pll_gate_to_set_ops = { 482 - .enable = ccu_pll_enable, 483 - .disable = ccu_pll_disable, 484 - .is_enabled = ccu_pll_is_enabled, 485 - .recalc_rate = ccu_pll_recalc_rate, 486 - .determine_rate = ccu_pll_determine_rate, 487 - .set_rate = ccu_pll_set_rate_norst, 488 - .debug_init = ccu_pll_debug_init 489 - }; 490 - 491 - static const struct clk_ops ccu_pll_straight_set_ops = { 492 - .enable = ccu_pll_enable, 493 - .disable = ccu_pll_disable, 494 - .is_enabled = ccu_pll_is_enabled, 495 - .recalc_rate = ccu_pll_recalc_rate, 496 - .determine_rate = ccu_pll_determine_rate, 497 - .set_rate = ccu_pll_set_rate_reset, 498 - .debug_init = ccu_pll_debug_init 499 - }; 500 - 501 - struct ccu_pll *ccu_pll_hw_register(const struct ccu_pll_init_data *pll_init) 502 - { 503 - struct clk_parent_data parent_data = { }; 504 - struct clk_init_data hw_init = { }; 505 - struct ccu_pll *pll; 506 - int ret; 507 - 508 - if (!pll_init) 509 - return ERR_PTR(-EINVAL); 510 - 511 - pll = kzalloc_obj(*pll); 512 - if (!pll) 513 - return ERR_PTR(-ENOMEM); 514 - 515 - /* 516 - * Note since Baikal-T1 System Controller registers are MMIO-backed 517 - * we won't check the regmap IO operations return status, because it 518 - * must be zero anyway. 519 - */ 520 - pll->hw.init = &hw_init; 521 - pll->reg_ctl = pll_init->base + CCU_PLL_CTL; 522 - pll->reg_ctl1 = pll_init->base + CCU_PLL_CTL1; 523 - pll->sys_regs = pll_init->sys_regs; 524 - pll->id = pll_init->id; 525 - spin_lock_init(&pll->lock); 526 - 527 - hw_init.name = pll_init->name; 528 - hw_init.flags = pll_init->flags; 529 - 530 - if (hw_init.flags & CLK_SET_RATE_GATE) 531 - hw_init.ops = &ccu_pll_gate_to_set_ops; 532 - else 533 - hw_init.ops = &ccu_pll_straight_set_ops; 534 - 535 - if (!pll_init->parent_name) { 536 - ret = -EINVAL; 537 - goto err_free_pll; 538 - } 539 - parent_data.fw_name = pll_init->parent_name; 540 - hw_init.parent_data = &parent_data; 541 - hw_init.num_parents = 1; 542 - 543 - ret = of_clk_hw_register(pll_init->np, &pll->hw); 544 - if (ret) 545 - goto err_free_pll; 546 - 547 - return pll; 548 - 549 - err_free_pll: 550 - kfree(pll); 551 - 552 - return ERR_PTR(ret); 553 - } 554 - 555 - void ccu_pll_hw_unregister(struct ccu_pll *pll) 556 - { 557 - clk_hw_unregister(&pll->hw); 558 - 559 - kfree(pll); 560 - }
-72
drivers/clk/baikal-t1/ccu-pll.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* 3 - * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC 4 - * 5 - * Baikal-T1 CCU PLL interface driver 6 - */ 7 - #ifndef __CLK_BT1_CCU_PLL_H__ 8 - #define __CLK_BT1_CCU_PLL_H__ 9 - 10 - #include <linux/clk-provider.h> 11 - #include <linux/spinlock.h> 12 - #include <linux/regmap.h> 13 - #include <linux/bits.h> 14 - #include <linux/of.h> 15 - 16 - /* 17 - * CCU PLL private flags 18 - * @CCU_PLL_BASIC: Basic PLL required by the kernel as early as possible. 19 - */ 20 - #define CCU_PLL_BASIC BIT(0) 21 - 22 - /* 23 - * struct ccu_pll_init_data - CCU PLL initialization data 24 - * @id: Clock private identifier. 25 - * @name: Clocks name. 26 - * @parent_name: Clocks parent name in a fw node. 27 - * @base: PLL registers base address with respect to the sys_regs base. 28 - * @sys_regs: Baikal-T1 System Controller registers map. 29 - * @np: Pointer to the node describing the CCU PLLs. 30 - * @flags: PLL clock flags. 31 - * @features: PLL private features. 32 - */ 33 - struct ccu_pll_init_data { 34 - unsigned int id; 35 - const char *name; 36 - const char *parent_name; 37 - unsigned int base; 38 - struct regmap *sys_regs; 39 - struct device_node *np; 40 - unsigned long flags; 41 - unsigned long features; 42 - }; 43 - 44 - /* 45 - * struct ccu_pll - CCU PLL descriptor 46 - * @hw: clk_hw of the PLL. 47 - * @id: Clock private identifier. 48 - * @reg_ctl: PLL control register base. 49 - * @reg_ctl1: PLL control1 register base. 50 - * @sys_regs: Baikal-T1 System Controller registers map. 51 - * @lock: PLL state change spin-lock. 52 - */ 53 - struct ccu_pll { 54 - struct clk_hw hw; 55 - unsigned int id; 56 - unsigned int reg_ctl; 57 - unsigned int reg_ctl1; 58 - struct regmap *sys_regs; 59 - spinlock_t lock; 60 - }; 61 - #define to_ccu_pll(_hw) container_of(_hw, struct ccu_pll, hw) 62 - 63 - static inline struct clk_hw *ccu_pll_get_clk_hw(struct ccu_pll *pll) 64 - { 65 - return pll ? &pll->hw : NULL; 66 - } 67 - 68 - struct ccu_pll *ccu_pll_hw_register(const struct ccu_pll_init_data *init); 69 - 70 - void ccu_pll_hw_unregister(struct ccu_pll *pll); 71 - 72 - #endif /* __CLK_BT1_CCU_PLL_H__ */
-217
drivers/clk/baikal-t1/ccu-rst.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Copyright (C) 2021 BAIKAL ELECTRONICS, JSC 4 - * 5 - * Authors: 6 - * Serge Semin <Sergey.Semin@baikalelectronics.ru> 7 - * 8 - * Baikal-T1 CCU Resets interface driver 9 - */ 10 - 11 - #define pr_fmt(fmt) "bt1-ccu-rst: " fmt 12 - 13 - #include <linux/bits.h> 14 - #include <linux/delay.h> 15 - #include <linux/kernel.h> 16 - #include <linux/of.h> 17 - #include <linux/printk.h> 18 - #include <linux/regmap.h> 19 - #include <linux/reset-controller.h> 20 - #include <linux/slab.h> 21 - 22 - #include <dt-bindings/reset/bt1-ccu.h> 23 - 24 - #include "ccu-rst.h" 25 - 26 - #define CCU_AXI_MAIN_BASE 0x030 27 - #define CCU_AXI_DDR_BASE 0x034 28 - #define CCU_AXI_SATA_BASE 0x038 29 - #define CCU_AXI_GMAC0_BASE 0x03C 30 - #define CCU_AXI_GMAC1_BASE 0x040 31 - #define CCU_AXI_XGMAC_BASE 0x044 32 - #define CCU_AXI_PCIE_M_BASE 0x048 33 - #define CCU_AXI_PCIE_S_BASE 0x04C 34 - #define CCU_AXI_USB_BASE 0x050 35 - #define CCU_AXI_HWA_BASE 0x054 36 - #define CCU_AXI_SRAM_BASE 0x058 37 - 38 - #define CCU_SYS_DDR_BASE 0x02c 39 - #define CCU_SYS_SATA_REF_BASE 0x060 40 - #define CCU_SYS_APB_BASE 0x064 41 - #define CCU_SYS_PCIE_BASE 0x144 42 - 43 - #define CCU_RST_DELAY_US 1 44 - 45 - #define CCU_RST_TRIG(_base, _ofs) \ 46 - { \ 47 - .type = CCU_RST_TRIG, \ 48 - .base = _base, \ 49 - .mask = BIT(_ofs), \ 50 - } 51 - 52 - #define CCU_RST_DIR(_base, _ofs) \ 53 - { \ 54 - .type = CCU_RST_DIR, \ 55 - .base = _base, \ 56 - .mask = BIT(_ofs), \ 57 - } 58 - 59 - struct ccu_rst_info { 60 - enum ccu_rst_type type; 61 - unsigned int base; 62 - unsigned int mask; 63 - }; 64 - 65 - /* 66 - * Each AXI-bus clock divider is equipped with the corresponding clock-consumer 67 - * domain reset (it's self-deasserted reset control). 68 - */ 69 - static const struct ccu_rst_info axi_rst_info[] = { 70 - [CCU_AXI_MAIN_RST] = CCU_RST_TRIG(CCU_AXI_MAIN_BASE, 1), 71 - [CCU_AXI_DDR_RST] = CCU_RST_TRIG(CCU_AXI_DDR_BASE, 1), 72 - [CCU_AXI_SATA_RST] = CCU_RST_TRIG(CCU_AXI_SATA_BASE, 1), 73 - [CCU_AXI_GMAC0_RST] = CCU_RST_TRIG(CCU_AXI_GMAC0_BASE, 1), 74 - [CCU_AXI_GMAC1_RST] = CCU_RST_TRIG(CCU_AXI_GMAC1_BASE, 1), 75 - [CCU_AXI_XGMAC_RST] = CCU_RST_TRIG(CCU_AXI_XGMAC_BASE, 1), 76 - [CCU_AXI_PCIE_M_RST] = CCU_RST_TRIG(CCU_AXI_PCIE_M_BASE, 1), 77 - [CCU_AXI_PCIE_S_RST] = CCU_RST_TRIG(CCU_AXI_PCIE_S_BASE, 1), 78 - [CCU_AXI_USB_RST] = CCU_RST_TRIG(CCU_AXI_USB_BASE, 1), 79 - [CCU_AXI_HWA_RST] = CCU_RST_TRIG(CCU_AXI_HWA_BASE, 1), 80 - [CCU_AXI_SRAM_RST] = CCU_RST_TRIG(CCU_AXI_SRAM_BASE, 1), 81 - }; 82 - 83 - /* 84 - * SATA reference clock domain and APB-bus domain are connected with the 85 - * sefl-deasserted reset control, which can be activated via the corresponding 86 - * clock divider register. DDR and PCIe sub-domains can be reset with directly 87 - * controlled reset signals. Resetting the DDR controller though won't end up 88 - * well while the Linux kernel is working. 89 - */ 90 - static const struct ccu_rst_info sys_rst_info[] = { 91 - [CCU_SYS_SATA_REF_RST] = CCU_RST_TRIG(CCU_SYS_SATA_REF_BASE, 1), 92 - [CCU_SYS_APB_RST] = CCU_RST_TRIG(CCU_SYS_APB_BASE, 1), 93 - [CCU_SYS_DDR_FULL_RST] = CCU_RST_DIR(CCU_SYS_DDR_BASE, 1), 94 - [CCU_SYS_DDR_INIT_RST] = CCU_RST_DIR(CCU_SYS_DDR_BASE, 2), 95 - [CCU_SYS_PCIE_PCS_PHY_RST] = CCU_RST_DIR(CCU_SYS_PCIE_BASE, 0), 96 - [CCU_SYS_PCIE_PIPE0_RST] = CCU_RST_DIR(CCU_SYS_PCIE_BASE, 4), 97 - [CCU_SYS_PCIE_CORE_RST] = CCU_RST_DIR(CCU_SYS_PCIE_BASE, 8), 98 - [CCU_SYS_PCIE_PWR_RST] = CCU_RST_DIR(CCU_SYS_PCIE_BASE, 9), 99 - [CCU_SYS_PCIE_STICKY_RST] = CCU_RST_DIR(CCU_SYS_PCIE_BASE, 10), 100 - [CCU_SYS_PCIE_NSTICKY_RST] = CCU_RST_DIR(CCU_SYS_PCIE_BASE, 11), 101 - [CCU_SYS_PCIE_HOT_RST] = CCU_RST_DIR(CCU_SYS_PCIE_BASE, 12), 102 - }; 103 - 104 - static int ccu_rst_reset(struct reset_controller_dev *rcdev, unsigned long idx) 105 - { 106 - struct ccu_rst *rst = to_ccu_rst(rcdev); 107 - const struct ccu_rst_info *info = &rst->rsts_info[idx]; 108 - 109 - if (info->type != CCU_RST_TRIG) 110 - return -EOPNOTSUPP; 111 - 112 - regmap_update_bits(rst->sys_regs, info->base, info->mask, info->mask); 113 - 114 - /* The next delay must be enough to cover all the resets. */ 115 - udelay(CCU_RST_DELAY_US); 116 - 117 - return 0; 118 - } 119 - 120 - static int ccu_rst_set(struct reset_controller_dev *rcdev, 121 - unsigned long idx, bool high) 122 - { 123 - struct ccu_rst *rst = to_ccu_rst(rcdev); 124 - const struct ccu_rst_info *info = &rst->rsts_info[idx]; 125 - 126 - if (info->type != CCU_RST_DIR) 127 - return high ? -EOPNOTSUPP : 0; 128 - 129 - return regmap_update_bits(rst->sys_regs, info->base, 130 - info->mask, high ? info->mask : 0); 131 - } 132 - 133 - static int ccu_rst_assert(struct reset_controller_dev *rcdev, 134 - unsigned long idx) 135 - { 136 - return ccu_rst_set(rcdev, idx, true); 137 - } 138 - 139 - static int ccu_rst_deassert(struct reset_controller_dev *rcdev, 140 - unsigned long idx) 141 - { 142 - return ccu_rst_set(rcdev, idx, false); 143 - } 144 - 145 - static int ccu_rst_status(struct reset_controller_dev *rcdev, 146 - unsigned long idx) 147 - { 148 - struct ccu_rst *rst = to_ccu_rst(rcdev); 149 - const struct ccu_rst_info *info = &rst->rsts_info[idx]; 150 - u32 val; 151 - 152 - if (info->type != CCU_RST_DIR) 153 - return -EOPNOTSUPP; 154 - 155 - regmap_read(rst->sys_regs, info->base, &val); 156 - 157 - return !!(val & info->mask); 158 - } 159 - 160 - static const struct reset_control_ops ccu_rst_ops = { 161 - .reset = ccu_rst_reset, 162 - .assert = ccu_rst_assert, 163 - .deassert = ccu_rst_deassert, 164 - .status = ccu_rst_status, 165 - }; 166 - 167 - struct ccu_rst *ccu_rst_hw_register(const struct ccu_rst_init_data *rst_init) 168 - { 169 - struct ccu_rst *rst; 170 - int ret; 171 - 172 - if (!rst_init) 173 - return ERR_PTR(-EINVAL); 174 - 175 - rst = kzalloc_obj(*rst); 176 - if (!rst) 177 - return ERR_PTR(-ENOMEM); 178 - 179 - rst->sys_regs = rst_init->sys_regs; 180 - if (of_device_is_compatible(rst_init->np, "baikal,bt1-ccu-axi")) { 181 - rst->rcdev.nr_resets = ARRAY_SIZE(axi_rst_info); 182 - rst->rsts_info = axi_rst_info; 183 - } else if (of_device_is_compatible(rst_init->np, "baikal,bt1-ccu-sys")) { 184 - rst->rcdev.nr_resets = ARRAY_SIZE(sys_rst_info); 185 - rst->rsts_info = sys_rst_info; 186 - } else { 187 - pr_err("Incompatible DT node '%s' specified\n", 188 - of_node_full_name(rst_init->np)); 189 - ret = -EINVAL; 190 - goto err_kfree_rst; 191 - } 192 - 193 - rst->rcdev.owner = THIS_MODULE; 194 - rst->rcdev.ops = &ccu_rst_ops; 195 - rst->rcdev.of_node = rst_init->np; 196 - 197 - ret = reset_controller_register(&rst->rcdev); 198 - if (ret) { 199 - pr_err("Couldn't register '%s' reset controller\n", 200 - of_node_full_name(rst_init->np)); 201 - goto err_kfree_rst; 202 - } 203 - 204 - return rst; 205 - 206 - err_kfree_rst: 207 - kfree(rst); 208 - 209 - return ERR_PTR(ret); 210 - } 211 - 212 - void ccu_rst_hw_unregister(struct ccu_rst *rst) 213 - { 214 - reset_controller_unregister(&rst->rcdev); 215 - 216 - kfree(rst); 217 - }
-67
drivers/clk/baikal-t1/ccu-rst.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* 3 - * Copyright (C) 2021 BAIKAL ELECTRONICS, JSC 4 - * 5 - * Baikal-T1 CCU Resets interface driver 6 - */ 7 - #ifndef __CLK_BT1_CCU_RST_H__ 8 - #define __CLK_BT1_CCU_RST_H__ 9 - 10 - #include <linux/of.h> 11 - #include <linux/regmap.h> 12 - #include <linux/reset-controller.h> 13 - 14 - struct ccu_rst_info; 15 - 16 - /* 17 - * enum ccu_rst_type - CCU Reset types 18 - * @CCU_RST_TRIG: Self-deasserted reset signal. 19 - * @CCU_RST_DIR: Directly controlled reset signal. 20 - */ 21 - enum ccu_rst_type { 22 - CCU_RST_TRIG, 23 - CCU_RST_DIR, 24 - }; 25 - 26 - /* 27 - * struct ccu_rst_init_data - CCU Resets initialization data 28 - * @sys_regs: Baikal-T1 System Controller registers map. 29 - * @np: Pointer to the node with the System CCU block. 30 - */ 31 - struct ccu_rst_init_data { 32 - struct regmap *sys_regs; 33 - struct device_node *np; 34 - }; 35 - 36 - /* 37 - * struct ccu_rst - CCU Reset descriptor 38 - * @rcdev: Reset controller descriptor. 39 - * @sys_regs: Baikal-T1 System Controller registers map. 40 - * @rsts_info: Reset flag info (base address and mask). 41 - */ 42 - struct ccu_rst { 43 - struct reset_controller_dev rcdev; 44 - struct regmap *sys_regs; 45 - const struct ccu_rst_info *rsts_info; 46 - }; 47 - #define to_ccu_rst(_rcdev) container_of(_rcdev, struct ccu_rst, rcdev) 48 - 49 - #ifdef CONFIG_CLK_BT1_CCU_RST 50 - 51 - struct ccu_rst *ccu_rst_hw_register(const struct ccu_rst_init_data *init); 52 - 53 - void ccu_rst_hw_unregister(struct ccu_rst *rst); 54 - 55 - #else 56 - 57 - static inline 58 - struct ccu_rst *ccu_rst_hw_register(const struct ccu_rst_init_data *init) 59 - { 60 - return NULL; 61 - } 62 - 63 - static inline void ccu_rst_hw_unregister(struct ccu_rst *rst) {} 64 - 65 - #endif 66 - 67 - #endif /* __CLK_BT1_CCU_RST_H__ */
-520
drivers/clk/baikal-t1/clk-ccu-div.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC 4 - * 5 - * Authors: 6 - * Serge Semin <Sergey.Semin@baikalelectronics.ru> 7 - * Dmitry Dunaev <dmitry.dunaev@baikalelectronics.ru> 8 - * 9 - * Baikal-T1 CCU Dividers clock driver 10 - */ 11 - 12 - #define pr_fmt(fmt) "bt1-ccu-div: " fmt 13 - 14 - #include <linux/kernel.h> 15 - #include <linux/platform_device.h> 16 - #include <linux/printk.h> 17 - #include <linux/slab.h> 18 - #include <linux/clk-provider.h> 19 - #include <linux/reset-controller.h> 20 - #include <linux/mfd/syscon.h> 21 - #include <linux/of.h> 22 - #include <linux/of_address.h> 23 - #include <linux/ioport.h> 24 - #include <linux/regmap.h> 25 - 26 - #include <dt-bindings/clock/bt1-ccu.h> 27 - 28 - #include "ccu-div.h" 29 - #include "ccu-rst.h" 30 - 31 - #define CCU_AXI_MAIN_BASE 0x030 32 - #define CCU_AXI_DDR_BASE 0x034 33 - #define CCU_AXI_SATA_BASE 0x038 34 - #define CCU_AXI_GMAC0_BASE 0x03C 35 - #define CCU_AXI_GMAC1_BASE 0x040 36 - #define CCU_AXI_XGMAC_BASE 0x044 37 - #define CCU_AXI_PCIE_M_BASE 0x048 38 - #define CCU_AXI_PCIE_S_BASE 0x04C 39 - #define CCU_AXI_USB_BASE 0x050 40 - #define CCU_AXI_HWA_BASE 0x054 41 - #define CCU_AXI_SRAM_BASE 0x058 42 - 43 - #define CCU_SYS_SATA_REF_BASE 0x060 44 - #define CCU_SYS_APB_BASE 0x064 45 - #define CCU_SYS_GMAC0_BASE 0x068 46 - #define CCU_SYS_GMAC1_BASE 0x06C 47 - #define CCU_SYS_XGMAC_BASE 0x070 48 - #define CCU_SYS_USB_BASE 0x074 49 - #define CCU_SYS_PVT_BASE 0x078 50 - #define CCU_SYS_HWA_BASE 0x07C 51 - #define CCU_SYS_UART_BASE 0x084 52 - #define CCU_SYS_TIMER0_BASE 0x088 53 - #define CCU_SYS_TIMER1_BASE 0x08C 54 - #define CCU_SYS_TIMER2_BASE 0x090 55 - #define CCU_SYS_WDT_BASE 0x150 56 - 57 - #define CCU_DIV_VAR_INFO(_id, _name, _pname, _base, _width, _flags, _features) \ 58 - { \ 59 - .id = _id, \ 60 - .name = _name, \ 61 - .parent_name = _pname, \ 62 - .base = _base, \ 63 - .type = CCU_DIV_VAR, \ 64 - .width = _width, \ 65 - .flags = _flags, \ 66 - .features = _features \ 67 - } 68 - 69 - #define CCU_DIV_GATE_INFO(_id, _name, _pname, _base, _divider) \ 70 - { \ 71 - .id = _id, \ 72 - .name = _name, \ 73 - .parent_name = _pname, \ 74 - .base = _base, \ 75 - .type = CCU_DIV_GATE, \ 76 - .divider = _divider \ 77 - } 78 - 79 - #define CCU_DIV_BUF_INFO(_id, _name, _pname, _base, _flags) \ 80 - { \ 81 - .id = _id, \ 82 - .name = _name, \ 83 - .parent_name = _pname, \ 84 - .base = _base, \ 85 - .type = CCU_DIV_BUF, \ 86 - .flags = _flags \ 87 - } 88 - 89 - #define CCU_DIV_FIXED_INFO(_id, _name, _pname, _divider) \ 90 - { \ 91 - .id = _id, \ 92 - .name = _name, \ 93 - .parent_name = _pname, \ 94 - .type = CCU_DIV_FIXED, \ 95 - .divider = _divider \ 96 - } 97 - 98 - struct ccu_div_info { 99 - unsigned int id; 100 - const char *name; 101 - const char *parent_name; 102 - unsigned int base; 103 - enum ccu_div_type type; 104 - union { 105 - unsigned int width; 106 - unsigned int divider; 107 - }; 108 - unsigned long flags; 109 - unsigned long features; 110 - }; 111 - 112 - struct ccu_div_data { 113 - struct device_node *np; 114 - struct regmap *sys_regs; 115 - 116 - unsigned int divs_num; 117 - const struct ccu_div_info *divs_info; 118 - struct ccu_div **divs; 119 - 120 - struct ccu_rst *rsts; 121 - }; 122 - 123 - /* 124 - * AXI Main Interconnect (axi_main_clk) and DDR AXI-bus (axi_ddr_clk) clocks 125 - * must be left enabled in any case, since former one is responsible for 126 - * clocking a bus between CPU cores and the rest of the SoC components, while 127 - * the later is clocking the AXI-bus between DDR controller and the Main 128 - * Interconnect. So should any of these clocks get to be disabled, the system 129 - * will literally stop working. That's why we marked them as critical. 130 - */ 131 - static const struct ccu_div_info axi_info[] = { 132 - CCU_DIV_VAR_INFO(CCU_AXI_MAIN_CLK, "axi_main_clk", "pcie_clk", 133 - CCU_AXI_MAIN_BASE, 4, 134 - CLK_IS_CRITICAL, CCU_DIV_RESET_DOMAIN), 135 - CCU_DIV_VAR_INFO(CCU_AXI_DDR_CLK, "axi_ddr_clk", "sata_clk", 136 - CCU_AXI_DDR_BASE, 4, 137 - CLK_IS_CRITICAL | CLK_SET_RATE_GATE, 138 - CCU_DIV_RESET_DOMAIN), 139 - CCU_DIV_VAR_INFO(CCU_AXI_SATA_CLK, "axi_sata_clk", "sata_clk", 140 - CCU_AXI_SATA_BASE, 4, 141 - CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN), 142 - CCU_DIV_VAR_INFO(CCU_AXI_GMAC0_CLK, "axi_gmac0_clk", "eth_clk", 143 - CCU_AXI_GMAC0_BASE, 4, 144 - CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN), 145 - CCU_DIV_VAR_INFO(CCU_AXI_GMAC1_CLK, "axi_gmac1_clk", "eth_clk", 146 - CCU_AXI_GMAC1_BASE, 4, 147 - CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN), 148 - CCU_DIV_VAR_INFO(CCU_AXI_XGMAC_CLK, "axi_xgmac_clk", "eth_clk", 149 - CCU_AXI_XGMAC_BASE, 4, 150 - CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN), 151 - CCU_DIV_VAR_INFO(CCU_AXI_PCIE_M_CLK, "axi_pcie_m_clk", "pcie_clk", 152 - CCU_AXI_PCIE_M_BASE, 4, 153 - CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN), 154 - CCU_DIV_VAR_INFO(CCU_AXI_PCIE_S_CLK, "axi_pcie_s_clk", "pcie_clk", 155 - CCU_AXI_PCIE_S_BASE, 4, 156 - CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN), 157 - CCU_DIV_VAR_INFO(CCU_AXI_USB_CLK, "axi_usb_clk", "sata_clk", 158 - CCU_AXI_USB_BASE, 4, 159 - CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN), 160 - CCU_DIV_VAR_INFO(CCU_AXI_HWA_CLK, "axi_hwa_clk", "sata_clk", 161 - CCU_AXI_HWA_BASE, 4, 162 - CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN), 163 - CCU_DIV_VAR_INFO(CCU_AXI_SRAM_CLK, "axi_sram_clk", "eth_clk", 164 - CCU_AXI_SRAM_BASE, 4, 165 - CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN) 166 - }; 167 - 168 - /* 169 - * APB-bus clock is marked as critical since it's a main communication bus 170 - * for the SoC devices registers IO-operations. 171 - */ 172 - static const struct ccu_div_info sys_info[] = { 173 - CCU_DIV_VAR_INFO(CCU_SYS_SATA_CLK, "sys_sata_clk", 174 - "sata_clk", CCU_SYS_SATA_REF_BASE, 4, 175 - CLK_SET_RATE_GATE, 176 - CCU_DIV_SKIP_ONE | CCU_DIV_LOCK_SHIFTED | 177 - CCU_DIV_RESET_DOMAIN), 178 - CCU_DIV_BUF_INFO(CCU_SYS_SATA_REF_CLK, "sys_sata_ref_clk", 179 - "sys_sata_clk", CCU_SYS_SATA_REF_BASE, 180 - CLK_SET_RATE_PARENT), 181 - CCU_DIV_VAR_INFO(CCU_SYS_APB_CLK, "sys_apb_clk", 182 - "pcie_clk", CCU_SYS_APB_BASE, 5, 183 - CLK_IS_CRITICAL, CCU_DIV_BASIC | CCU_DIV_RESET_DOMAIN), 184 - CCU_DIV_GATE_INFO(CCU_SYS_GMAC0_TX_CLK, "sys_gmac0_tx_clk", 185 - "eth_clk", CCU_SYS_GMAC0_BASE, 5), 186 - CCU_DIV_FIXED_INFO(CCU_SYS_GMAC0_PTP_CLK, "sys_gmac0_ptp_clk", 187 - "eth_clk", 10), 188 - CCU_DIV_GATE_INFO(CCU_SYS_GMAC1_TX_CLK, "sys_gmac1_tx_clk", 189 - "eth_clk", CCU_SYS_GMAC1_BASE, 5), 190 - CCU_DIV_FIXED_INFO(CCU_SYS_GMAC1_PTP_CLK, "sys_gmac1_ptp_clk", 191 - "eth_clk", 10), 192 - CCU_DIV_GATE_INFO(CCU_SYS_XGMAC_CLK, "sys_xgmac_clk", 193 - "eth_clk", CCU_SYS_XGMAC_BASE, 1), 194 - CCU_DIV_FIXED_INFO(CCU_SYS_XGMAC_REF_CLK, "sys_xgmac_ref_clk", 195 - "sys_xgmac_clk", 8), 196 - CCU_DIV_FIXED_INFO(CCU_SYS_XGMAC_PTP_CLK, "sys_xgmac_ptp_clk", 197 - "sys_xgmac_clk", 8), 198 - CCU_DIV_GATE_INFO(CCU_SYS_USB_CLK, "sys_usb_clk", 199 - "eth_clk", CCU_SYS_USB_BASE, 10), 200 - CCU_DIV_VAR_INFO(CCU_SYS_PVT_CLK, "sys_pvt_clk", 201 - "ref_clk", CCU_SYS_PVT_BASE, 5, 202 - CLK_SET_RATE_GATE, 0), 203 - CCU_DIV_VAR_INFO(CCU_SYS_HWA_CLK, "sys_hwa_clk", 204 - "sata_clk", CCU_SYS_HWA_BASE, 4, 205 - CLK_SET_RATE_GATE, 0), 206 - CCU_DIV_VAR_INFO(CCU_SYS_UART_CLK, "sys_uart_clk", 207 - "eth_clk", CCU_SYS_UART_BASE, 17, 208 - CLK_SET_RATE_GATE, 0), 209 - CCU_DIV_FIXED_INFO(CCU_SYS_I2C1_CLK, "sys_i2c1_clk", 210 - "eth_clk", 10), 211 - CCU_DIV_FIXED_INFO(CCU_SYS_I2C2_CLK, "sys_i2c2_clk", 212 - "eth_clk", 10), 213 - CCU_DIV_FIXED_INFO(CCU_SYS_GPIO_CLK, "sys_gpio_clk", 214 - "ref_clk", 25), 215 - CCU_DIV_VAR_INFO(CCU_SYS_TIMER0_CLK, "sys_timer0_clk", 216 - "ref_clk", CCU_SYS_TIMER0_BASE, 17, 217 - CLK_SET_RATE_GATE, CCU_DIV_BASIC), 218 - CCU_DIV_VAR_INFO(CCU_SYS_TIMER1_CLK, "sys_timer1_clk", 219 - "ref_clk", CCU_SYS_TIMER1_BASE, 17, 220 - CLK_SET_RATE_GATE, CCU_DIV_BASIC), 221 - CCU_DIV_VAR_INFO(CCU_SYS_TIMER2_CLK, "sys_timer2_clk", 222 - "ref_clk", CCU_SYS_TIMER2_BASE, 17, 223 - CLK_SET_RATE_GATE, CCU_DIV_BASIC), 224 - CCU_DIV_VAR_INFO(CCU_SYS_WDT_CLK, "sys_wdt_clk", 225 - "eth_clk", CCU_SYS_WDT_BASE, 17, 226 - CLK_SET_RATE_GATE, CCU_DIV_SKIP_ONE_TO_THREE) 227 - }; 228 - 229 - static struct ccu_div_data *axi_data; 230 - static struct ccu_div_data *sys_data; 231 - 232 - static void ccu_div_set_data(struct ccu_div_data *data) 233 - { 234 - struct device_node *np = data->np; 235 - 236 - if (of_device_is_compatible(np, "baikal,bt1-ccu-axi")) 237 - axi_data = data; 238 - else if (of_device_is_compatible(np, "baikal,bt1-ccu-sys")) 239 - sys_data = data; 240 - else 241 - pr_err("Invalid DT node '%s' specified\n", of_node_full_name(np)); 242 - } 243 - 244 - static struct ccu_div_data *ccu_div_get_data(struct device_node *np) 245 - { 246 - if (of_device_is_compatible(np, "baikal,bt1-ccu-axi")) 247 - return axi_data; 248 - else if (of_device_is_compatible(np, "baikal,bt1-ccu-sys")) 249 - return sys_data; 250 - 251 - pr_err("Invalid DT node '%s' specified\n", of_node_full_name(np)); 252 - 253 - return NULL; 254 - } 255 - 256 - static struct ccu_div *ccu_div_find_desc(struct ccu_div_data *data, 257 - unsigned int clk_id) 258 - { 259 - int idx; 260 - 261 - for (idx = 0; idx < data->divs_num; ++idx) { 262 - if (data->divs_info[idx].id == clk_id) 263 - return data->divs[idx]; 264 - } 265 - 266 - return ERR_PTR(-EINVAL); 267 - } 268 - 269 - static struct ccu_div_data *ccu_div_create_data(struct device_node *np) 270 - { 271 - struct ccu_div_data *data; 272 - int ret; 273 - 274 - data = kzalloc_obj(*data); 275 - if (!data) 276 - return ERR_PTR(-ENOMEM); 277 - 278 - data->np = np; 279 - if (of_device_is_compatible(np, "baikal,bt1-ccu-axi")) { 280 - data->divs_num = ARRAY_SIZE(axi_info); 281 - data->divs_info = axi_info; 282 - } else if (of_device_is_compatible(np, "baikal,bt1-ccu-sys")) { 283 - data->divs_num = ARRAY_SIZE(sys_info); 284 - data->divs_info = sys_info; 285 - } else { 286 - pr_err("Incompatible DT node '%s' specified\n", 287 - of_node_full_name(np)); 288 - ret = -EINVAL; 289 - goto err_kfree_data; 290 - } 291 - 292 - data->divs = kzalloc_objs(*data->divs, data->divs_num); 293 - if (!data->divs) { 294 - ret = -ENOMEM; 295 - goto err_kfree_data; 296 - } 297 - 298 - return data; 299 - 300 - err_kfree_data: 301 - kfree(data); 302 - 303 - return ERR_PTR(ret); 304 - } 305 - 306 - static void ccu_div_free_data(struct ccu_div_data *data) 307 - { 308 - kfree(data->divs); 309 - 310 - kfree(data); 311 - } 312 - 313 - static int ccu_div_find_sys_regs(struct ccu_div_data *data) 314 - { 315 - data->sys_regs = syscon_node_to_regmap(data->np->parent); 316 - if (IS_ERR(data->sys_regs)) { 317 - pr_err("Failed to find syscon regs for '%s'\n", 318 - of_node_full_name(data->np)); 319 - return PTR_ERR(data->sys_regs); 320 - } 321 - 322 - return 0; 323 - } 324 - 325 - static struct clk_hw *ccu_div_of_clk_hw_get(struct of_phandle_args *clkspec, 326 - void *priv) 327 - { 328 - struct ccu_div_data *data = priv; 329 - struct ccu_div *div; 330 - unsigned int clk_id; 331 - 332 - clk_id = clkspec->args[0]; 333 - div = ccu_div_find_desc(data, clk_id); 334 - if (IS_ERR(div)) { 335 - if (div != ERR_PTR(-EPROBE_DEFER)) 336 - pr_info("Invalid clock ID %d specified\n", clk_id); 337 - 338 - return ERR_CAST(div); 339 - } 340 - 341 - return ccu_div_get_clk_hw(div); 342 - } 343 - 344 - static int ccu_div_clk_register(struct ccu_div_data *data, bool defer) 345 - { 346 - int idx, ret; 347 - 348 - for (idx = 0; idx < data->divs_num; ++idx) { 349 - const struct ccu_div_info *info = &data->divs_info[idx]; 350 - struct ccu_div_init_data init = {0}; 351 - 352 - if (!!(info->features & CCU_DIV_BASIC) ^ defer) { 353 - if (!data->divs[idx]) 354 - data->divs[idx] = ERR_PTR(-EPROBE_DEFER); 355 - 356 - continue; 357 - } 358 - 359 - init.id = info->id; 360 - init.name = info->name; 361 - init.parent_name = info->parent_name; 362 - init.np = data->np; 363 - init.type = info->type; 364 - init.flags = info->flags; 365 - init.features = info->features; 366 - 367 - if (init.type == CCU_DIV_VAR) { 368 - init.base = info->base; 369 - init.sys_regs = data->sys_regs; 370 - init.width = info->width; 371 - } else if (init.type == CCU_DIV_GATE) { 372 - init.base = info->base; 373 - init.sys_regs = data->sys_regs; 374 - init.divider = info->divider; 375 - } else if (init.type == CCU_DIV_BUF) { 376 - init.base = info->base; 377 - init.sys_regs = data->sys_regs; 378 - } else { 379 - init.divider = info->divider; 380 - } 381 - 382 - data->divs[idx] = ccu_div_hw_register(&init); 383 - if (IS_ERR(data->divs[idx])) { 384 - ret = PTR_ERR(data->divs[idx]); 385 - pr_err("Couldn't register divider '%s' hw\n", 386 - init.name); 387 - goto err_hw_unregister; 388 - } 389 - } 390 - 391 - return 0; 392 - 393 - err_hw_unregister: 394 - for (--idx; idx >= 0; --idx) { 395 - if (!!(data->divs_info[idx].features & CCU_DIV_BASIC) ^ defer) 396 - continue; 397 - 398 - ccu_div_hw_unregister(data->divs[idx]); 399 - } 400 - 401 - return ret; 402 - } 403 - 404 - static void ccu_div_clk_unregister(struct ccu_div_data *data, bool defer) 405 - { 406 - int idx; 407 - 408 - /* Uninstall only the clocks registered on the specified stage */ 409 - for (idx = 0; idx < data->divs_num; ++idx) { 410 - if (!!(data->divs_info[idx].features & CCU_DIV_BASIC) ^ defer) 411 - continue; 412 - 413 - ccu_div_hw_unregister(data->divs[idx]); 414 - } 415 - } 416 - 417 - static int ccu_div_of_register(struct ccu_div_data *data) 418 - { 419 - int ret; 420 - 421 - ret = of_clk_add_hw_provider(data->np, ccu_div_of_clk_hw_get, data); 422 - if (ret) { 423 - pr_err("Couldn't register dividers '%s' clock provider\n", 424 - of_node_full_name(data->np)); 425 - } 426 - 427 - return ret; 428 - } 429 - 430 - static int ccu_div_rst_register(struct ccu_div_data *data) 431 - { 432 - struct ccu_rst_init_data init = {0}; 433 - 434 - init.sys_regs = data->sys_regs; 435 - init.np = data->np; 436 - 437 - data->rsts = ccu_rst_hw_register(&init); 438 - if (IS_ERR(data->rsts)) { 439 - pr_err("Couldn't register divider '%s' reset controller\n", 440 - of_node_full_name(data->np)); 441 - return PTR_ERR(data->rsts); 442 - } 443 - 444 - return 0; 445 - } 446 - 447 - static int ccu_div_probe(struct platform_device *pdev) 448 - { 449 - struct ccu_div_data *data; 450 - int ret; 451 - 452 - data = ccu_div_get_data(dev_of_node(&pdev->dev)); 453 - if (!data) 454 - return -EINVAL; 455 - 456 - ret = ccu_div_clk_register(data, false); 457 - if (ret) 458 - return ret; 459 - 460 - ret = ccu_div_rst_register(data); 461 - if (ret) 462 - goto err_clk_unregister; 463 - 464 - return 0; 465 - 466 - err_clk_unregister: 467 - ccu_div_clk_unregister(data, false); 468 - 469 - return ret; 470 - } 471 - 472 - static const struct of_device_id ccu_div_of_match[] = { 473 - { .compatible = "baikal,bt1-ccu-axi" }, 474 - { .compatible = "baikal,bt1-ccu-sys" }, 475 - { } 476 - }; 477 - 478 - static struct platform_driver ccu_div_driver = { 479 - .probe = ccu_div_probe, 480 - .driver = { 481 - .name = "clk-ccu-div", 482 - .of_match_table = ccu_div_of_match, 483 - .suppress_bind_attrs = true, 484 - }, 485 - }; 486 - builtin_platform_driver(ccu_div_driver); 487 - 488 - static __init void ccu_div_init(struct device_node *np) 489 - { 490 - struct ccu_div_data *data; 491 - int ret; 492 - 493 - data = ccu_div_create_data(np); 494 - if (IS_ERR(data)) 495 - return; 496 - 497 - ret = ccu_div_find_sys_regs(data); 498 - if (ret) 499 - goto err_free_data; 500 - 501 - ret = ccu_div_clk_register(data, true); 502 - if (ret) 503 - goto err_free_data; 504 - 505 - ret = ccu_div_of_register(data); 506 - if (ret) 507 - goto err_clk_unregister; 508 - 509 - ccu_div_set_data(data); 510 - 511 - return; 512 - 513 - err_clk_unregister: 514 - ccu_div_clk_unregister(data, true); 515 - 516 - err_free_data: 517 - ccu_div_free_data(data); 518 - } 519 - CLK_OF_DECLARE_DRIVER(ccu_axi, "baikal,bt1-ccu-axi", ccu_div_init); 520 - CLK_OF_DECLARE_DRIVER(ccu_sys, "baikal,bt1-ccu-sys", ccu_div_init);
-277
drivers/clk/baikal-t1/clk-ccu-pll.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC 4 - * 5 - * Authors: 6 - * Serge Semin <Sergey.Semin@baikalelectronics.ru> 7 - * Dmitry Dunaev <dmitry.dunaev@baikalelectronics.ru> 8 - * 9 - * Baikal-T1 CCU PLL clocks driver 10 - */ 11 - 12 - #define pr_fmt(fmt) "bt1-ccu-pll: " fmt 13 - 14 - #include <linux/kernel.h> 15 - #include <linux/platform_device.h> 16 - #include <linux/printk.h> 17 - #include <linux/slab.h> 18 - #include <linux/clk-provider.h> 19 - #include <linux/mfd/syscon.h> 20 - #include <linux/of.h> 21 - #include <linux/of_address.h> 22 - #include <linux/ioport.h> 23 - #include <linux/regmap.h> 24 - 25 - #include <dt-bindings/clock/bt1-ccu.h> 26 - 27 - #include "ccu-pll.h" 28 - 29 - #define CCU_CPU_PLL_BASE 0x000 30 - #define CCU_SATA_PLL_BASE 0x008 31 - #define CCU_DDR_PLL_BASE 0x010 32 - #define CCU_PCIE_PLL_BASE 0x018 33 - #define CCU_ETH_PLL_BASE 0x020 34 - 35 - #define CCU_PLL_INFO(_id, _name, _pname, _base, _flags, _features) \ 36 - { \ 37 - .id = _id, \ 38 - .name = _name, \ 39 - .parent_name = _pname, \ 40 - .base = _base, \ 41 - .flags = _flags, \ 42 - .features = _features, \ 43 - } 44 - 45 - #define CCU_PLL_NUM ARRAY_SIZE(pll_info) 46 - 47 - struct ccu_pll_info { 48 - unsigned int id; 49 - const char *name; 50 - const char *parent_name; 51 - unsigned int base; 52 - unsigned long flags; 53 - unsigned long features; 54 - }; 55 - 56 - /* 57 - * Alas we have to mark all PLLs as critical. CPU and DDR PLLs are sources of 58 - * CPU cores and DDR controller reference clocks, due to which they obviously 59 - * shouldn't be ever gated. SATA and PCIe PLLs are the parents of APB-bus and 60 - * DDR controller AXI-bus clocks. If they are gated the system will be 61 - * unusable. Moreover disabling SATA and Ethernet PLLs causes automatic reset 62 - * of the corresponding subsystems. So until we aren't ready to re-initialize 63 - * all the devices consuming those PLLs, they will be marked as critical too. 64 - */ 65 - static const struct ccu_pll_info pll_info[] = { 66 - CCU_PLL_INFO(CCU_CPU_PLL, "cpu_pll", "ref_clk", CCU_CPU_PLL_BASE, 67 - CLK_IS_CRITICAL, CCU_PLL_BASIC), 68 - CCU_PLL_INFO(CCU_SATA_PLL, "sata_pll", "ref_clk", CCU_SATA_PLL_BASE, 69 - CLK_IS_CRITICAL | CLK_SET_RATE_GATE, 0), 70 - CCU_PLL_INFO(CCU_DDR_PLL, "ddr_pll", "ref_clk", CCU_DDR_PLL_BASE, 71 - CLK_IS_CRITICAL | CLK_SET_RATE_GATE, 0), 72 - CCU_PLL_INFO(CCU_PCIE_PLL, "pcie_pll", "ref_clk", CCU_PCIE_PLL_BASE, 73 - CLK_IS_CRITICAL, CCU_PLL_BASIC), 74 - CCU_PLL_INFO(CCU_ETH_PLL, "eth_pll", "ref_clk", CCU_ETH_PLL_BASE, 75 - CLK_IS_CRITICAL | CLK_SET_RATE_GATE, 0) 76 - }; 77 - 78 - struct ccu_pll_data { 79 - struct device_node *np; 80 - struct regmap *sys_regs; 81 - struct ccu_pll *plls[CCU_PLL_NUM]; 82 - }; 83 - 84 - static struct ccu_pll_data *pll_data; 85 - 86 - static struct ccu_pll *ccu_pll_find_desc(struct ccu_pll_data *data, 87 - unsigned int clk_id) 88 - { 89 - int idx; 90 - 91 - for (idx = 0; idx < CCU_PLL_NUM; ++idx) { 92 - if (pll_info[idx].id == clk_id) 93 - return data->plls[idx]; 94 - } 95 - 96 - return ERR_PTR(-EINVAL); 97 - } 98 - 99 - static struct ccu_pll_data *ccu_pll_create_data(struct device_node *np) 100 - { 101 - struct ccu_pll_data *data; 102 - 103 - data = kzalloc_obj(*data); 104 - if (!data) 105 - return ERR_PTR(-ENOMEM); 106 - 107 - data->np = np; 108 - 109 - return data; 110 - } 111 - 112 - static void ccu_pll_free_data(struct ccu_pll_data *data) 113 - { 114 - kfree(data); 115 - } 116 - 117 - static int ccu_pll_find_sys_regs(struct ccu_pll_data *data) 118 - { 119 - data->sys_regs = syscon_node_to_regmap(data->np->parent); 120 - if (IS_ERR(data->sys_regs)) { 121 - pr_err("Failed to find syscon regs for '%s'\n", 122 - of_node_full_name(data->np)); 123 - return PTR_ERR(data->sys_regs); 124 - } 125 - 126 - return 0; 127 - } 128 - 129 - static struct clk_hw *ccu_pll_of_clk_hw_get(struct of_phandle_args *clkspec, 130 - void *priv) 131 - { 132 - struct ccu_pll_data *data = priv; 133 - struct ccu_pll *pll; 134 - unsigned int clk_id; 135 - 136 - clk_id = clkspec->args[0]; 137 - pll = ccu_pll_find_desc(data, clk_id); 138 - if (IS_ERR(pll)) { 139 - if (pll != ERR_PTR(-EPROBE_DEFER)) 140 - pr_info("Invalid PLL clock ID %d specified\n", clk_id); 141 - 142 - return ERR_CAST(pll); 143 - } 144 - 145 - return ccu_pll_get_clk_hw(pll); 146 - } 147 - 148 - static int ccu_pll_clk_register(struct ccu_pll_data *data, bool defer) 149 - { 150 - int idx, ret; 151 - 152 - for (idx = 0; idx < CCU_PLL_NUM; ++idx) { 153 - const struct ccu_pll_info *info = &pll_info[idx]; 154 - struct ccu_pll_init_data init = {0}; 155 - 156 - /* Defer non-basic PLLs allocation for the probe stage */ 157 - if (!!(info->features & CCU_PLL_BASIC) ^ defer) { 158 - if (!data->plls[idx]) 159 - data->plls[idx] = ERR_PTR(-EPROBE_DEFER); 160 - 161 - continue; 162 - } 163 - 164 - init.id = info->id; 165 - init.name = info->name; 166 - init.parent_name = info->parent_name; 167 - init.base = info->base; 168 - init.sys_regs = data->sys_regs; 169 - init.np = data->np; 170 - init.flags = info->flags; 171 - init.features = info->features; 172 - 173 - data->plls[idx] = ccu_pll_hw_register(&init); 174 - if (IS_ERR(data->plls[idx])) { 175 - ret = PTR_ERR(data->plls[idx]); 176 - pr_err("Couldn't register PLL hw '%s'\n", 177 - init.name); 178 - goto err_hw_unregister; 179 - } 180 - } 181 - 182 - return 0; 183 - 184 - err_hw_unregister: 185 - for (--idx; idx >= 0; --idx) { 186 - if (!!(pll_info[idx].features & CCU_PLL_BASIC) ^ defer) 187 - continue; 188 - 189 - ccu_pll_hw_unregister(data->plls[idx]); 190 - } 191 - 192 - return ret; 193 - } 194 - 195 - static void ccu_pll_clk_unregister(struct ccu_pll_data *data, bool defer) 196 - { 197 - int idx; 198 - 199 - /* Uninstall only the clocks registered on the specified stage */ 200 - for (idx = 0; idx < CCU_PLL_NUM; ++idx) { 201 - if (!!(pll_info[idx].features & CCU_PLL_BASIC) ^ defer) 202 - continue; 203 - 204 - ccu_pll_hw_unregister(data->plls[idx]); 205 - } 206 - } 207 - 208 - static int ccu_pll_of_register(struct ccu_pll_data *data) 209 - { 210 - int ret; 211 - 212 - ret = of_clk_add_hw_provider(data->np, ccu_pll_of_clk_hw_get, data); 213 - if (ret) { 214 - pr_err("Couldn't register PLL provider of '%s'\n", 215 - of_node_full_name(data->np)); 216 - } 217 - 218 - return ret; 219 - } 220 - 221 - static int ccu_pll_probe(struct platform_device *pdev) 222 - { 223 - struct ccu_pll_data *data = pll_data; 224 - 225 - if (!data) 226 - return -EINVAL; 227 - 228 - return ccu_pll_clk_register(data, false); 229 - } 230 - 231 - static const struct of_device_id ccu_pll_of_match[] = { 232 - { .compatible = "baikal,bt1-ccu-pll" }, 233 - { } 234 - }; 235 - 236 - static struct platform_driver ccu_pll_driver = { 237 - .probe = ccu_pll_probe, 238 - .driver = { 239 - .name = "clk-ccu-pll", 240 - .of_match_table = ccu_pll_of_match, 241 - .suppress_bind_attrs = true, 242 - }, 243 - }; 244 - builtin_platform_driver(ccu_pll_driver); 245 - 246 - static __init void ccu_pll_init(struct device_node *np) 247 - { 248 - struct ccu_pll_data *data; 249 - int ret; 250 - 251 - data = ccu_pll_create_data(np); 252 - if (IS_ERR(data)) 253 - return; 254 - 255 - ret = ccu_pll_find_sys_regs(data); 256 - if (ret) 257 - goto err_free_data; 258 - 259 - ret = ccu_pll_clk_register(data, true); 260 - if (ret) 261 - goto err_free_data; 262 - 263 - ret = ccu_pll_of_register(data); 264 - if (ret) 265 - goto err_clk_unregister; 266 - 267 - pll_data = data; 268 - 269 - return; 270 - 271 - err_clk_unregister: 272 - ccu_pll_clk_unregister(data, true); 273 - 274 - err_free_data: 275 - ccu_pll_free_data(data); 276 - } 277 - CLK_OF_DECLARE_DRIVER(ccu_pll, "baikal,bt1-ccu-pll", ccu_pll_init);
-48
include/dt-bindings/clock/bt1-ccu.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* 3 - * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC 4 - * 5 - * Baikal-T1 CCU clock indices 6 - */ 7 - #ifndef __DT_BINDINGS_CLOCK_BT1_CCU_H 8 - #define __DT_BINDINGS_CLOCK_BT1_CCU_H 9 - 10 - #define CCU_CPU_PLL 0 11 - #define CCU_SATA_PLL 1 12 - #define CCU_DDR_PLL 2 13 - #define CCU_PCIE_PLL 3 14 - #define CCU_ETH_PLL 4 15 - 16 - #define CCU_AXI_MAIN_CLK 0 17 - #define CCU_AXI_DDR_CLK 1 18 - #define CCU_AXI_SATA_CLK 2 19 - #define CCU_AXI_GMAC0_CLK 3 20 - #define CCU_AXI_GMAC1_CLK 4 21 - #define CCU_AXI_XGMAC_CLK 5 22 - #define CCU_AXI_PCIE_M_CLK 6 23 - #define CCU_AXI_PCIE_S_CLK 7 24 - #define CCU_AXI_USB_CLK 8 25 - #define CCU_AXI_HWA_CLK 9 26 - #define CCU_AXI_SRAM_CLK 10 27 - 28 - #define CCU_SYS_SATA_REF_CLK 0 29 - #define CCU_SYS_APB_CLK 1 30 - #define CCU_SYS_GMAC0_TX_CLK 2 31 - #define CCU_SYS_GMAC0_PTP_CLK 3 32 - #define CCU_SYS_GMAC1_TX_CLK 4 33 - #define CCU_SYS_GMAC1_PTP_CLK 5 34 - #define CCU_SYS_XGMAC_REF_CLK 6 35 - #define CCU_SYS_XGMAC_PTP_CLK 7 36 - #define CCU_SYS_USB_CLK 8 37 - #define CCU_SYS_PVT_CLK 9 38 - #define CCU_SYS_HWA_CLK 10 39 - #define CCU_SYS_UART_CLK 11 40 - #define CCU_SYS_I2C1_CLK 12 41 - #define CCU_SYS_I2C2_CLK 13 42 - #define CCU_SYS_GPIO_CLK 14 43 - #define CCU_SYS_TIMER0_CLK 15 44 - #define CCU_SYS_TIMER1_CLK 16 45 - #define CCU_SYS_TIMER2_CLK 17 46 - #define CCU_SYS_WDT_CLK 18 47 - 48 - #endif /* __DT_BINDINGS_CLOCK_BT1_CCU_H */