linux-stable/drivers/clk/baikal-t1/clk-ccu-div.c

522 lines
14 KiB
C
Raw Normal View History

clk: Add Baikal-T1 CCU Dividers driver Nearly each Baikal-T1 IP-core is supposed to have a clock source of particular frequency. But since there are greater than five IP-blocks embedded into the SoC, the CCU PLLs can't fulfill all the needs. Baikal-T1 CCU provides a set of fixed and configurable clock dividers in order to generate a necessary signal for each chip sub-block. This driver creates the of-based hardware clocks for each divider available in Baikal-T1 CCU. The same way as for PLLs we split the functionality up into the clocks operations (gate, ungate, set rate, etc) and hardware clocks declaration/registration procedures. In accordance with the CCU documentation all its dividers are distributed into two CCU sub-blocks: AXI-bus and system devices reference clocks. The former sub-block is used to supply the clocks for AXI-bus interfaces (AXI clock domains) and the later one provides the SoC IP-cores reference clocks. Each sub-block is represented by a dedicated DT node, so they have different compatible strings to distinguish one from another. For some reason CCU provides the dividers of different types. Some dividers can be gateable some can't, some are fixed while the others are variable, some have special divider' limitations, some've got a non-standard register layout and so on. In order to cover all of these cases the hardware clocks driver is designed with an info-descriptor pattern. So there are special static descriptors declared for the dividers of each type with additional flags describing the block peculiarity. These descriptors are then used to create hardware clocks with proper operations. Some CCU dividers provide a way to reset a domain they generate a clock for. So the CCU AXI-bus and CCU system devices clock drivers also perform the reset controller registration. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Rob Herring <robh+dt@kernel.org> Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200526222056.18072-5-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Drop return from void function, silence sparse warnings about initializing structs with NULL vs. integer] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2020-05-26 22:20:56 +00:00
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
*
* Authors:
* Serge Semin <Sergey.Semin@baikalelectronics.ru>
* Dmitry Dunaev <dmitry.dunaev@baikalelectronics.ru>
*
* Baikal-T1 CCU Dividers clock driver
*/
#define pr_fmt(fmt) "bt1-ccu-div: " fmt
#include <linux/kernel.h>
clk: baikal-t1: Convert to platform device driver In accordance with the way the MIPS platform is normally design there are only six clock sources which need to be available on the kernel start in order to one end up booting correctly: + CPU PLL: needed by the r4k and MIPS GIC timer drivers. The former one is initialized by the arch code, while the later one is implemented in the mips-gic-timer.c driver as the OF-declared timer. + PCIe PLL: required as a parental clock source for the APB/timer domains. + APB clock: needed in order to access all the SoC CSRs at least for the timer OF-declared drivers. + APB Timer{0-2} clocks: these are the DW APB timers which drivers dw_apb_timer_of.c are implemented as the OF-declared timers. So as long as the clocks above are available early the kernel will normally work. Let's convert the Baikal-T1 CCU drivers to the platform device drivers keeping that in mind. Generally speaking the conversion isn't that complicated since the driver infrastructure has been designed as flexible enough for that. First we need to add a new PLL/Divider clock features flag which indicates the corresponding clock source as a basic one and that clock sources will be available on the kernel early boot stages. Second the internal PLL/Divider descriptors need to be initialized with -EPROBE_DEFER value as the corresponding clock source is unavailable at the early stages. They will be allocated and initialized on the Baikal-T1 clock platform driver probe procedure. Finally the already available PLL/Divider init functions need to be split up into two ones: init procedure performed in the framework of the OF-declared clock initialization (of_clk_init()), and the probe procedure called by the platform devices bus driver. Note the later method will just continue the system clocks initialization started in the former one. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20220929225402.9696-9-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Remove module things because the Kconfig is still bool] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-09-29 22:54:02 +00:00
#include <linux/platform_device.h>
clk: Add Baikal-T1 CCU Dividers driver Nearly each Baikal-T1 IP-core is supposed to have a clock source of particular frequency. But since there are greater than five IP-blocks embedded into the SoC, the CCU PLLs can't fulfill all the needs. Baikal-T1 CCU provides a set of fixed and configurable clock dividers in order to generate a necessary signal for each chip sub-block. This driver creates the of-based hardware clocks for each divider available in Baikal-T1 CCU. The same way as for PLLs we split the functionality up into the clocks operations (gate, ungate, set rate, etc) and hardware clocks declaration/registration procedures. In accordance with the CCU documentation all its dividers are distributed into two CCU sub-blocks: AXI-bus and system devices reference clocks. The former sub-block is used to supply the clocks for AXI-bus interfaces (AXI clock domains) and the later one provides the SoC IP-cores reference clocks. Each sub-block is represented by a dedicated DT node, so they have different compatible strings to distinguish one from another. For some reason CCU provides the dividers of different types. Some dividers can be gateable some can't, some are fixed while the others are variable, some have special divider' limitations, some've got a non-standard register layout and so on. In order to cover all of these cases the hardware clocks driver is designed with an info-descriptor pattern. So there are special static descriptors declared for the dividers of each type with additional flags describing the block peculiarity. These descriptors are then used to create hardware clocks with proper operations. Some CCU dividers provide a way to reset a domain they generate a clock for. So the CCU AXI-bus and CCU system devices clock drivers also perform the reset controller registration. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Rob Herring <robh+dt@kernel.org> Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200526222056.18072-5-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Drop return from void function, silence sparse warnings about initializing structs with NULL vs. integer] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2020-05-26 22:20:56 +00:00
#include <linux/printk.h>
#include <linux/slab.h>
#include <linux/clk-provider.h>
#include <linux/reset-controller.h>
#include <linux/mfd/syscon.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/ioport.h>
#include <linux/regmap.h>
#include <dt-bindings/clock/bt1-ccu.h>
#include "ccu-div.h"
clk: baikal-t1: Move reset-controls code into a dedicated module Before adding the directly controlled resets support it's reasonable to move the existing resets control functionality into a dedicated object for the sake of the CCU dividers clock driver simplification. After the new functionality was added clk-ccu-div.c would have got to a mixture of the weakly dependent clocks and resets methods. Splitting the methods up into the two objects will make the code easier to read and maintain. It shall also improve the code scalability (though hopefully we won't need this part that much in the future). The reset control functionality is now implemented in the framework of a single unit since splitting it up doesn't make much sense due to relatively simple reset operations. The ccu-rst.c has been designed to be looking like ccu-div.c or ccu-pll.c with two globally available methods for the sake of the code unification and better code readability. This commit doesn't provide any change in the CCU reset implementation semantics. As before the driver will support the trigger-like CCU resets only, which are responsible for the AXI-bus, APB-bus and SATA-ref blocks reset. The assert/de-assert-capable reset controls support will be added in the next commit. Note the CCU Clock dividers and resets functionality split up was possible due to not having any side-effects (at least we didn't found ones) of the regmap-based concurrent access of the common CCU dividers/reset CSRs. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> Link: https://lore.kernel.org/r/20220929225402.9696-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-09-29 22:53:59 +00:00
#include "ccu-rst.h"
clk: Add Baikal-T1 CCU Dividers driver Nearly each Baikal-T1 IP-core is supposed to have a clock source of particular frequency. But since there are greater than five IP-blocks embedded into the SoC, the CCU PLLs can't fulfill all the needs. Baikal-T1 CCU provides a set of fixed and configurable clock dividers in order to generate a necessary signal for each chip sub-block. This driver creates the of-based hardware clocks for each divider available in Baikal-T1 CCU. The same way as for PLLs we split the functionality up into the clocks operations (gate, ungate, set rate, etc) and hardware clocks declaration/registration procedures. In accordance with the CCU documentation all its dividers are distributed into two CCU sub-blocks: AXI-bus and system devices reference clocks. The former sub-block is used to supply the clocks for AXI-bus interfaces (AXI clock domains) and the later one provides the SoC IP-cores reference clocks. Each sub-block is represented by a dedicated DT node, so they have different compatible strings to distinguish one from another. For some reason CCU provides the dividers of different types. Some dividers can be gateable some can't, some are fixed while the others are variable, some have special divider' limitations, some've got a non-standard register layout and so on. In order to cover all of these cases the hardware clocks driver is designed with an info-descriptor pattern. So there are special static descriptors declared for the dividers of each type with additional flags describing the block peculiarity. These descriptors are then used to create hardware clocks with proper operations. Some CCU dividers provide a way to reset a domain they generate a clock for. So the CCU AXI-bus and CCU system devices clock drivers also perform the reset controller registration. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Rob Herring <robh+dt@kernel.org> Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200526222056.18072-5-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Drop return from void function, silence sparse warnings about initializing structs with NULL vs. integer] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2020-05-26 22:20:56 +00:00
#define CCU_AXI_MAIN_BASE 0x030
#define CCU_AXI_DDR_BASE 0x034
#define CCU_AXI_SATA_BASE 0x038
#define CCU_AXI_GMAC0_BASE 0x03C
#define CCU_AXI_GMAC1_BASE 0x040
#define CCU_AXI_XGMAC_BASE 0x044
#define CCU_AXI_PCIE_M_BASE 0x048
#define CCU_AXI_PCIE_S_BASE 0x04C
#define CCU_AXI_USB_BASE 0x050
#define CCU_AXI_HWA_BASE 0x054
#define CCU_AXI_SRAM_BASE 0x058
#define CCU_SYS_SATA_REF_BASE 0x060
#define CCU_SYS_APB_BASE 0x064
#define CCU_SYS_GMAC0_BASE 0x068
#define CCU_SYS_GMAC1_BASE 0x06C
#define CCU_SYS_XGMAC_BASE 0x070
#define CCU_SYS_USB_BASE 0x074
#define CCU_SYS_PVT_BASE 0x078
#define CCU_SYS_HWA_BASE 0x07C
#define CCU_SYS_UART_BASE 0x084
#define CCU_SYS_TIMER0_BASE 0x088
#define CCU_SYS_TIMER1_BASE 0x08C
#define CCU_SYS_TIMER2_BASE 0x090
#define CCU_SYS_WDT_BASE 0x150
#define CCU_DIV_VAR_INFO(_id, _name, _pname, _base, _width, _flags, _features) \
{ \
.id = _id, \
.name = _name, \
.parent_name = _pname, \
.base = _base, \
.type = CCU_DIV_VAR, \
.width = _width, \
.flags = _flags, \
.features = _features \
}
#define CCU_DIV_GATE_INFO(_id, _name, _pname, _base, _divider) \
{ \
.id = _id, \
.name = _name, \
.parent_name = _pname, \
.base = _base, \
.type = CCU_DIV_GATE, \
.divider = _divider \
}
#define CCU_DIV_BUF_INFO(_id, _name, _pname, _base, _flags) \
{ \
.id = _id, \
.name = _name, \
.parent_name = _pname, \
.base = _base, \
.type = CCU_DIV_BUF, \
.flags = _flags \
}
clk: Add Baikal-T1 CCU Dividers driver Nearly each Baikal-T1 IP-core is supposed to have a clock source of particular frequency. But since there are greater than five IP-blocks embedded into the SoC, the CCU PLLs can't fulfill all the needs. Baikal-T1 CCU provides a set of fixed and configurable clock dividers in order to generate a necessary signal for each chip sub-block. This driver creates the of-based hardware clocks for each divider available in Baikal-T1 CCU. The same way as for PLLs we split the functionality up into the clocks operations (gate, ungate, set rate, etc) and hardware clocks declaration/registration procedures. In accordance with the CCU documentation all its dividers are distributed into two CCU sub-blocks: AXI-bus and system devices reference clocks. The former sub-block is used to supply the clocks for AXI-bus interfaces (AXI clock domains) and the later one provides the SoC IP-cores reference clocks. Each sub-block is represented by a dedicated DT node, so they have different compatible strings to distinguish one from another. For some reason CCU provides the dividers of different types. Some dividers can be gateable some can't, some are fixed while the others are variable, some have special divider' limitations, some've got a non-standard register layout and so on. In order to cover all of these cases the hardware clocks driver is designed with an info-descriptor pattern. So there are special static descriptors declared for the dividers of each type with additional flags describing the block peculiarity. These descriptors are then used to create hardware clocks with proper operations. Some CCU dividers provide a way to reset a domain they generate a clock for. So the CCU AXI-bus and CCU system devices clock drivers also perform the reset controller registration. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Rob Herring <robh+dt@kernel.org> Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200526222056.18072-5-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Drop return from void function, silence sparse warnings about initializing structs with NULL vs. integer] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2020-05-26 22:20:56 +00:00
#define CCU_DIV_FIXED_INFO(_id, _name, _pname, _divider) \
{ \
.id = _id, \
.name = _name, \
.parent_name = _pname, \
.type = CCU_DIV_FIXED, \
.divider = _divider \
}
struct ccu_div_info {
unsigned int id;
const char *name;
const char *parent_name;
unsigned int base;
enum ccu_div_type type;
union {
unsigned int width;
unsigned int divider;
};
unsigned long flags;
unsigned long features;
};
struct ccu_div_data {
struct device_node *np;
struct regmap *sys_regs;
unsigned int divs_num;
const struct ccu_div_info *divs_info;
struct ccu_div **divs;
clk: baikal-t1: Move reset-controls code into a dedicated module Before adding the directly controlled resets support it's reasonable to move the existing resets control functionality into a dedicated object for the sake of the CCU dividers clock driver simplification. After the new functionality was added clk-ccu-div.c would have got to a mixture of the weakly dependent clocks and resets methods. Splitting the methods up into the two objects will make the code easier to read and maintain. It shall also improve the code scalability (though hopefully we won't need this part that much in the future). The reset control functionality is now implemented in the framework of a single unit since splitting it up doesn't make much sense due to relatively simple reset operations. The ccu-rst.c has been designed to be looking like ccu-div.c or ccu-pll.c with two globally available methods for the sake of the code unification and better code readability. This commit doesn't provide any change in the CCU reset implementation semantics. As before the driver will support the trigger-like CCU resets only, which are responsible for the AXI-bus, APB-bus and SATA-ref blocks reset. The assert/de-assert-capable reset controls support will be added in the next commit. Note the CCU Clock dividers and resets functionality split up was possible due to not having any side-effects (at least we didn't found ones) of the regmap-based concurrent access of the common CCU dividers/reset CSRs. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> Link: https://lore.kernel.org/r/20220929225402.9696-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-09-29 22:53:59 +00:00
struct ccu_rst *rsts;
clk: Add Baikal-T1 CCU Dividers driver Nearly each Baikal-T1 IP-core is supposed to have a clock source of particular frequency. But since there are greater than five IP-blocks embedded into the SoC, the CCU PLLs can't fulfill all the needs. Baikal-T1 CCU provides a set of fixed and configurable clock dividers in order to generate a necessary signal for each chip sub-block. This driver creates the of-based hardware clocks for each divider available in Baikal-T1 CCU. The same way as for PLLs we split the functionality up into the clocks operations (gate, ungate, set rate, etc) and hardware clocks declaration/registration procedures. In accordance with the CCU documentation all its dividers are distributed into two CCU sub-blocks: AXI-bus and system devices reference clocks. The former sub-block is used to supply the clocks for AXI-bus interfaces (AXI clock domains) and the later one provides the SoC IP-cores reference clocks. Each sub-block is represented by a dedicated DT node, so they have different compatible strings to distinguish one from another. For some reason CCU provides the dividers of different types. Some dividers can be gateable some can't, some are fixed while the others are variable, some have special divider' limitations, some've got a non-standard register layout and so on. In order to cover all of these cases the hardware clocks driver is designed with an info-descriptor pattern. So there are special static descriptors declared for the dividers of each type with additional flags describing the block peculiarity. These descriptors are then used to create hardware clocks with proper operations. Some CCU dividers provide a way to reset a domain they generate a clock for. So the CCU AXI-bus and CCU system devices clock drivers also perform the reset controller registration. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Rob Herring <robh+dt@kernel.org> Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200526222056.18072-5-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Drop return from void function, silence sparse warnings about initializing structs with NULL vs. integer] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2020-05-26 22:20:56 +00:00
};
/*
* AXI Main Interconnect (axi_main_clk) and DDR AXI-bus (axi_ddr_clk) clocks
* must be left enabled in any case, since former one is responsible for
* clocking a bus between CPU cores and the rest of the SoC components, while
* the later is clocking the AXI-bus between DDR controller and the Main
* Interconnect. So should any of these clocks get to be disabled, the system
* will literally stop working. That's why we marked them as critical.
*/
static const struct ccu_div_info axi_info[] = {
CCU_DIV_VAR_INFO(CCU_AXI_MAIN_CLK, "axi_main_clk", "pcie_clk",
CCU_AXI_MAIN_BASE, 4,
CLK_IS_CRITICAL, CCU_DIV_RESET_DOMAIN),
CCU_DIV_VAR_INFO(CCU_AXI_DDR_CLK, "axi_ddr_clk", "sata_clk",
CCU_AXI_DDR_BASE, 4,
CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
CCU_DIV_RESET_DOMAIN),
CCU_DIV_VAR_INFO(CCU_AXI_SATA_CLK, "axi_sata_clk", "sata_clk",
CCU_AXI_SATA_BASE, 4,
CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN),
CCU_DIV_VAR_INFO(CCU_AXI_GMAC0_CLK, "axi_gmac0_clk", "eth_clk",
CCU_AXI_GMAC0_BASE, 4,
CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN),
CCU_DIV_VAR_INFO(CCU_AXI_GMAC1_CLK, "axi_gmac1_clk", "eth_clk",
CCU_AXI_GMAC1_BASE, 4,
CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN),
CCU_DIV_VAR_INFO(CCU_AXI_XGMAC_CLK, "axi_xgmac_clk", "eth_clk",
CCU_AXI_XGMAC_BASE, 4,
CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN),
CCU_DIV_VAR_INFO(CCU_AXI_PCIE_M_CLK, "axi_pcie_m_clk", "pcie_clk",
CCU_AXI_PCIE_M_BASE, 4,
CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN),
CCU_DIV_VAR_INFO(CCU_AXI_PCIE_S_CLK, "axi_pcie_s_clk", "pcie_clk",
CCU_AXI_PCIE_S_BASE, 4,
CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN),
CCU_DIV_VAR_INFO(CCU_AXI_USB_CLK, "axi_usb_clk", "sata_clk",
CCU_AXI_USB_BASE, 4,
CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN),
CCU_DIV_VAR_INFO(CCU_AXI_HWA_CLK, "axi_hwa_clk", "sata_clk",
CCU_AXI_HWA_BASE, 4,
CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN),
CCU_DIV_VAR_INFO(CCU_AXI_SRAM_CLK, "axi_sram_clk", "eth_clk",
CCU_AXI_SRAM_BASE, 4,
CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN)
};
/*
* APB-bus clock is marked as critical since it's a main communication bus
* for the SoC devices registers IO-operations.
*/
static const struct ccu_div_info sys_info[] = {
CCU_DIV_VAR_INFO(CCU_SYS_SATA_CLK, "sys_sata_clk",
clk: Add Baikal-T1 CCU Dividers driver Nearly each Baikal-T1 IP-core is supposed to have a clock source of particular frequency. But since there are greater than five IP-blocks embedded into the SoC, the CCU PLLs can't fulfill all the needs. Baikal-T1 CCU provides a set of fixed and configurable clock dividers in order to generate a necessary signal for each chip sub-block. This driver creates the of-based hardware clocks for each divider available in Baikal-T1 CCU. The same way as for PLLs we split the functionality up into the clocks operations (gate, ungate, set rate, etc) and hardware clocks declaration/registration procedures. In accordance with the CCU documentation all its dividers are distributed into two CCU sub-blocks: AXI-bus and system devices reference clocks. The former sub-block is used to supply the clocks for AXI-bus interfaces (AXI clock domains) and the later one provides the SoC IP-cores reference clocks. Each sub-block is represented by a dedicated DT node, so they have different compatible strings to distinguish one from another. For some reason CCU provides the dividers of different types. Some dividers can be gateable some can't, some are fixed while the others are variable, some have special divider' limitations, some've got a non-standard register layout and so on. In order to cover all of these cases the hardware clocks driver is designed with an info-descriptor pattern. So there are special static descriptors declared for the dividers of each type with additional flags describing the block peculiarity. These descriptors are then used to create hardware clocks with proper operations. Some CCU dividers provide a way to reset a domain they generate a clock for. So the CCU AXI-bus and CCU system devices clock drivers also perform the reset controller registration. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Rob Herring <robh+dt@kernel.org> Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200526222056.18072-5-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Drop return from void function, silence sparse warnings about initializing structs with NULL vs. integer] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2020-05-26 22:20:56 +00:00
"sata_clk", CCU_SYS_SATA_REF_BASE, 4,
CLK_SET_RATE_GATE,
CCU_DIV_SKIP_ONE | CCU_DIV_LOCK_SHIFTED |
CCU_DIV_RESET_DOMAIN),
CCU_DIV_BUF_INFO(CCU_SYS_SATA_REF_CLK, "sys_sata_ref_clk",
"sys_sata_clk", CCU_SYS_SATA_REF_BASE,
CLK_SET_RATE_PARENT),
clk: Add Baikal-T1 CCU Dividers driver Nearly each Baikal-T1 IP-core is supposed to have a clock source of particular frequency. But since there are greater than five IP-blocks embedded into the SoC, the CCU PLLs can't fulfill all the needs. Baikal-T1 CCU provides a set of fixed and configurable clock dividers in order to generate a necessary signal for each chip sub-block. This driver creates the of-based hardware clocks for each divider available in Baikal-T1 CCU. The same way as for PLLs we split the functionality up into the clocks operations (gate, ungate, set rate, etc) and hardware clocks declaration/registration procedures. In accordance with the CCU documentation all its dividers are distributed into two CCU sub-blocks: AXI-bus and system devices reference clocks. The former sub-block is used to supply the clocks for AXI-bus interfaces (AXI clock domains) and the later one provides the SoC IP-cores reference clocks. Each sub-block is represented by a dedicated DT node, so they have different compatible strings to distinguish one from another. For some reason CCU provides the dividers of different types. Some dividers can be gateable some can't, some are fixed while the others are variable, some have special divider' limitations, some've got a non-standard register layout and so on. In order to cover all of these cases the hardware clocks driver is designed with an info-descriptor pattern. So there are special static descriptors declared for the dividers of each type with additional flags describing the block peculiarity. These descriptors are then used to create hardware clocks with proper operations. Some CCU dividers provide a way to reset a domain they generate a clock for. So the CCU AXI-bus and CCU system devices clock drivers also perform the reset controller registration. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Rob Herring <robh+dt@kernel.org> Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200526222056.18072-5-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Drop return from void function, silence sparse warnings about initializing structs with NULL vs. integer] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2020-05-26 22:20:56 +00:00
CCU_DIV_VAR_INFO(CCU_SYS_APB_CLK, "sys_apb_clk",
"pcie_clk", CCU_SYS_APB_BASE, 5,
clk: baikal-t1: Convert to platform device driver In accordance with the way the MIPS platform is normally design there are only six clock sources which need to be available on the kernel start in order to one end up booting correctly: + CPU PLL: needed by the r4k and MIPS GIC timer drivers. The former one is initialized by the arch code, while the later one is implemented in the mips-gic-timer.c driver as the OF-declared timer. + PCIe PLL: required as a parental clock source for the APB/timer domains. + APB clock: needed in order to access all the SoC CSRs at least for the timer OF-declared drivers. + APB Timer{0-2} clocks: these are the DW APB timers which drivers dw_apb_timer_of.c are implemented as the OF-declared timers. So as long as the clocks above are available early the kernel will normally work. Let's convert the Baikal-T1 CCU drivers to the platform device drivers keeping that in mind. Generally speaking the conversion isn't that complicated since the driver infrastructure has been designed as flexible enough for that. First we need to add a new PLL/Divider clock features flag which indicates the corresponding clock source as a basic one and that clock sources will be available on the kernel early boot stages. Second the internal PLL/Divider descriptors need to be initialized with -EPROBE_DEFER value as the corresponding clock source is unavailable at the early stages. They will be allocated and initialized on the Baikal-T1 clock platform driver probe procedure. Finally the already available PLL/Divider init functions need to be split up into two ones: init procedure performed in the framework of the OF-declared clock initialization (of_clk_init()), and the probe procedure called by the platform devices bus driver. Note the later method will just continue the system clocks initialization started in the former one. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20220929225402.9696-9-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Remove module things because the Kconfig is still bool] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-09-29 22:54:02 +00:00
CLK_IS_CRITICAL, CCU_DIV_BASIC | CCU_DIV_RESET_DOMAIN),
clk: Add Baikal-T1 CCU Dividers driver Nearly each Baikal-T1 IP-core is supposed to have a clock source of particular frequency. But since there are greater than five IP-blocks embedded into the SoC, the CCU PLLs can't fulfill all the needs. Baikal-T1 CCU provides a set of fixed and configurable clock dividers in order to generate a necessary signal for each chip sub-block. This driver creates the of-based hardware clocks for each divider available in Baikal-T1 CCU. The same way as for PLLs we split the functionality up into the clocks operations (gate, ungate, set rate, etc) and hardware clocks declaration/registration procedures. In accordance with the CCU documentation all its dividers are distributed into two CCU sub-blocks: AXI-bus and system devices reference clocks. The former sub-block is used to supply the clocks for AXI-bus interfaces (AXI clock domains) and the later one provides the SoC IP-cores reference clocks. Each sub-block is represented by a dedicated DT node, so they have different compatible strings to distinguish one from another. For some reason CCU provides the dividers of different types. Some dividers can be gateable some can't, some are fixed while the others are variable, some have special divider' limitations, some've got a non-standard register layout and so on. In order to cover all of these cases the hardware clocks driver is designed with an info-descriptor pattern. So there are special static descriptors declared for the dividers of each type with additional flags describing the block peculiarity. These descriptors are then used to create hardware clocks with proper operations. Some CCU dividers provide a way to reset a domain they generate a clock for. So the CCU AXI-bus and CCU system devices clock drivers also perform the reset controller registration. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Rob Herring <robh+dt@kernel.org> Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200526222056.18072-5-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Drop return from void function, silence sparse warnings about initializing structs with NULL vs. integer] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2020-05-26 22:20:56 +00:00
CCU_DIV_GATE_INFO(CCU_SYS_GMAC0_TX_CLK, "sys_gmac0_tx_clk",
"eth_clk", CCU_SYS_GMAC0_BASE, 5),
CCU_DIV_FIXED_INFO(CCU_SYS_GMAC0_PTP_CLK, "sys_gmac0_ptp_clk",
"eth_clk", 10),
CCU_DIV_GATE_INFO(CCU_SYS_GMAC1_TX_CLK, "sys_gmac1_tx_clk",
"eth_clk", CCU_SYS_GMAC1_BASE, 5),
CCU_DIV_FIXED_INFO(CCU_SYS_GMAC1_PTP_CLK, "sys_gmac1_ptp_clk",
"eth_clk", 10),
CCU_DIV_GATE_INFO(CCU_SYS_XGMAC_CLK, "sys_xgmac_clk",
"eth_clk", CCU_SYS_XGMAC_BASE, 1),
CCU_DIV_FIXED_INFO(CCU_SYS_XGMAC_REF_CLK, "sys_xgmac_ref_clk",
"sys_xgmac_clk", 8),
clk: Add Baikal-T1 CCU Dividers driver Nearly each Baikal-T1 IP-core is supposed to have a clock source of particular frequency. But since there are greater than five IP-blocks embedded into the SoC, the CCU PLLs can't fulfill all the needs. Baikal-T1 CCU provides a set of fixed and configurable clock dividers in order to generate a necessary signal for each chip sub-block. This driver creates the of-based hardware clocks for each divider available in Baikal-T1 CCU. The same way as for PLLs we split the functionality up into the clocks operations (gate, ungate, set rate, etc) and hardware clocks declaration/registration procedures. In accordance with the CCU documentation all its dividers are distributed into two CCU sub-blocks: AXI-bus and system devices reference clocks. The former sub-block is used to supply the clocks for AXI-bus interfaces (AXI clock domains) and the later one provides the SoC IP-cores reference clocks. Each sub-block is represented by a dedicated DT node, so they have different compatible strings to distinguish one from another. For some reason CCU provides the dividers of different types. Some dividers can be gateable some can't, some are fixed while the others are variable, some have special divider' limitations, some've got a non-standard register layout and so on. In order to cover all of these cases the hardware clocks driver is designed with an info-descriptor pattern. So there are special static descriptors declared for the dividers of each type with additional flags describing the block peculiarity. These descriptors are then used to create hardware clocks with proper operations. Some CCU dividers provide a way to reset a domain they generate a clock for. So the CCU AXI-bus and CCU system devices clock drivers also perform the reset controller registration. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Rob Herring <robh+dt@kernel.org> Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200526222056.18072-5-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Drop return from void function, silence sparse warnings about initializing structs with NULL vs. integer] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2020-05-26 22:20:56 +00:00
CCU_DIV_FIXED_INFO(CCU_SYS_XGMAC_PTP_CLK, "sys_xgmac_ptp_clk",
"sys_xgmac_clk", 8),
clk: Add Baikal-T1 CCU Dividers driver Nearly each Baikal-T1 IP-core is supposed to have a clock source of particular frequency. But since there are greater than five IP-blocks embedded into the SoC, the CCU PLLs can't fulfill all the needs. Baikal-T1 CCU provides a set of fixed and configurable clock dividers in order to generate a necessary signal for each chip sub-block. This driver creates the of-based hardware clocks for each divider available in Baikal-T1 CCU. The same way as for PLLs we split the functionality up into the clocks operations (gate, ungate, set rate, etc) and hardware clocks declaration/registration procedures. In accordance with the CCU documentation all its dividers are distributed into two CCU sub-blocks: AXI-bus and system devices reference clocks. The former sub-block is used to supply the clocks for AXI-bus interfaces (AXI clock domains) and the later one provides the SoC IP-cores reference clocks. Each sub-block is represented by a dedicated DT node, so they have different compatible strings to distinguish one from another. For some reason CCU provides the dividers of different types. Some dividers can be gateable some can't, some are fixed while the others are variable, some have special divider' limitations, some've got a non-standard register layout and so on. In order to cover all of these cases the hardware clocks driver is designed with an info-descriptor pattern. So there are special static descriptors declared for the dividers of each type with additional flags describing the block peculiarity. These descriptors are then used to create hardware clocks with proper operations. Some CCU dividers provide a way to reset a domain they generate a clock for. So the CCU AXI-bus and CCU system devices clock drivers also perform the reset controller registration. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Rob Herring <robh+dt@kernel.org> Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200526222056.18072-5-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Drop return from void function, silence sparse warnings about initializing structs with NULL vs. integer] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2020-05-26 22:20:56 +00:00
CCU_DIV_GATE_INFO(CCU_SYS_USB_CLK, "sys_usb_clk",
"eth_clk", CCU_SYS_USB_BASE, 10),
CCU_DIV_VAR_INFO(CCU_SYS_PVT_CLK, "sys_pvt_clk",
"ref_clk", CCU_SYS_PVT_BASE, 5,
CLK_SET_RATE_GATE, 0),
CCU_DIV_VAR_INFO(CCU_SYS_HWA_CLK, "sys_hwa_clk",
"sata_clk", CCU_SYS_HWA_BASE, 4,
CLK_SET_RATE_GATE, 0),
CCU_DIV_VAR_INFO(CCU_SYS_UART_CLK, "sys_uart_clk",
"eth_clk", CCU_SYS_UART_BASE, 17,
CLK_SET_RATE_GATE, 0),
CCU_DIV_FIXED_INFO(CCU_SYS_I2C1_CLK, "sys_i2c1_clk",
"eth_clk", 10),
CCU_DIV_FIXED_INFO(CCU_SYS_I2C2_CLK, "sys_i2c2_clk",
"eth_clk", 10),
CCU_DIV_FIXED_INFO(CCU_SYS_GPIO_CLK, "sys_gpio_clk",
"ref_clk", 25),
CCU_DIV_VAR_INFO(CCU_SYS_TIMER0_CLK, "sys_timer0_clk",
"ref_clk", CCU_SYS_TIMER0_BASE, 17,
clk: baikal-t1: Convert to platform device driver In accordance with the way the MIPS platform is normally design there are only six clock sources which need to be available on the kernel start in order to one end up booting correctly: + CPU PLL: needed by the r4k and MIPS GIC timer drivers. The former one is initialized by the arch code, while the later one is implemented in the mips-gic-timer.c driver as the OF-declared timer. + PCIe PLL: required as a parental clock source for the APB/timer domains. + APB clock: needed in order to access all the SoC CSRs at least for the timer OF-declared drivers. + APB Timer{0-2} clocks: these are the DW APB timers which drivers dw_apb_timer_of.c are implemented as the OF-declared timers. So as long as the clocks above are available early the kernel will normally work. Let's convert the Baikal-T1 CCU drivers to the platform device drivers keeping that in mind. Generally speaking the conversion isn't that complicated since the driver infrastructure has been designed as flexible enough for that. First we need to add a new PLL/Divider clock features flag which indicates the corresponding clock source as a basic one and that clock sources will be available on the kernel early boot stages. Second the internal PLL/Divider descriptors need to be initialized with -EPROBE_DEFER value as the corresponding clock source is unavailable at the early stages. They will be allocated and initialized on the Baikal-T1 clock platform driver probe procedure. Finally the already available PLL/Divider init functions need to be split up into two ones: init procedure performed in the framework of the OF-declared clock initialization (of_clk_init()), and the probe procedure called by the platform devices bus driver. Note the later method will just continue the system clocks initialization started in the former one. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20220929225402.9696-9-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Remove module things because the Kconfig is still bool] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-09-29 22:54:02 +00:00
CLK_SET_RATE_GATE, CCU_DIV_BASIC),
clk: Add Baikal-T1 CCU Dividers driver Nearly each Baikal-T1 IP-core is supposed to have a clock source of particular frequency. But since there are greater than five IP-blocks embedded into the SoC, the CCU PLLs can't fulfill all the needs. Baikal-T1 CCU provides a set of fixed and configurable clock dividers in order to generate a necessary signal for each chip sub-block. This driver creates the of-based hardware clocks for each divider available in Baikal-T1 CCU. The same way as for PLLs we split the functionality up into the clocks operations (gate, ungate, set rate, etc) and hardware clocks declaration/registration procedures. In accordance with the CCU documentation all its dividers are distributed into two CCU sub-blocks: AXI-bus and system devices reference clocks. The former sub-block is used to supply the clocks for AXI-bus interfaces (AXI clock domains) and the later one provides the SoC IP-cores reference clocks. Each sub-block is represented by a dedicated DT node, so they have different compatible strings to distinguish one from another. For some reason CCU provides the dividers of different types. Some dividers can be gateable some can't, some are fixed while the others are variable, some have special divider' limitations, some've got a non-standard register layout and so on. In order to cover all of these cases the hardware clocks driver is designed with an info-descriptor pattern. So there are special static descriptors declared for the dividers of each type with additional flags describing the block peculiarity. These descriptors are then used to create hardware clocks with proper operations. Some CCU dividers provide a way to reset a domain they generate a clock for. So the CCU AXI-bus and CCU system devices clock drivers also perform the reset controller registration. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Rob Herring <robh+dt@kernel.org> Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200526222056.18072-5-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Drop return from void function, silence sparse warnings about initializing structs with NULL vs. integer] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2020-05-26 22:20:56 +00:00
CCU_DIV_VAR_INFO(CCU_SYS_TIMER1_CLK, "sys_timer1_clk",
"ref_clk", CCU_SYS_TIMER1_BASE, 17,
clk: baikal-t1: Convert to platform device driver In accordance with the way the MIPS platform is normally design there are only six clock sources which need to be available on the kernel start in order to one end up booting correctly: + CPU PLL: needed by the r4k and MIPS GIC timer drivers. The former one is initialized by the arch code, while the later one is implemented in the mips-gic-timer.c driver as the OF-declared timer. + PCIe PLL: required as a parental clock source for the APB/timer domains. + APB clock: needed in order to access all the SoC CSRs at least for the timer OF-declared drivers. + APB Timer{0-2} clocks: these are the DW APB timers which drivers dw_apb_timer_of.c are implemented as the OF-declared timers. So as long as the clocks above are available early the kernel will normally work. Let's convert the Baikal-T1 CCU drivers to the platform device drivers keeping that in mind. Generally speaking the conversion isn't that complicated since the driver infrastructure has been designed as flexible enough for that. First we need to add a new PLL/Divider clock features flag which indicates the corresponding clock source as a basic one and that clock sources will be available on the kernel early boot stages. Second the internal PLL/Divider descriptors need to be initialized with -EPROBE_DEFER value as the corresponding clock source is unavailable at the early stages. They will be allocated and initialized on the Baikal-T1 clock platform driver probe procedure. Finally the already available PLL/Divider init functions need to be split up into two ones: init procedure performed in the framework of the OF-declared clock initialization (of_clk_init()), and the probe procedure called by the platform devices bus driver. Note the later method will just continue the system clocks initialization started in the former one. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20220929225402.9696-9-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Remove module things because the Kconfig is still bool] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-09-29 22:54:02 +00:00
CLK_SET_RATE_GATE, CCU_DIV_BASIC),
clk: Add Baikal-T1 CCU Dividers driver Nearly each Baikal-T1 IP-core is supposed to have a clock source of particular frequency. But since there are greater than five IP-blocks embedded into the SoC, the CCU PLLs can't fulfill all the needs. Baikal-T1 CCU provides a set of fixed and configurable clock dividers in order to generate a necessary signal for each chip sub-block. This driver creates the of-based hardware clocks for each divider available in Baikal-T1 CCU. The same way as for PLLs we split the functionality up into the clocks operations (gate, ungate, set rate, etc) and hardware clocks declaration/registration procedures. In accordance with the CCU documentation all its dividers are distributed into two CCU sub-blocks: AXI-bus and system devices reference clocks. The former sub-block is used to supply the clocks for AXI-bus interfaces (AXI clock domains) and the later one provides the SoC IP-cores reference clocks. Each sub-block is represented by a dedicated DT node, so they have different compatible strings to distinguish one from another. For some reason CCU provides the dividers of different types. Some dividers can be gateable some can't, some are fixed while the others are variable, some have special divider' limitations, some've got a non-standard register layout and so on. In order to cover all of these cases the hardware clocks driver is designed with an info-descriptor pattern. So there are special static descriptors declared for the dividers of each type with additional flags describing the block peculiarity. These descriptors are then used to create hardware clocks with proper operations. Some CCU dividers provide a way to reset a domain they generate a clock for. So the CCU AXI-bus and CCU system devices clock drivers also perform the reset controller registration. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Rob Herring <robh+dt@kernel.org> Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200526222056.18072-5-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Drop return from void function, silence sparse warnings about initializing structs with NULL vs. integer] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2020-05-26 22:20:56 +00:00
CCU_DIV_VAR_INFO(CCU_SYS_TIMER2_CLK, "sys_timer2_clk",
"ref_clk", CCU_SYS_TIMER2_BASE, 17,
clk: baikal-t1: Convert to platform device driver In accordance with the way the MIPS platform is normally design there are only six clock sources which need to be available on the kernel start in order to one end up booting correctly: + CPU PLL: needed by the r4k and MIPS GIC timer drivers. The former one is initialized by the arch code, while the later one is implemented in the mips-gic-timer.c driver as the OF-declared timer. + PCIe PLL: required as a parental clock source for the APB/timer domains. + APB clock: needed in order to access all the SoC CSRs at least for the timer OF-declared drivers. + APB Timer{0-2} clocks: these are the DW APB timers which drivers dw_apb_timer_of.c are implemented as the OF-declared timers. So as long as the clocks above are available early the kernel will normally work. Let's convert the Baikal-T1 CCU drivers to the platform device drivers keeping that in mind. Generally speaking the conversion isn't that complicated since the driver infrastructure has been designed as flexible enough for that. First we need to add a new PLL/Divider clock features flag which indicates the corresponding clock source as a basic one and that clock sources will be available on the kernel early boot stages. Second the internal PLL/Divider descriptors need to be initialized with -EPROBE_DEFER value as the corresponding clock source is unavailable at the early stages. They will be allocated and initialized on the Baikal-T1 clock platform driver probe procedure. Finally the already available PLL/Divider init functions need to be split up into two ones: init procedure performed in the framework of the OF-declared clock initialization (of_clk_init()), and the probe procedure called by the platform devices bus driver. Note the later method will just continue the system clocks initialization started in the former one. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20220929225402.9696-9-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Remove module things because the Kconfig is still bool] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-09-29 22:54:02 +00:00
CLK_SET_RATE_GATE, CCU_DIV_BASIC),
clk: Add Baikal-T1 CCU Dividers driver Nearly each Baikal-T1 IP-core is supposed to have a clock source of particular frequency. But since there are greater than five IP-blocks embedded into the SoC, the CCU PLLs can't fulfill all the needs. Baikal-T1 CCU provides a set of fixed and configurable clock dividers in order to generate a necessary signal for each chip sub-block. This driver creates the of-based hardware clocks for each divider available in Baikal-T1 CCU. The same way as for PLLs we split the functionality up into the clocks operations (gate, ungate, set rate, etc) and hardware clocks declaration/registration procedures. In accordance with the CCU documentation all its dividers are distributed into two CCU sub-blocks: AXI-bus and system devices reference clocks. The former sub-block is used to supply the clocks for AXI-bus interfaces (AXI clock domains) and the later one provides the SoC IP-cores reference clocks. Each sub-block is represented by a dedicated DT node, so they have different compatible strings to distinguish one from another. For some reason CCU provides the dividers of different types. Some dividers can be gateable some can't, some are fixed while the others are variable, some have special divider' limitations, some've got a non-standard register layout and so on. In order to cover all of these cases the hardware clocks driver is designed with an info-descriptor pattern. So there are special static descriptors declared for the dividers of each type with additional flags describing the block peculiarity. These descriptors are then used to create hardware clocks with proper operations. Some CCU dividers provide a way to reset a domain they generate a clock for. So the CCU AXI-bus and CCU system devices clock drivers also perform the reset controller registration. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Rob Herring <robh+dt@kernel.org> Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200526222056.18072-5-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Drop return from void function, silence sparse warnings about initializing structs with NULL vs. integer] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2020-05-26 22:20:56 +00:00
CCU_DIV_VAR_INFO(CCU_SYS_WDT_CLK, "sys_wdt_clk",
"eth_clk", CCU_SYS_WDT_BASE, 17,
CLK_SET_RATE_GATE, CCU_DIV_SKIP_ONE_TO_THREE)
};
clk: baikal-t1: Convert to platform device driver In accordance with the way the MIPS platform is normally design there are only six clock sources which need to be available on the kernel start in order to one end up booting correctly: + CPU PLL: needed by the r4k and MIPS GIC timer drivers. The former one is initialized by the arch code, while the later one is implemented in the mips-gic-timer.c driver as the OF-declared timer. + PCIe PLL: required as a parental clock source for the APB/timer domains. + APB clock: needed in order to access all the SoC CSRs at least for the timer OF-declared drivers. + APB Timer{0-2} clocks: these are the DW APB timers which drivers dw_apb_timer_of.c are implemented as the OF-declared timers. So as long as the clocks above are available early the kernel will normally work. Let's convert the Baikal-T1 CCU drivers to the platform device drivers keeping that in mind. Generally speaking the conversion isn't that complicated since the driver infrastructure has been designed as flexible enough for that. First we need to add a new PLL/Divider clock features flag which indicates the corresponding clock source as a basic one and that clock sources will be available on the kernel early boot stages. Second the internal PLL/Divider descriptors need to be initialized with -EPROBE_DEFER value as the corresponding clock source is unavailable at the early stages. They will be allocated and initialized on the Baikal-T1 clock platform driver probe procedure. Finally the already available PLL/Divider init functions need to be split up into two ones: init procedure performed in the framework of the OF-declared clock initialization (of_clk_init()), and the probe procedure called by the platform devices bus driver. Note the later method will just continue the system clocks initialization started in the former one. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20220929225402.9696-9-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Remove module things because the Kconfig is still bool] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-09-29 22:54:02 +00:00
static struct ccu_div_data *axi_data;
static struct ccu_div_data *sys_data;
static void ccu_div_set_data(struct ccu_div_data *data)
{
struct device_node *np = data->np;
if (of_device_is_compatible(np, "baikal,bt1-ccu-axi"))
axi_data = data;
else if (of_device_is_compatible(np, "baikal,bt1-ccu-sys"))
sys_data = data;
else
pr_err("Invalid DT node '%s' specified\n", of_node_full_name(np));
}
static struct ccu_div_data *ccu_div_get_data(struct device_node *np)
{
if (of_device_is_compatible(np, "baikal,bt1-ccu-axi"))
return axi_data;
else if (of_device_is_compatible(np, "baikal,bt1-ccu-sys"))
return sys_data;
pr_err("Invalid DT node '%s' specified\n", of_node_full_name(np));
return NULL;
}
clk: Add Baikal-T1 CCU Dividers driver Nearly each Baikal-T1 IP-core is supposed to have a clock source of particular frequency. But since there are greater than five IP-blocks embedded into the SoC, the CCU PLLs can't fulfill all the needs. Baikal-T1 CCU provides a set of fixed and configurable clock dividers in order to generate a necessary signal for each chip sub-block. This driver creates the of-based hardware clocks for each divider available in Baikal-T1 CCU. The same way as for PLLs we split the functionality up into the clocks operations (gate, ungate, set rate, etc) and hardware clocks declaration/registration procedures. In accordance with the CCU documentation all its dividers are distributed into two CCU sub-blocks: AXI-bus and system devices reference clocks. The former sub-block is used to supply the clocks for AXI-bus interfaces (AXI clock domains) and the later one provides the SoC IP-cores reference clocks. Each sub-block is represented by a dedicated DT node, so they have different compatible strings to distinguish one from another. For some reason CCU provides the dividers of different types. Some dividers can be gateable some can't, some are fixed while the others are variable, some have special divider' limitations, some've got a non-standard register layout and so on. In order to cover all of these cases the hardware clocks driver is designed with an info-descriptor pattern. So there are special static descriptors declared for the dividers of each type with additional flags describing the block peculiarity. These descriptors are then used to create hardware clocks with proper operations. Some CCU dividers provide a way to reset a domain they generate a clock for. So the CCU AXI-bus and CCU system devices clock drivers also perform the reset controller registration. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Rob Herring <robh+dt@kernel.org> Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200526222056.18072-5-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Drop return from void function, silence sparse warnings about initializing structs with NULL vs. integer] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2020-05-26 22:20:56 +00:00
static struct ccu_div *ccu_div_find_desc(struct ccu_div_data *data,
unsigned int clk_id)
{
int idx;
for (idx = 0; idx < data->divs_num; ++idx) {
clk: baikal-t1: Convert to platform device driver In accordance with the way the MIPS platform is normally design there are only six clock sources which need to be available on the kernel start in order to one end up booting correctly: + CPU PLL: needed by the r4k and MIPS GIC timer drivers. The former one is initialized by the arch code, while the later one is implemented in the mips-gic-timer.c driver as the OF-declared timer. + PCIe PLL: required as a parental clock source for the APB/timer domains. + APB clock: needed in order to access all the SoC CSRs at least for the timer OF-declared drivers. + APB Timer{0-2} clocks: these are the DW APB timers which drivers dw_apb_timer_of.c are implemented as the OF-declared timers. So as long as the clocks above are available early the kernel will normally work. Let's convert the Baikal-T1 CCU drivers to the platform device drivers keeping that in mind. Generally speaking the conversion isn't that complicated since the driver infrastructure has been designed as flexible enough for that. First we need to add a new PLL/Divider clock features flag which indicates the corresponding clock source as a basic one and that clock sources will be available on the kernel early boot stages. Second the internal PLL/Divider descriptors need to be initialized with -EPROBE_DEFER value as the corresponding clock source is unavailable at the early stages. They will be allocated and initialized on the Baikal-T1 clock platform driver probe procedure. Finally the already available PLL/Divider init functions need to be split up into two ones: init procedure performed in the framework of the OF-declared clock initialization (of_clk_init()), and the probe procedure called by the platform devices bus driver. Note the later method will just continue the system clocks initialization started in the former one. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20220929225402.9696-9-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Remove module things because the Kconfig is still bool] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-09-29 22:54:02 +00:00
if (data->divs_info[idx].id == clk_id)
return data->divs[idx];
clk: Add Baikal-T1 CCU Dividers driver Nearly each Baikal-T1 IP-core is supposed to have a clock source of particular frequency. But since there are greater than five IP-blocks embedded into the SoC, the CCU PLLs can't fulfill all the needs. Baikal-T1 CCU provides a set of fixed and configurable clock dividers in order to generate a necessary signal for each chip sub-block. This driver creates the of-based hardware clocks for each divider available in Baikal-T1 CCU. The same way as for PLLs we split the functionality up into the clocks operations (gate, ungate, set rate, etc) and hardware clocks declaration/registration procedures. In accordance with the CCU documentation all its dividers are distributed into two CCU sub-blocks: AXI-bus and system devices reference clocks. The former sub-block is used to supply the clocks for AXI-bus interfaces (AXI clock domains) and the later one provides the SoC IP-cores reference clocks. Each sub-block is represented by a dedicated DT node, so they have different compatible strings to distinguish one from another. For some reason CCU provides the dividers of different types. Some dividers can be gateable some can't, some are fixed while the others are variable, some have special divider' limitations, some've got a non-standard register layout and so on. In order to cover all of these cases the hardware clocks driver is designed with an info-descriptor pattern. So there are special static descriptors declared for the dividers of each type with additional flags describing the block peculiarity. These descriptors are then used to create hardware clocks with proper operations. Some CCU dividers provide a way to reset a domain they generate a clock for. So the CCU AXI-bus and CCU system devices clock drivers also perform the reset controller registration. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Rob Herring <robh+dt@kernel.org> Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200526222056.18072-5-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Drop return from void function, silence sparse warnings about initializing structs with NULL vs. integer] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2020-05-26 22:20:56 +00:00
}
return ERR_PTR(-EINVAL);
}
static struct ccu_div_data *ccu_div_create_data(struct device_node *np)
{
struct ccu_div_data *data;
int ret;
data = kzalloc(sizeof(*data), GFP_KERNEL);
if (!data)
return ERR_PTR(-ENOMEM);
data->np = np;
if (of_device_is_compatible(np, "baikal,bt1-ccu-axi")) {
data->divs_num = ARRAY_SIZE(axi_info);
data->divs_info = axi_info;
} else if (of_device_is_compatible(np, "baikal,bt1-ccu-sys")) {
data->divs_num = ARRAY_SIZE(sys_info);
data->divs_info = sys_info;
} else {
pr_err("Incompatible DT node '%s' specified\n",
clk: Add Baikal-T1 CCU Dividers driver Nearly each Baikal-T1 IP-core is supposed to have a clock source of particular frequency. But since there are greater than five IP-blocks embedded into the SoC, the CCU PLLs can't fulfill all the needs. Baikal-T1 CCU provides a set of fixed and configurable clock dividers in order to generate a necessary signal for each chip sub-block. This driver creates the of-based hardware clocks for each divider available in Baikal-T1 CCU. The same way as for PLLs we split the functionality up into the clocks operations (gate, ungate, set rate, etc) and hardware clocks declaration/registration procedures. In accordance with the CCU documentation all its dividers are distributed into two CCU sub-blocks: AXI-bus and system devices reference clocks. The former sub-block is used to supply the clocks for AXI-bus interfaces (AXI clock domains) and the later one provides the SoC IP-cores reference clocks. Each sub-block is represented by a dedicated DT node, so they have different compatible strings to distinguish one from another. For some reason CCU provides the dividers of different types. Some dividers can be gateable some can't, some are fixed while the others are variable, some have special divider' limitations, some've got a non-standard register layout and so on. In order to cover all of these cases the hardware clocks driver is designed with an info-descriptor pattern. So there are special static descriptors declared for the dividers of each type with additional flags describing the block peculiarity. These descriptors are then used to create hardware clocks with proper operations. Some CCU dividers provide a way to reset a domain they generate a clock for. So the CCU AXI-bus and CCU system devices clock drivers also perform the reset controller registration. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Rob Herring <robh+dt@kernel.org> Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200526222056.18072-5-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Drop return from void function, silence sparse warnings about initializing structs with NULL vs. integer] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2020-05-26 22:20:56 +00:00
of_node_full_name(np));
ret = -EINVAL;
goto err_kfree_data;
}
data->divs = kcalloc(data->divs_num, sizeof(*data->divs), GFP_KERNEL);
if (!data->divs) {
ret = -ENOMEM;
goto err_kfree_data;
}
return data;
err_kfree_data:
kfree(data);
return ERR_PTR(ret);
}
static void ccu_div_free_data(struct ccu_div_data *data)
{
kfree(data->divs);
kfree(data);
}
static int ccu_div_find_sys_regs(struct ccu_div_data *data)
{
data->sys_regs = syscon_node_to_regmap(data->np->parent);
if (IS_ERR(data->sys_regs)) {
pr_err("Failed to find syscon regs for '%s'\n",
of_node_full_name(data->np));
return PTR_ERR(data->sys_regs);
}
return 0;
}
static struct clk_hw *ccu_div_of_clk_hw_get(struct of_phandle_args *clkspec,
void *priv)
{
struct ccu_div_data *data = priv;
struct ccu_div *div;
unsigned int clk_id;
clk_id = clkspec->args[0];
div = ccu_div_find_desc(data, clk_id);
if (IS_ERR(div)) {
clk: baikal-t1: Convert to platform device driver In accordance with the way the MIPS platform is normally design there are only six clock sources which need to be available on the kernel start in order to one end up booting correctly: + CPU PLL: needed by the r4k and MIPS GIC timer drivers. The former one is initialized by the arch code, while the later one is implemented in the mips-gic-timer.c driver as the OF-declared timer. + PCIe PLL: required as a parental clock source for the APB/timer domains. + APB clock: needed in order to access all the SoC CSRs at least for the timer OF-declared drivers. + APB Timer{0-2} clocks: these are the DW APB timers which drivers dw_apb_timer_of.c are implemented as the OF-declared timers. So as long as the clocks above are available early the kernel will normally work. Let's convert the Baikal-T1 CCU drivers to the platform device drivers keeping that in mind. Generally speaking the conversion isn't that complicated since the driver infrastructure has been designed as flexible enough for that. First we need to add a new PLL/Divider clock features flag which indicates the corresponding clock source as a basic one and that clock sources will be available on the kernel early boot stages. Second the internal PLL/Divider descriptors need to be initialized with -EPROBE_DEFER value as the corresponding clock source is unavailable at the early stages. They will be allocated and initialized on the Baikal-T1 clock platform driver probe procedure. Finally the already available PLL/Divider init functions need to be split up into two ones: init procedure performed in the framework of the OF-declared clock initialization (of_clk_init()), and the probe procedure called by the platform devices bus driver. Note the later method will just continue the system clocks initialization started in the former one. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20220929225402.9696-9-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Remove module things because the Kconfig is still bool] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-09-29 22:54:02 +00:00
if (div != ERR_PTR(-EPROBE_DEFER))
pr_info("Invalid clock ID %d specified\n", clk_id);
clk: Add Baikal-T1 CCU Dividers driver Nearly each Baikal-T1 IP-core is supposed to have a clock source of particular frequency. But since there are greater than five IP-blocks embedded into the SoC, the CCU PLLs can't fulfill all the needs. Baikal-T1 CCU provides a set of fixed and configurable clock dividers in order to generate a necessary signal for each chip sub-block. This driver creates the of-based hardware clocks for each divider available in Baikal-T1 CCU. The same way as for PLLs we split the functionality up into the clocks operations (gate, ungate, set rate, etc) and hardware clocks declaration/registration procedures. In accordance with the CCU documentation all its dividers are distributed into two CCU sub-blocks: AXI-bus and system devices reference clocks. The former sub-block is used to supply the clocks for AXI-bus interfaces (AXI clock domains) and the later one provides the SoC IP-cores reference clocks. Each sub-block is represented by a dedicated DT node, so they have different compatible strings to distinguish one from another. For some reason CCU provides the dividers of different types. Some dividers can be gateable some can't, some are fixed while the others are variable, some have special divider' limitations, some've got a non-standard register layout and so on. In order to cover all of these cases the hardware clocks driver is designed with an info-descriptor pattern. So there are special static descriptors declared for the dividers of each type with additional flags describing the block peculiarity. These descriptors are then used to create hardware clocks with proper operations. Some CCU dividers provide a way to reset a domain they generate a clock for. So the CCU AXI-bus and CCU system devices clock drivers also perform the reset controller registration. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Rob Herring <robh+dt@kernel.org> Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200526222056.18072-5-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Drop return from void function, silence sparse warnings about initializing structs with NULL vs. integer] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2020-05-26 22:20:56 +00:00
return ERR_CAST(div);
}
return ccu_div_get_clk_hw(div);
}
clk: baikal-t1: Convert to platform device driver In accordance with the way the MIPS platform is normally design there are only six clock sources which need to be available on the kernel start in order to one end up booting correctly: + CPU PLL: needed by the r4k and MIPS GIC timer drivers. The former one is initialized by the arch code, while the later one is implemented in the mips-gic-timer.c driver as the OF-declared timer. + PCIe PLL: required as a parental clock source for the APB/timer domains. + APB clock: needed in order to access all the SoC CSRs at least for the timer OF-declared drivers. + APB Timer{0-2} clocks: these are the DW APB timers which drivers dw_apb_timer_of.c are implemented as the OF-declared timers. So as long as the clocks above are available early the kernel will normally work. Let's convert the Baikal-T1 CCU drivers to the platform device drivers keeping that in mind. Generally speaking the conversion isn't that complicated since the driver infrastructure has been designed as flexible enough for that. First we need to add a new PLL/Divider clock features flag which indicates the corresponding clock source as a basic one and that clock sources will be available on the kernel early boot stages. Second the internal PLL/Divider descriptors need to be initialized with -EPROBE_DEFER value as the corresponding clock source is unavailable at the early stages. They will be allocated and initialized on the Baikal-T1 clock platform driver probe procedure. Finally the already available PLL/Divider init functions need to be split up into two ones: init procedure performed in the framework of the OF-declared clock initialization (of_clk_init()), and the probe procedure called by the platform devices bus driver. Note the later method will just continue the system clocks initialization started in the former one. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20220929225402.9696-9-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Remove module things because the Kconfig is still bool] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-09-29 22:54:02 +00:00
static int ccu_div_clk_register(struct ccu_div_data *data, bool defer)
clk: Add Baikal-T1 CCU Dividers driver Nearly each Baikal-T1 IP-core is supposed to have a clock source of particular frequency. But since there are greater than five IP-blocks embedded into the SoC, the CCU PLLs can't fulfill all the needs. Baikal-T1 CCU provides a set of fixed and configurable clock dividers in order to generate a necessary signal for each chip sub-block. This driver creates the of-based hardware clocks for each divider available in Baikal-T1 CCU. The same way as for PLLs we split the functionality up into the clocks operations (gate, ungate, set rate, etc) and hardware clocks declaration/registration procedures. In accordance with the CCU documentation all its dividers are distributed into two CCU sub-blocks: AXI-bus and system devices reference clocks. The former sub-block is used to supply the clocks for AXI-bus interfaces (AXI clock domains) and the later one provides the SoC IP-cores reference clocks. Each sub-block is represented by a dedicated DT node, so they have different compatible strings to distinguish one from another. For some reason CCU provides the dividers of different types. Some dividers can be gateable some can't, some are fixed while the others are variable, some have special divider' limitations, some've got a non-standard register layout and so on. In order to cover all of these cases the hardware clocks driver is designed with an info-descriptor pattern. So there are special static descriptors declared for the dividers of each type with additional flags describing the block peculiarity. These descriptors are then used to create hardware clocks with proper operations. Some CCU dividers provide a way to reset a domain they generate a clock for. So the CCU AXI-bus and CCU system devices clock drivers also perform the reset controller registration. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Rob Herring <robh+dt@kernel.org> Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200526222056.18072-5-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Drop return from void function, silence sparse warnings about initializing structs with NULL vs. integer] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2020-05-26 22:20:56 +00:00
{
int idx, ret;
for (idx = 0; idx < data->divs_num; ++idx) {
const struct ccu_div_info *info = &data->divs_info[idx];
struct ccu_div_init_data init = {0};
clk: baikal-t1: Convert to platform device driver In accordance with the way the MIPS platform is normally design there are only six clock sources which need to be available on the kernel start in order to one end up booting correctly: + CPU PLL: needed by the r4k and MIPS GIC timer drivers. The former one is initialized by the arch code, while the later one is implemented in the mips-gic-timer.c driver as the OF-declared timer. + PCIe PLL: required as a parental clock source for the APB/timer domains. + APB clock: needed in order to access all the SoC CSRs at least for the timer OF-declared drivers. + APB Timer{0-2} clocks: these are the DW APB timers which drivers dw_apb_timer_of.c are implemented as the OF-declared timers. So as long as the clocks above are available early the kernel will normally work. Let's convert the Baikal-T1 CCU drivers to the platform device drivers keeping that in mind. Generally speaking the conversion isn't that complicated since the driver infrastructure has been designed as flexible enough for that. First we need to add a new PLL/Divider clock features flag which indicates the corresponding clock source as a basic one and that clock sources will be available on the kernel early boot stages. Second the internal PLL/Divider descriptors need to be initialized with -EPROBE_DEFER value as the corresponding clock source is unavailable at the early stages. They will be allocated and initialized on the Baikal-T1 clock platform driver probe procedure. Finally the already available PLL/Divider init functions need to be split up into two ones: init procedure performed in the framework of the OF-declared clock initialization (of_clk_init()), and the probe procedure called by the platform devices bus driver. Note the later method will just continue the system clocks initialization started in the former one. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20220929225402.9696-9-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Remove module things because the Kconfig is still bool] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-09-29 22:54:02 +00:00
if (!!(info->features & CCU_DIV_BASIC) ^ defer) {
if (!data->divs[idx])
data->divs[idx] = ERR_PTR(-EPROBE_DEFER);
continue;
}
clk: Add Baikal-T1 CCU Dividers driver Nearly each Baikal-T1 IP-core is supposed to have a clock source of particular frequency. But since there are greater than five IP-blocks embedded into the SoC, the CCU PLLs can't fulfill all the needs. Baikal-T1 CCU provides a set of fixed and configurable clock dividers in order to generate a necessary signal for each chip sub-block. This driver creates the of-based hardware clocks for each divider available in Baikal-T1 CCU. The same way as for PLLs we split the functionality up into the clocks operations (gate, ungate, set rate, etc) and hardware clocks declaration/registration procedures. In accordance with the CCU documentation all its dividers are distributed into two CCU sub-blocks: AXI-bus and system devices reference clocks. The former sub-block is used to supply the clocks for AXI-bus interfaces (AXI clock domains) and the later one provides the SoC IP-cores reference clocks. Each sub-block is represented by a dedicated DT node, so they have different compatible strings to distinguish one from another. For some reason CCU provides the dividers of different types. Some dividers can be gateable some can't, some are fixed while the others are variable, some have special divider' limitations, some've got a non-standard register layout and so on. In order to cover all of these cases the hardware clocks driver is designed with an info-descriptor pattern. So there are special static descriptors declared for the dividers of each type with additional flags describing the block peculiarity. These descriptors are then used to create hardware clocks with proper operations. Some CCU dividers provide a way to reset a domain they generate a clock for. So the CCU AXI-bus and CCU system devices clock drivers also perform the reset controller registration. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Rob Herring <robh+dt@kernel.org> Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200526222056.18072-5-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Drop return from void function, silence sparse warnings about initializing structs with NULL vs. integer] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2020-05-26 22:20:56 +00:00
init.id = info->id;
init.name = info->name;
init.parent_name = info->parent_name;
init.np = data->np;
init.type = info->type;
init.flags = info->flags;
init.features = info->features;
if (init.type == CCU_DIV_VAR) {
init.base = info->base;
init.sys_regs = data->sys_regs;
init.width = info->width;
} else if (init.type == CCU_DIV_GATE) {
init.base = info->base;
init.sys_regs = data->sys_regs;
init.divider = info->divider;
} else if (init.type == CCU_DIV_BUF) {
init.base = info->base;
init.sys_regs = data->sys_regs;
clk: Add Baikal-T1 CCU Dividers driver Nearly each Baikal-T1 IP-core is supposed to have a clock source of particular frequency. But since there are greater than five IP-blocks embedded into the SoC, the CCU PLLs can't fulfill all the needs. Baikal-T1 CCU provides a set of fixed and configurable clock dividers in order to generate a necessary signal for each chip sub-block. This driver creates the of-based hardware clocks for each divider available in Baikal-T1 CCU. The same way as for PLLs we split the functionality up into the clocks operations (gate, ungate, set rate, etc) and hardware clocks declaration/registration procedures. In accordance with the CCU documentation all its dividers are distributed into two CCU sub-blocks: AXI-bus and system devices reference clocks. The former sub-block is used to supply the clocks for AXI-bus interfaces (AXI clock domains) and the later one provides the SoC IP-cores reference clocks. Each sub-block is represented by a dedicated DT node, so they have different compatible strings to distinguish one from another. For some reason CCU provides the dividers of different types. Some dividers can be gateable some can't, some are fixed while the others are variable, some have special divider' limitations, some've got a non-standard register layout and so on. In order to cover all of these cases the hardware clocks driver is designed with an info-descriptor pattern. So there are special static descriptors declared for the dividers of each type with additional flags describing the block peculiarity. These descriptors are then used to create hardware clocks with proper operations. Some CCU dividers provide a way to reset a domain they generate a clock for. So the CCU AXI-bus and CCU system devices clock drivers also perform the reset controller registration. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Rob Herring <robh+dt@kernel.org> Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200526222056.18072-5-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Drop return from void function, silence sparse warnings about initializing structs with NULL vs. integer] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2020-05-26 22:20:56 +00:00
} else {
init.divider = info->divider;
}
data->divs[idx] = ccu_div_hw_register(&init);
if (IS_ERR(data->divs[idx])) {
ret = PTR_ERR(data->divs[idx]);
pr_err("Couldn't register divider '%s' hw\n",
init.name);
goto err_hw_unregister;
}
}
return 0;
err_hw_unregister:
clk: baikal-t1: Convert to platform device driver In accordance with the way the MIPS platform is normally design there are only six clock sources which need to be available on the kernel start in order to one end up booting correctly: + CPU PLL: needed by the r4k and MIPS GIC timer drivers. The former one is initialized by the arch code, while the later one is implemented in the mips-gic-timer.c driver as the OF-declared timer. + PCIe PLL: required as a parental clock source for the APB/timer domains. + APB clock: needed in order to access all the SoC CSRs at least for the timer OF-declared drivers. + APB Timer{0-2} clocks: these are the DW APB timers which drivers dw_apb_timer_of.c are implemented as the OF-declared timers. So as long as the clocks above are available early the kernel will normally work. Let's convert the Baikal-T1 CCU drivers to the platform device drivers keeping that in mind. Generally speaking the conversion isn't that complicated since the driver infrastructure has been designed as flexible enough for that. First we need to add a new PLL/Divider clock features flag which indicates the corresponding clock source as a basic one and that clock sources will be available on the kernel early boot stages. Second the internal PLL/Divider descriptors need to be initialized with -EPROBE_DEFER value as the corresponding clock source is unavailable at the early stages. They will be allocated and initialized on the Baikal-T1 clock platform driver probe procedure. Finally the already available PLL/Divider init functions need to be split up into two ones: init procedure performed in the framework of the OF-declared clock initialization (of_clk_init()), and the probe procedure called by the platform devices bus driver. Note the later method will just continue the system clocks initialization started in the former one. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20220929225402.9696-9-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Remove module things because the Kconfig is still bool] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-09-29 22:54:02 +00:00
for (--idx; idx >= 0; --idx) {
if (!!(data->divs_info[idx].features & CCU_DIV_BASIC) ^ defer)
continue;
clk: Add Baikal-T1 CCU Dividers driver Nearly each Baikal-T1 IP-core is supposed to have a clock source of particular frequency. But since there are greater than five IP-blocks embedded into the SoC, the CCU PLLs can't fulfill all the needs. Baikal-T1 CCU provides a set of fixed and configurable clock dividers in order to generate a necessary signal for each chip sub-block. This driver creates the of-based hardware clocks for each divider available in Baikal-T1 CCU. The same way as for PLLs we split the functionality up into the clocks operations (gate, ungate, set rate, etc) and hardware clocks declaration/registration procedures. In accordance with the CCU documentation all its dividers are distributed into two CCU sub-blocks: AXI-bus and system devices reference clocks. The former sub-block is used to supply the clocks for AXI-bus interfaces (AXI clock domains) and the later one provides the SoC IP-cores reference clocks. Each sub-block is represented by a dedicated DT node, so they have different compatible strings to distinguish one from another. For some reason CCU provides the dividers of different types. Some dividers can be gateable some can't, some are fixed while the others are variable, some have special divider' limitations, some've got a non-standard register layout and so on. In order to cover all of these cases the hardware clocks driver is designed with an info-descriptor pattern. So there are special static descriptors declared for the dividers of each type with additional flags describing the block peculiarity. These descriptors are then used to create hardware clocks with proper operations. Some CCU dividers provide a way to reset a domain they generate a clock for. So the CCU AXI-bus and CCU system devices clock drivers also perform the reset controller registration. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Rob Herring <robh+dt@kernel.org> Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200526222056.18072-5-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Drop return from void function, silence sparse warnings about initializing structs with NULL vs. integer] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2020-05-26 22:20:56 +00:00
ccu_div_hw_unregister(data->divs[idx]);
clk: baikal-t1: Convert to platform device driver In accordance with the way the MIPS platform is normally design there are only six clock sources which need to be available on the kernel start in order to one end up booting correctly: + CPU PLL: needed by the r4k and MIPS GIC timer drivers. The former one is initialized by the arch code, while the later one is implemented in the mips-gic-timer.c driver as the OF-declared timer. + PCIe PLL: required as a parental clock source for the APB/timer domains. + APB clock: needed in order to access all the SoC CSRs at least for the timer OF-declared drivers. + APB Timer{0-2} clocks: these are the DW APB timers which drivers dw_apb_timer_of.c are implemented as the OF-declared timers. So as long as the clocks above are available early the kernel will normally work. Let's convert the Baikal-T1 CCU drivers to the platform device drivers keeping that in mind. Generally speaking the conversion isn't that complicated since the driver infrastructure has been designed as flexible enough for that. First we need to add a new PLL/Divider clock features flag which indicates the corresponding clock source as a basic one and that clock sources will be available on the kernel early boot stages. Second the internal PLL/Divider descriptors need to be initialized with -EPROBE_DEFER value as the corresponding clock source is unavailable at the early stages. They will be allocated and initialized on the Baikal-T1 clock platform driver probe procedure. Finally the already available PLL/Divider init functions need to be split up into two ones: init procedure performed in the framework of the OF-declared clock initialization (of_clk_init()), and the probe procedure called by the platform devices bus driver. Note the later method will just continue the system clocks initialization started in the former one. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20220929225402.9696-9-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Remove module things because the Kconfig is still bool] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-09-29 22:54:02 +00:00
}
clk: Add Baikal-T1 CCU Dividers driver Nearly each Baikal-T1 IP-core is supposed to have a clock source of particular frequency. But since there are greater than five IP-blocks embedded into the SoC, the CCU PLLs can't fulfill all the needs. Baikal-T1 CCU provides a set of fixed and configurable clock dividers in order to generate a necessary signal for each chip sub-block. This driver creates the of-based hardware clocks for each divider available in Baikal-T1 CCU. The same way as for PLLs we split the functionality up into the clocks operations (gate, ungate, set rate, etc) and hardware clocks declaration/registration procedures. In accordance with the CCU documentation all its dividers are distributed into two CCU sub-blocks: AXI-bus and system devices reference clocks. The former sub-block is used to supply the clocks for AXI-bus interfaces (AXI clock domains) and the later one provides the SoC IP-cores reference clocks. Each sub-block is represented by a dedicated DT node, so they have different compatible strings to distinguish one from another. For some reason CCU provides the dividers of different types. Some dividers can be gateable some can't, some are fixed while the others are variable, some have special divider' limitations, some've got a non-standard register layout and so on. In order to cover all of these cases the hardware clocks driver is designed with an info-descriptor pattern. So there are special static descriptors declared for the dividers of each type with additional flags describing the block peculiarity. These descriptors are then used to create hardware clocks with proper operations. Some CCU dividers provide a way to reset a domain they generate a clock for. So the CCU AXI-bus and CCU system devices clock drivers also perform the reset controller registration. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Rob Herring <robh+dt@kernel.org> Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200526222056.18072-5-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Drop return from void function, silence sparse warnings about initializing structs with NULL vs. integer] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2020-05-26 22:20:56 +00:00
return ret;
}
clk: baikal-t1: Convert to platform device driver In accordance with the way the MIPS platform is normally design there are only six clock sources which need to be available on the kernel start in order to one end up booting correctly: + CPU PLL: needed by the r4k and MIPS GIC timer drivers. The former one is initialized by the arch code, while the later one is implemented in the mips-gic-timer.c driver as the OF-declared timer. + PCIe PLL: required as a parental clock source for the APB/timer domains. + APB clock: needed in order to access all the SoC CSRs at least for the timer OF-declared drivers. + APB Timer{0-2} clocks: these are the DW APB timers which drivers dw_apb_timer_of.c are implemented as the OF-declared timers. So as long as the clocks above are available early the kernel will normally work. Let's convert the Baikal-T1 CCU drivers to the platform device drivers keeping that in mind. Generally speaking the conversion isn't that complicated since the driver infrastructure has been designed as flexible enough for that. First we need to add a new PLL/Divider clock features flag which indicates the corresponding clock source as a basic one and that clock sources will be available on the kernel early boot stages. Second the internal PLL/Divider descriptors need to be initialized with -EPROBE_DEFER value as the corresponding clock source is unavailable at the early stages. They will be allocated and initialized on the Baikal-T1 clock platform driver probe procedure. Finally the already available PLL/Divider init functions need to be split up into two ones: init procedure performed in the framework of the OF-declared clock initialization (of_clk_init()), and the probe procedure called by the platform devices bus driver. Note the later method will just continue the system clocks initialization started in the former one. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20220929225402.9696-9-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Remove module things because the Kconfig is still bool] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-09-29 22:54:02 +00:00
static void ccu_div_clk_unregister(struct ccu_div_data *data, bool defer)
clk: Add Baikal-T1 CCU Dividers driver Nearly each Baikal-T1 IP-core is supposed to have a clock source of particular frequency. But since there are greater than five IP-blocks embedded into the SoC, the CCU PLLs can't fulfill all the needs. Baikal-T1 CCU provides a set of fixed and configurable clock dividers in order to generate a necessary signal for each chip sub-block. This driver creates the of-based hardware clocks for each divider available in Baikal-T1 CCU. The same way as for PLLs we split the functionality up into the clocks operations (gate, ungate, set rate, etc) and hardware clocks declaration/registration procedures. In accordance with the CCU documentation all its dividers are distributed into two CCU sub-blocks: AXI-bus and system devices reference clocks. The former sub-block is used to supply the clocks for AXI-bus interfaces (AXI clock domains) and the later one provides the SoC IP-cores reference clocks. Each sub-block is represented by a dedicated DT node, so they have different compatible strings to distinguish one from another. For some reason CCU provides the dividers of different types. Some dividers can be gateable some can't, some are fixed while the others are variable, some have special divider' limitations, some've got a non-standard register layout and so on. In order to cover all of these cases the hardware clocks driver is designed with an info-descriptor pattern. So there are special static descriptors declared for the dividers of each type with additional flags describing the block peculiarity. These descriptors are then used to create hardware clocks with proper operations. Some CCU dividers provide a way to reset a domain they generate a clock for. So the CCU AXI-bus and CCU system devices clock drivers also perform the reset controller registration. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Rob Herring <robh+dt@kernel.org> Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200526222056.18072-5-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Drop return from void function, silence sparse warnings about initializing structs with NULL vs. integer] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2020-05-26 22:20:56 +00:00
{
int idx;
clk: baikal-t1: Convert to platform device driver In accordance with the way the MIPS platform is normally design there are only six clock sources which need to be available on the kernel start in order to one end up booting correctly: + CPU PLL: needed by the r4k and MIPS GIC timer drivers. The former one is initialized by the arch code, while the later one is implemented in the mips-gic-timer.c driver as the OF-declared timer. + PCIe PLL: required as a parental clock source for the APB/timer domains. + APB clock: needed in order to access all the SoC CSRs at least for the timer OF-declared drivers. + APB Timer{0-2} clocks: these are the DW APB timers which drivers dw_apb_timer_of.c are implemented as the OF-declared timers. So as long as the clocks above are available early the kernel will normally work. Let's convert the Baikal-T1 CCU drivers to the platform device drivers keeping that in mind. Generally speaking the conversion isn't that complicated since the driver infrastructure has been designed as flexible enough for that. First we need to add a new PLL/Divider clock features flag which indicates the corresponding clock source as a basic one and that clock sources will be available on the kernel early boot stages. Second the internal PLL/Divider descriptors need to be initialized with -EPROBE_DEFER value as the corresponding clock source is unavailable at the early stages. They will be allocated and initialized on the Baikal-T1 clock platform driver probe procedure. Finally the already available PLL/Divider init functions need to be split up into two ones: init procedure performed in the framework of the OF-declared clock initialization (of_clk_init()), and the probe procedure called by the platform devices bus driver. Note the later method will just continue the system clocks initialization started in the former one. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20220929225402.9696-9-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Remove module things because the Kconfig is still bool] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-09-29 22:54:02 +00:00
/* Uninstall only the clocks registered on the specfied stage */
for (idx = 0; idx < data->divs_num; ++idx) {
if (!!(data->divs_info[idx].features & CCU_DIV_BASIC) ^ defer)
continue;
clk: Add Baikal-T1 CCU Dividers driver Nearly each Baikal-T1 IP-core is supposed to have a clock source of particular frequency. But since there are greater than five IP-blocks embedded into the SoC, the CCU PLLs can't fulfill all the needs. Baikal-T1 CCU provides a set of fixed and configurable clock dividers in order to generate a necessary signal for each chip sub-block. This driver creates the of-based hardware clocks for each divider available in Baikal-T1 CCU. The same way as for PLLs we split the functionality up into the clocks operations (gate, ungate, set rate, etc) and hardware clocks declaration/registration procedures. In accordance with the CCU documentation all its dividers are distributed into two CCU sub-blocks: AXI-bus and system devices reference clocks. The former sub-block is used to supply the clocks for AXI-bus interfaces (AXI clock domains) and the later one provides the SoC IP-cores reference clocks. Each sub-block is represented by a dedicated DT node, so they have different compatible strings to distinguish one from another. For some reason CCU provides the dividers of different types. Some dividers can be gateable some can't, some are fixed while the others are variable, some have special divider' limitations, some've got a non-standard register layout and so on. In order to cover all of these cases the hardware clocks driver is designed with an info-descriptor pattern. So there are special static descriptors declared for the dividers of each type with additional flags describing the block peculiarity. These descriptors are then used to create hardware clocks with proper operations. Some CCU dividers provide a way to reset a domain they generate a clock for. So the CCU AXI-bus and CCU system devices clock drivers also perform the reset controller registration. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Rob Herring <robh+dt@kernel.org> Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200526222056.18072-5-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Drop return from void function, silence sparse warnings about initializing structs with NULL vs. integer] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2020-05-26 22:20:56 +00:00
ccu_div_hw_unregister(data->divs[idx]);
clk: baikal-t1: Convert to platform device driver In accordance with the way the MIPS platform is normally design there are only six clock sources which need to be available on the kernel start in order to one end up booting correctly: + CPU PLL: needed by the r4k and MIPS GIC timer drivers. The former one is initialized by the arch code, while the later one is implemented in the mips-gic-timer.c driver as the OF-declared timer. + PCIe PLL: required as a parental clock source for the APB/timer domains. + APB clock: needed in order to access all the SoC CSRs at least for the timer OF-declared drivers. + APB Timer{0-2} clocks: these are the DW APB timers which drivers dw_apb_timer_of.c are implemented as the OF-declared timers. So as long as the clocks above are available early the kernel will normally work. Let's convert the Baikal-T1 CCU drivers to the platform device drivers keeping that in mind. Generally speaking the conversion isn't that complicated since the driver infrastructure has been designed as flexible enough for that. First we need to add a new PLL/Divider clock features flag which indicates the corresponding clock source as a basic one and that clock sources will be available on the kernel early boot stages. Second the internal PLL/Divider descriptors need to be initialized with -EPROBE_DEFER value as the corresponding clock source is unavailable at the early stages. They will be allocated and initialized on the Baikal-T1 clock platform driver probe procedure. Finally the already available PLL/Divider init functions need to be split up into two ones: init procedure performed in the framework of the OF-declared clock initialization (of_clk_init()), and the probe procedure called by the platform devices bus driver. Note the later method will just continue the system clocks initialization started in the former one. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20220929225402.9696-9-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Remove module things because the Kconfig is still bool] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-09-29 22:54:02 +00:00
}
}
static int ccu_div_of_register(struct ccu_div_data *data)
{
int ret;
ret = of_clk_add_hw_provider(data->np, ccu_div_of_clk_hw_get, data);
if (ret) {
pr_err("Couldn't register dividers '%s' clock provider\n",
of_node_full_name(data->np));
}
return ret;
clk: Add Baikal-T1 CCU Dividers driver Nearly each Baikal-T1 IP-core is supposed to have a clock source of particular frequency. But since there are greater than five IP-blocks embedded into the SoC, the CCU PLLs can't fulfill all the needs. Baikal-T1 CCU provides a set of fixed and configurable clock dividers in order to generate a necessary signal for each chip sub-block. This driver creates the of-based hardware clocks for each divider available in Baikal-T1 CCU. The same way as for PLLs we split the functionality up into the clocks operations (gate, ungate, set rate, etc) and hardware clocks declaration/registration procedures. In accordance with the CCU documentation all its dividers are distributed into two CCU sub-blocks: AXI-bus and system devices reference clocks. The former sub-block is used to supply the clocks for AXI-bus interfaces (AXI clock domains) and the later one provides the SoC IP-cores reference clocks. Each sub-block is represented by a dedicated DT node, so they have different compatible strings to distinguish one from another. For some reason CCU provides the dividers of different types. Some dividers can be gateable some can't, some are fixed while the others are variable, some have special divider' limitations, some've got a non-standard register layout and so on. In order to cover all of these cases the hardware clocks driver is designed with an info-descriptor pattern. So there are special static descriptors declared for the dividers of each type with additional flags describing the block peculiarity. These descriptors are then used to create hardware clocks with proper operations. Some CCU dividers provide a way to reset a domain they generate a clock for. So the CCU AXI-bus and CCU system devices clock drivers also perform the reset controller registration. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Rob Herring <robh+dt@kernel.org> Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200526222056.18072-5-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Drop return from void function, silence sparse warnings about initializing structs with NULL vs. integer] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2020-05-26 22:20:56 +00:00
}
static int ccu_div_rst_register(struct ccu_div_data *data)
{
clk: baikal-t1: Move reset-controls code into a dedicated module Before adding the directly controlled resets support it's reasonable to move the existing resets control functionality into a dedicated object for the sake of the CCU dividers clock driver simplification. After the new functionality was added clk-ccu-div.c would have got to a mixture of the weakly dependent clocks and resets methods. Splitting the methods up into the two objects will make the code easier to read and maintain. It shall also improve the code scalability (though hopefully we won't need this part that much in the future). The reset control functionality is now implemented in the framework of a single unit since splitting it up doesn't make much sense due to relatively simple reset operations. The ccu-rst.c has been designed to be looking like ccu-div.c or ccu-pll.c with two globally available methods for the sake of the code unification and better code readability. This commit doesn't provide any change in the CCU reset implementation semantics. As before the driver will support the trigger-like CCU resets only, which are responsible for the AXI-bus, APB-bus and SATA-ref blocks reset. The assert/de-assert-capable reset controls support will be added in the next commit. Note the CCU Clock dividers and resets functionality split up was possible due to not having any side-effects (at least we didn't found ones) of the regmap-based concurrent access of the common CCU dividers/reset CSRs. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> Link: https://lore.kernel.org/r/20220929225402.9696-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-09-29 22:53:59 +00:00
struct ccu_rst_init_data init = {0};
clk: Add Baikal-T1 CCU Dividers driver Nearly each Baikal-T1 IP-core is supposed to have a clock source of particular frequency. But since there are greater than five IP-blocks embedded into the SoC, the CCU PLLs can't fulfill all the needs. Baikal-T1 CCU provides a set of fixed and configurable clock dividers in order to generate a necessary signal for each chip sub-block. This driver creates the of-based hardware clocks for each divider available in Baikal-T1 CCU. The same way as for PLLs we split the functionality up into the clocks operations (gate, ungate, set rate, etc) and hardware clocks declaration/registration procedures. In accordance with the CCU documentation all its dividers are distributed into two CCU sub-blocks: AXI-bus and system devices reference clocks. The former sub-block is used to supply the clocks for AXI-bus interfaces (AXI clock domains) and the later one provides the SoC IP-cores reference clocks. Each sub-block is represented by a dedicated DT node, so they have different compatible strings to distinguish one from another. For some reason CCU provides the dividers of different types. Some dividers can be gateable some can't, some are fixed while the others are variable, some have special divider' limitations, some've got a non-standard register layout and so on. In order to cover all of these cases the hardware clocks driver is designed with an info-descriptor pattern. So there are special static descriptors declared for the dividers of each type with additional flags describing the block peculiarity. These descriptors are then used to create hardware clocks with proper operations. Some CCU dividers provide a way to reset a domain they generate a clock for. So the CCU AXI-bus and CCU system devices clock drivers also perform the reset controller registration. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Rob Herring <robh+dt@kernel.org> Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200526222056.18072-5-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Drop return from void function, silence sparse warnings about initializing structs with NULL vs. integer] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2020-05-26 22:20:56 +00:00
clk: baikal-t1: Move reset-controls code into a dedicated module Before adding the directly controlled resets support it's reasonable to move the existing resets control functionality into a dedicated object for the sake of the CCU dividers clock driver simplification. After the new functionality was added clk-ccu-div.c would have got to a mixture of the weakly dependent clocks and resets methods. Splitting the methods up into the two objects will make the code easier to read and maintain. It shall also improve the code scalability (though hopefully we won't need this part that much in the future). The reset control functionality is now implemented in the framework of a single unit since splitting it up doesn't make much sense due to relatively simple reset operations. The ccu-rst.c has been designed to be looking like ccu-div.c or ccu-pll.c with two globally available methods for the sake of the code unification and better code readability. This commit doesn't provide any change in the CCU reset implementation semantics. As before the driver will support the trigger-like CCU resets only, which are responsible for the AXI-bus, APB-bus and SATA-ref blocks reset. The assert/de-assert-capable reset controls support will be added in the next commit. Note the CCU Clock dividers and resets functionality split up was possible due to not having any side-effects (at least we didn't found ones) of the regmap-based concurrent access of the common CCU dividers/reset CSRs. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> Link: https://lore.kernel.org/r/20220929225402.9696-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-09-29 22:53:59 +00:00
init.sys_regs = data->sys_regs;
init.np = data->np;
clk: Add Baikal-T1 CCU Dividers driver Nearly each Baikal-T1 IP-core is supposed to have a clock source of particular frequency. But since there are greater than five IP-blocks embedded into the SoC, the CCU PLLs can't fulfill all the needs. Baikal-T1 CCU provides a set of fixed and configurable clock dividers in order to generate a necessary signal for each chip sub-block. This driver creates the of-based hardware clocks for each divider available in Baikal-T1 CCU. The same way as for PLLs we split the functionality up into the clocks operations (gate, ungate, set rate, etc) and hardware clocks declaration/registration procedures. In accordance with the CCU documentation all its dividers are distributed into two CCU sub-blocks: AXI-bus and system devices reference clocks. The former sub-block is used to supply the clocks for AXI-bus interfaces (AXI clock domains) and the later one provides the SoC IP-cores reference clocks. Each sub-block is represented by a dedicated DT node, so they have different compatible strings to distinguish one from another. For some reason CCU provides the dividers of different types. Some dividers can be gateable some can't, some are fixed while the others are variable, some have special divider' limitations, some've got a non-standard register layout and so on. In order to cover all of these cases the hardware clocks driver is designed with an info-descriptor pattern. So there are special static descriptors declared for the dividers of each type with additional flags describing the block peculiarity. These descriptors are then used to create hardware clocks with proper operations. Some CCU dividers provide a way to reset a domain they generate a clock for. So the CCU AXI-bus and CCU system devices clock drivers also perform the reset controller registration. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Rob Herring <robh+dt@kernel.org> Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200526222056.18072-5-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Drop return from void function, silence sparse warnings about initializing structs with NULL vs. integer] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2020-05-26 22:20:56 +00:00
clk: baikal-t1: Move reset-controls code into a dedicated module Before adding the directly controlled resets support it's reasonable to move the existing resets control functionality into a dedicated object for the sake of the CCU dividers clock driver simplification. After the new functionality was added clk-ccu-div.c would have got to a mixture of the weakly dependent clocks and resets methods. Splitting the methods up into the two objects will make the code easier to read and maintain. It shall also improve the code scalability (though hopefully we won't need this part that much in the future). The reset control functionality is now implemented in the framework of a single unit since splitting it up doesn't make much sense due to relatively simple reset operations. The ccu-rst.c has been designed to be looking like ccu-div.c or ccu-pll.c with two globally available methods for the sake of the code unification and better code readability. This commit doesn't provide any change in the CCU reset implementation semantics. As before the driver will support the trigger-like CCU resets only, which are responsible for the AXI-bus, APB-bus and SATA-ref blocks reset. The assert/de-assert-capable reset controls support will be added in the next commit. Note the CCU Clock dividers and resets functionality split up was possible due to not having any side-effects (at least we didn't found ones) of the regmap-based concurrent access of the common CCU dividers/reset CSRs. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> Link: https://lore.kernel.org/r/20220929225402.9696-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-09-29 22:53:59 +00:00
data->rsts = ccu_rst_hw_register(&init);
if (IS_ERR(data->rsts)) {
clk: Add Baikal-T1 CCU Dividers driver Nearly each Baikal-T1 IP-core is supposed to have a clock source of particular frequency. But since there are greater than five IP-blocks embedded into the SoC, the CCU PLLs can't fulfill all the needs. Baikal-T1 CCU provides a set of fixed and configurable clock dividers in order to generate a necessary signal for each chip sub-block. This driver creates the of-based hardware clocks for each divider available in Baikal-T1 CCU. The same way as for PLLs we split the functionality up into the clocks operations (gate, ungate, set rate, etc) and hardware clocks declaration/registration procedures. In accordance with the CCU documentation all its dividers are distributed into two CCU sub-blocks: AXI-bus and system devices reference clocks. The former sub-block is used to supply the clocks for AXI-bus interfaces (AXI clock domains) and the later one provides the SoC IP-cores reference clocks. Each sub-block is represented by a dedicated DT node, so they have different compatible strings to distinguish one from another. For some reason CCU provides the dividers of different types. Some dividers can be gateable some can't, some are fixed while the others are variable, some have special divider' limitations, some've got a non-standard register layout and so on. In order to cover all of these cases the hardware clocks driver is designed with an info-descriptor pattern. So there are special static descriptors declared for the dividers of each type with additional flags describing the block peculiarity. These descriptors are then used to create hardware clocks with proper operations. Some CCU dividers provide a way to reset a domain they generate a clock for. So the CCU AXI-bus and CCU system devices clock drivers also perform the reset controller registration. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Rob Herring <robh+dt@kernel.org> Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200526222056.18072-5-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Drop return from void function, silence sparse warnings about initializing structs with NULL vs. integer] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2020-05-26 22:20:56 +00:00
pr_err("Couldn't register divider '%s' reset controller\n",
of_node_full_name(data->np));
clk: baikal-t1: Move reset-controls code into a dedicated module Before adding the directly controlled resets support it's reasonable to move the existing resets control functionality into a dedicated object for the sake of the CCU dividers clock driver simplification. After the new functionality was added clk-ccu-div.c would have got to a mixture of the weakly dependent clocks and resets methods. Splitting the methods up into the two objects will make the code easier to read and maintain. It shall also improve the code scalability (though hopefully we won't need this part that much in the future). The reset control functionality is now implemented in the framework of a single unit since splitting it up doesn't make much sense due to relatively simple reset operations. The ccu-rst.c has been designed to be looking like ccu-div.c or ccu-pll.c with two globally available methods for the sake of the code unification and better code readability. This commit doesn't provide any change in the CCU reset implementation semantics. As before the driver will support the trigger-like CCU resets only, which are responsible for the AXI-bus, APB-bus and SATA-ref blocks reset. The assert/de-assert-capable reset controls support will be added in the next commit. Note the CCU Clock dividers and resets functionality split up was possible due to not having any side-effects (at least we didn't found ones) of the regmap-based concurrent access of the common CCU dividers/reset CSRs. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> Link: https://lore.kernel.org/r/20220929225402.9696-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-09-29 22:53:59 +00:00
return PTR_ERR(data->rsts);
}
clk: Add Baikal-T1 CCU Dividers driver Nearly each Baikal-T1 IP-core is supposed to have a clock source of particular frequency. But since there are greater than five IP-blocks embedded into the SoC, the CCU PLLs can't fulfill all the needs. Baikal-T1 CCU provides a set of fixed and configurable clock dividers in order to generate a necessary signal for each chip sub-block. This driver creates the of-based hardware clocks for each divider available in Baikal-T1 CCU. The same way as for PLLs we split the functionality up into the clocks operations (gate, ungate, set rate, etc) and hardware clocks declaration/registration procedures. In accordance with the CCU documentation all its dividers are distributed into two CCU sub-blocks: AXI-bus and system devices reference clocks. The former sub-block is used to supply the clocks for AXI-bus interfaces (AXI clock domains) and the later one provides the SoC IP-cores reference clocks. Each sub-block is represented by a dedicated DT node, so they have different compatible strings to distinguish one from another. For some reason CCU provides the dividers of different types. Some dividers can be gateable some can't, some are fixed while the others are variable, some have special divider' limitations, some've got a non-standard register layout and so on. In order to cover all of these cases the hardware clocks driver is designed with an info-descriptor pattern. So there are special static descriptors declared for the dividers of each type with additional flags describing the block peculiarity. These descriptors are then used to create hardware clocks with proper operations. Some CCU dividers provide a way to reset a domain they generate a clock for. So the CCU AXI-bus and CCU system devices clock drivers also perform the reset controller registration. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Rob Herring <robh+dt@kernel.org> Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200526222056.18072-5-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Drop return from void function, silence sparse warnings about initializing structs with NULL vs. integer] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2020-05-26 22:20:56 +00:00
clk: baikal-t1: Move reset-controls code into a dedicated module Before adding the directly controlled resets support it's reasonable to move the existing resets control functionality into a dedicated object for the sake of the CCU dividers clock driver simplification. After the new functionality was added clk-ccu-div.c would have got to a mixture of the weakly dependent clocks and resets methods. Splitting the methods up into the two objects will make the code easier to read and maintain. It shall also improve the code scalability (though hopefully we won't need this part that much in the future). The reset control functionality is now implemented in the framework of a single unit since splitting it up doesn't make much sense due to relatively simple reset operations. The ccu-rst.c has been designed to be looking like ccu-div.c or ccu-pll.c with two globally available methods for the sake of the code unification and better code readability. This commit doesn't provide any change in the CCU reset implementation semantics. As before the driver will support the trigger-like CCU resets only, which are responsible for the AXI-bus, APB-bus and SATA-ref blocks reset. The assert/de-assert-capable reset controls support will be added in the next commit. Note the CCU Clock dividers and resets functionality split up was possible due to not having any side-effects (at least we didn't found ones) of the regmap-based concurrent access of the common CCU dividers/reset CSRs. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> Link: https://lore.kernel.org/r/20220929225402.9696-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-09-29 22:53:59 +00:00
return 0;
clk: Add Baikal-T1 CCU Dividers driver Nearly each Baikal-T1 IP-core is supposed to have a clock source of particular frequency. But since there are greater than five IP-blocks embedded into the SoC, the CCU PLLs can't fulfill all the needs. Baikal-T1 CCU provides a set of fixed and configurable clock dividers in order to generate a necessary signal for each chip sub-block. This driver creates the of-based hardware clocks for each divider available in Baikal-T1 CCU. The same way as for PLLs we split the functionality up into the clocks operations (gate, ungate, set rate, etc) and hardware clocks declaration/registration procedures. In accordance with the CCU documentation all its dividers are distributed into two CCU sub-blocks: AXI-bus and system devices reference clocks. The former sub-block is used to supply the clocks for AXI-bus interfaces (AXI clock domains) and the later one provides the SoC IP-cores reference clocks. Each sub-block is represented by a dedicated DT node, so they have different compatible strings to distinguish one from another. For some reason CCU provides the dividers of different types. Some dividers can be gateable some can't, some are fixed while the others are variable, some have special divider' limitations, some've got a non-standard register layout and so on. In order to cover all of these cases the hardware clocks driver is designed with an info-descriptor pattern. So there are special static descriptors declared for the dividers of each type with additional flags describing the block peculiarity. These descriptors are then used to create hardware clocks with proper operations. Some CCU dividers provide a way to reset a domain they generate a clock for. So the CCU AXI-bus and CCU system devices clock drivers also perform the reset controller registration. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Rob Herring <robh+dt@kernel.org> Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200526222056.18072-5-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Drop return from void function, silence sparse warnings about initializing structs with NULL vs. integer] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2020-05-26 22:20:56 +00:00
}
clk: baikal-t1: Convert to platform device driver In accordance with the way the MIPS platform is normally design there are only six clock sources which need to be available on the kernel start in order to one end up booting correctly: + CPU PLL: needed by the r4k and MIPS GIC timer drivers. The former one is initialized by the arch code, while the later one is implemented in the mips-gic-timer.c driver as the OF-declared timer. + PCIe PLL: required as a parental clock source for the APB/timer domains. + APB clock: needed in order to access all the SoC CSRs at least for the timer OF-declared drivers. + APB Timer{0-2} clocks: these are the DW APB timers which drivers dw_apb_timer_of.c are implemented as the OF-declared timers. So as long as the clocks above are available early the kernel will normally work. Let's convert the Baikal-T1 CCU drivers to the platform device drivers keeping that in mind. Generally speaking the conversion isn't that complicated since the driver infrastructure has been designed as flexible enough for that. First we need to add a new PLL/Divider clock features flag which indicates the corresponding clock source as a basic one and that clock sources will be available on the kernel early boot stages. Second the internal PLL/Divider descriptors need to be initialized with -EPROBE_DEFER value as the corresponding clock source is unavailable at the early stages. They will be allocated and initialized on the Baikal-T1 clock platform driver probe procedure. Finally the already available PLL/Divider init functions need to be split up into two ones: init procedure performed in the framework of the OF-declared clock initialization (of_clk_init()), and the probe procedure called by the platform devices bus driver. Note the later method will just continue the system clocks initialization started in the former one. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20220929225402.9696-9-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Remove module things because the Kconfig is still bool] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-09-29 22:54:02 +00:00
static int ccu_div_probe(struct platform_device *pdev)
{
struct ccu_div_data *data;
int ret;
data = ccu_div_get_data(dev_of_node(&pdev->dev));
if (!data)
return -EINVAL;
ret = ccu_div_clk_register(data, false);
if (ret)
return ret;
ret = ccu_div_rst_register(data);
if (ret)
goto err_clk_unregister;
return 0;
err_clk_unregister:
ccu_div_clk_unregister(data, false);
return ret;
}
static const struct of_device_id ccu_div_of_match[] = {
{ .compatible = "baikal,bt1-ccu-axi" },
{ .compatible = "baikal,bt1-ccu-sys" },
{ }
};
static struct platform_driver ccu_div_driver = {
.probe = ccu_div_probe,
.driver = {
.name = "clk-ccu-div",
.of_match_table = ccu_div_of_match,
.suppress_bind_attrs = true,
},
};
builtin_platform_driver(ccu_div_driver);
static __init void ccu_div_init(struct device_node *np)
clk: Add Baikal-T1 CCU Dividers driver Nearly each Baikal-T1 IP-core is supposed to have a clock source of particular frequency. But since there are greater than five IP-blocks embedded into the SoC, the CCU PLLs can't fulfill all the needs. Baikal-T1 CCU provides a set of fixed and configurable clock dividers in order to generate a necessary signal for each chip sub-block. This driver creates the of-based hardware clocks for each divider available in Baikal-T1 CCU. The same way as for PLLs we split the functionality up into the clocks operations (gate, ungate, set rate, etc) and hardware clocks declaration/registration procedures. In accordance with the CCU documentation all its dividers are distributed into two CCU sub-blocks: AXI-bus and system devices reference clocks. The former sub-block is used to supply the clocks for AXI-bus interfaces (AXI clock domains) and the later one provides the SoC IP-cores reference clocks. Each sub-block is represented by a dedicated DT node, so they have different compatible strings to distinguish one from another. For some reason CCU provides the dividers of different types. Some dividers can be gateable some can't, some are fixed while the others are variable, some have special divider' limitations, some've got a non-standard register layout and so on. In order to cover all of these cases the hardware clocks driver is designed with an info-descriptor pattern. So there are special static descriptors declared for the dividers of each type with additional flags describing the block peculiarity. These descriptors are then used to create hardware clocks with proper operations. Some CCU dividers provide a way to reset a domain they generate a clock for. So the CCU AXI-bus and CCU system devices clock drivers also perform the reset controller registration. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Rob Herring <robh+dt@kernel.org> Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200526222056.18072-5-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Drop return from void function, silence sparse warnings about initializing structs with NULL vs. integer] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2020-05-26 22:20:56 +00:00
{
struct ccu_div_data *data;
int ret;
data = ccu_div_create_data(np);
if (IS_ERR(data))
return;
ret = ccu_div_find_sys_regs(data);
if (ret)
goto err_free_data;
clk: baikal-t1: Convert to platform device driver In accordance with the way the MIPS platform is normally design there are only six clock sources which need to be available on the kernel start in order to one end up booting correctly: + CPU PLL: needed by the r4k and MIPS GIC timer drivers. The former one is initialized by the arch code, while the later one is implemented in the mips-gic-timer.c driver as the OF-declared timer. + PCIe PLL: required as a parental clock source for the APB/timer domains. + APB clock: needed in order to access all the SoC CSRs at least for the timer OF-declared drivers. + APB Timer{0-2} clocks: these are the DW APB timers which drivers dw_apb_timer_of.c are implemented as the OF-declared timers. So as long as the clocks above are available early the kernel will normally work. Let's convert the Baikal-T1 CCU drivers to the platform device drivers keeping that in mind. Generally speaking the conversion isn't that complicated since the driver infrastructure has been designed as flexible enough for that. First we need to add a new PLL/Divider clock features flag which indicates the corresponding clock source as a basic one and that clock sources will be available on the kernel early boot stages. Second the internal PLL/Divider descriptors need to be initialized with -EPROBE_DEFER value as the corresponding clock source is unavailable at the early stages. They will be allocated and initialized on the Baikal-T1 clock platform driver probe procedure. Finally the already available PLL/Divider init functions need to be split up into two ones: init procedure performed in the framework of the OF-declared clock initialization (of_clk_init()), and the probe procedure called by the platform devices bus driver. Note the later method will just continue the system clocks initialization started in the former one. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20220929225402.9696-9-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Remove module things because the Kconfig is still bool] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-09-29 22:54:02 +00:00
ret = ccu_div_clk_register(data, true);
clk: Add Baikal-T1 CCU Dividers driver Nearly each Baikal-T1 IP-core is supposed to have a clock source of particular frequency. But since there are greater than five IP-blocks embedded into the SoC, the CCU PLLs can't fulfill all the needs. Baikal-T1 CCU provides a set of fixed and configurable clock dividers in order to generate a necessary signal for each chip sub-block. This driver creates the of-based hardware clocks for each divider available in Baikal-T1 CCU. The same way as for PLLs we split the functionality up into the clocks operations (gate, ungate, set rate, etc) and hardware clocks declaration/registration procedures. In accordance with the CCU documentation all its dividers are distributed into two CCU sub-blocks: AXI-bus and system devices reference clocks. The former sub-block is used to supply the clocks for AXI-bus interfaces (AXI clock domains) and the later one provides the SoC IP-cores reference clocks. Each sub-block is represented by a dedicated DT node, so they have different compatible strings to distinguish one from another. For some reason CCU provides the dividers of different types. Some dividers can be gateable some can't, some are fixed while the others are variable, some have special divider' limitations, some've got a non-standard register layout and so on. In order to cover all of these cases the hardware clocks driver is designed with an info-descriptor pattern. So there are special static descriptors declared for the dividers of each type with additional flags describing the block peculiarity. These descriptors are then used to create hardware clocks with proper operations. Some CCU dividers provide a way to reset a domain they generate a clock for. So the CCU AXI-bus and CCU system devices clock drivers also perform the reset controller registration. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Rob Herring <robh+dt@kernel.org> Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200526222056.18072-5-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Drop return from void function, silence sparse warnings about initializing structs with NULL vs. integer] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2020-05-26 22:20:56 +00:00
if (ret)
goto err_free_data;
clk: baikal-t1: Convert to platform device driver In accordance with the way the MIPS platform is normally design there are only six clock sources which need to be available on the kernel start in order to one end up booting correctly: + CPU PLL: needed by the r4k and MIPS GIC timer drivers. The former one is initialized by the arch code, while the later one is implemented in the mips-gic-timer.c driver as the OF-declared timer. + PCIe PLL: required as a parental clock source for the APB/timer domains. + APB clock: needed in order to access all the SoC CSRs at least for the timer OF-declared drivers. + APB Timer{0-2} clocks: these are the DW APB timers which drivers dw_apb_timer_of.c are implemented as the OF-declared timers. So as long as the clocks above are available early the kernel will normally work. Let's convert the Baikal-T1 CCU drivers to the platform device drivers keeping that in mind. Generally speaking the conversion isn't that complicated since the driver infrastructure has been designed as flexible enough for that. First we need to add a new PLL/Divider clock features flag which indicates the corresponding clock source as a basic one and that clock sources will be available on the kernel early boot stages. Second the internal PLL/Divider descriptors need to be initialized with -EPROBE_DEFER value as the corresponding clock source is unavailable at the early stages. They will be allocated and initialized on the Baikal-T1 clock platform driver probe procedure. Finally the already available PLL/Divider init functions need to be split up into two ones: init procedure performed in the framework of the OF-declared clock initialization (of_clk_init()), and the probe procedure called by the platform devices bus driver. Note the later method will just continue the system clocks initialization started in the former one. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20220929225402.9696-9-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Remove module things because the Kconfig is still bool] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-09-29 22:54:02 +00:00
ret = ccu_div_of_register(data);
clk: Add Baikal-T1 CCU Dividers driver Nearly each Baikal-T1 IP-core is supposed to have a clock source of particular frequency. But since there are greater than five IP-blocks embedded into the SoC, the CCU PLLs can't fulfill all the needs. Baikal-T1 CCU provides a set of fixed and configurable clock dividers in order to generate a necessary signal for each chip sub-block. This driver creates the of-based hardware clocks for each divider available in Baikal-T1 CCU. The same way as for PLLs we split the functionality up into the clocks operations (gate, ungate, set rate, etc) and hardware clocks declaration/registration procedures. In accordance with the CCU documentation all its dividers are distributed into two CCU sub-blocks: AXI-bus and system devices reference clocks. The former sub-block is used to supply the clocks for AXI-bus interfaces (AXI clock domains) and the later one provides the SoC IP-cores reference clocks. Each sub-block is represented by a dedicated DT node, so they have different compatible strings to distinguish one from another. For some reason CCU provides the dividers of different types. Some dividers can be gateable some can't, some are fixed while the others are variable, some have special divider' limitations, some've got a non-standard register layout and so on. In order to cover all of these cases the hardware clocks driver is designed with an info-descriptor pattern. So there are special static descriptors declared for the dividers of each type with additional flags describing the block peculiarity. These descriptors are then used to create hardware clocks with proper operations. Some CCU dividers provide a way to reset a domain they generate a clock for. So the CCU AXI-bus and CCU system devices clock drivers also perform the reset controller registration. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Rob Herring <robh+dt@kernel.org> Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200526222056.18072-5-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Drop return from void function, silence sparse warnings about initializing structs with NULL vs. integer] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2020-05-26 22:20:56 +00:00
if (ret)
goto err_clk_unregister;
clk: baikal-t1: Convert to platform device driver In accordance with the way the MIPS platform is normally design there are only six clock sources which need to be available on the kernel start in order to one end up booting correctly: + CPU PLL: needed by the r4k and MIPS GIC timer drivers. The former one is initialized by the arch code, while the later one is implemented in the mips-gic-timer.c driver as the OF-declared timer. + PCIe PLL: required as a parental clock source for the APB/timer domains. + APB clock: needed in order to access all the SoC CSRs at least for the timer OF-declared drivers. + APB Timer{0-2} clocks: these are the DW APB timers which drivers dw_apb_timer_of.c are implemented as the OF-declared timers. So as long as the clocks above are available early the kernel will normally work. Let's convert the Baikal-T1 CCU drivers to the platform device drivers keeping that in mind. Generally speaking the conversion isn't that complicated since the driver infrastructure has been designed as flexible enough for that. First we need to add a new PLL/Divider clock features flag which indicates the corresponding clock source as a basic one and that clock sources will be available on the kernel early boot stages. Second the internal PLL/Divider descriptors need to be initialized with -EPROBE_DEFER value as the corresponding clock source is unavailable at the early stages. They will be allocated and initialized on the Baikal-T1 clock platform driver probe procedure. Finally the already available PLL/Divider init functions need to be split up into two ones: init procedure performed in the framework of the OF-declared clock initialization (of_clk_init()), and the probe procedure called by the platform devices bus driver. Note the later method will just continue the system clocks initialization started in the former one. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20220929225402.9696-9-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Remove module things because the Kconfig is still bool] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-09-29 22:54:02 +00:00
ccu_div_set_data(data);
clk: Add Baikal-T1 CCU Dividers driver Nearly each Baikal-T1 IP-core is supposed to have a clock source of particular frequency. But since there are greater than five IP-blocks embedded into the SoC, the CCU PLLs can't fulfill all the needs. Baikal-T1 CCU provides a set of fixed and configurable clock dividers in order to generate a necessary signal for each chip sub-block. This driver creates the of-based hardware clocks for each divider available in Baikal-T1 CCU. The same way as for PLLs we split the functionality up into the clocks operations (gate, ungate, set rate, etc) and hardware clocks declaration/registration procedures. In accordance with the CCU documentation all its dividers are distributed into two CCU sub-blocks: AXI-bus and system devices reference clocks. The former sub-block is used to supply the clocks for AXI-bus interfaces (AXI clock domains) and the later one provides the SoC IP-cores reference clocks. Each sub-block is represented by a dedicated DT node, so they have different compatible strings to distinguish one from another. For some reason CCU provides the dividers of different types. Some dividers can be gateable some can't, some are fixed while the others are variable, some have special divider' limitations, some've got a non-standard register layout and so on. In order to cover all of these cases the hardware clocks driver is designed with an info-descriptor pattern. So there are special static descriptors declared for the dividers of each type with additional flags describing the block peculiarity. These descriptors are then used to create hardware clocks with proper operations. Some CCU dividers provide a way to reset a domain they generate a clock for. So the CCU AXI-bus and CCU system devices clock drivers also perform the reset controller registration. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Rob Herring <robh+dt@kernel.org> Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200526222056.18072-5-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Drop return from void function, silence sparse warnings about initializing structs with NULL vs. integer] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2020-05-26 22:20:56 +00:00
return;
err_clk_unregister:
clk: baikal-t1: Convert to platform device driver In accordance with the way the MIPS platform is normally design there are only six clock sources which need to be available on the kernel start in order to one end up booting correctly: + CPU PLL: needed by the r4k and MIPS GIC timer drivers. The former one is initialized by the arch code, while the later one is implemented in the mips-gic-timer.c driver as the OF-declared timer. + PCIe PLL: required as a parental clock source for the APB/timer domains. + APB clock: needed in order to access all the SoC CSRs at least for the timer OF-declared drivers. + APB Timer{0-2} clocks: these are the DW APB timers which drivers dw_apb_timer_of.c are implemented as the OF-declared timers. So as long as the clocks above are available early the kernel will normally work. Let's convert the Baikal-T1 CCU drivers to the platform device drivers keeping that in mind. Generally speaking the conversion isn't that complicated since the driver infrastructure has been designed as flexible enough for that. First we need to add a new PLL/Divider clock features flag which indicates the corresponding clock source as a basic one and that clock sources will be available on the kernel early boot stages. Second the internal PLL/Divider descriptors need to be initialized with -EPROBE_DEFER value as the corresponding clock source is unavailable at the early stages. They will be allocated and initialized on the Baikal-T1 clock platform driver probe procedure. Finally the already available PLL/Divider init functions need to be split up into two ones: init procedure performed in the framework of the OF-declared clock initialization (of_clk_init()), and the probe procedure called by the platform devices bus driver. Note the later method will just continue the system clocks initialization started in the former one. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20220929225402.9696-9-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Remove module things because the Kconfig is still bool] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-09-29 22:54:02 +00:00
ccu_div_clk_unregister(data, true);
clk: Add Baikal-T1 CCU Dividers driver Nearly each Baikal-T1 IP-core is supposed to have a clock source of particular frequency. But since there are greater than five IP-blocks embedded into the SoC, the CCU PLLs can't fulfill all the needs. Baikal-T1 CCU provides a set of fixed and configurable clock dividers in order to generate a necessary signal for each chip sub-block. This driver creates the of-based hardware clocks for each divider available in Baikal-T1 CCU. The same way as for PLLs we split the functionality up into the clocks operations (gate, ungate, set rate, etc) and hardware clocks declaration/registration procedures. In accordance with the CCU documentation all its dividers are distributed into two CCU sub-blocks: AXI-bus and system devices reference clocks. The former sub-block is used to supply the clocks for AXI-bus interfaces (AXI clock domains) and the later one provides the SoC IP-cores reference clocks. Each sub-block is represented by a dedicated DT node, so they have different compatible strings to distinguish one from another. For some reason CCU provides the dividers of different types. Some dividers can be gateable some can't, some are fixed while the others are variable, some have special divider' limitations, some've got a non-standard register layout and so on. In order to cover all of these cases the hardware clocks driver is designed with an info-descriptor pattern. So there are special static descriptors declared for the dividers of each type with additional flags describing the block peculiarity. These descriptors are then used to create hardware clocks with proper operations. Some CCU dividers provide a way to reset a domain they generate a clock for. So the CCU AXI-bus and CCU system devices clock drivers also perform the reset controller registration. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Rob Herring <robh+dt@kernel.org> Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200526222056.18072-5-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Drop return from void function, silence sparse warnings about initializing structs with NULL vs. integer] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2020-05-26 22:20:56 +00:00
err_free_data:
ccu_div_free_data(data);
}
clk: baikal-t1: Convert to platform device driver In accordance with the way the MIPS platform is normally design there are only six clock sources which need to be available on the kernel start in order to one end up booting correctly: + CPU PLL: needed by the r4k and MIPS GIC timer drivers. The former one is initialized by the arch code, while the later one is implemented in the mips-gic-timer.c driver as the OF-declared timer. + PCIe PLL: required as a parental clock source for the APB/timer domains. + APB clock: needed in order to access all the SoC CSRs at least for the timer OF-declared drivers. + APB Timer{0-2} clocks: these are the DW APB timers which drivers dw_apb_timer_of.c are implemented as the OF-declared timers. So as long as the clocks above are available early the kernel will normally work. Let's convert the Baikal-T1 CCU drivers to the platform device drivers keeping that in mind. Generally speaking the conversion isn't that complicated since the driver infrastructure has been designed as flexible enough for that. First we need to add a new PLL/Divider clock features flag which indicates the corresponding clock source as a basic one and that clock sources will be available on the kernel early boot stages. Second the internal PLL/Divider descriptors need to be initialized with -EPROBE_DEFER value as the corresponding clock source is unavailable at the early stages. They will be allocated and initialized on the Baikal-T1 clock platform driver probe procedure. Finally the already available PLL/Divider init functions need to be split up into two ones: init procedure performed in the framework of the OF-declared clock initialization (of_clk_init()), and the probe procedure called by the platform devices bus driver. Note the later method will just continue the system clocks initialization started in the former one. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20220929225402.9696-9-Sergey.Semin@baikalelectronics.ru [sboyd@kernel.org: Remove module things because the Kconfig is still bool] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-09-29 22:54:02 +00:00
CLK_OF_DECLARE_DRIVER(ccu_axi, "baikal,bt1-ccu-axi", ccu_div_init);
CLK_OF_DECLARE_DRIVER(ccu_sys, "baikal,bt1-ccu-sys", ccu_div_init);