mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-22 20:23:57 +08:00
Merge commit 'fe5fa8fbd4d47f40a45fa29ee1abdb10cb061ec2' into clk-next
This commit is contained in:
commit
b8f15e7119
@ -208,3 +208,8 @@ These clock IDs are defined in:
|
||||
ch3_unused lcpll_ports 4 BCM_NS2_LCPLL_PORTS_CH3_UNUSED
|
||||
ch4_unused lcpll_ports 5 BCM_NS2_LCPLL_PORTS_CH4_UNUSED
|
||||
ch5_unused lcpll_ports 6 BCM_NS2_LCPLL_PORTS_CH5_UNUSED
|
||||
|
||||
BCM63138
|
||||
--------
|
||||
PLL and leaf clock compatible strings for BCM63138 are:
|
||||
"brcm,bcm63138-armpll"
|
||||
|
22
Documentation/devicetree/bindings/clock/cs2000-cp.txt
Normal file
22
Documentation/devicetree/bindings/clock/cs2000-cp.txt
Normal file
@ -0,0 +1,22 @@
|
||||
CIRRUS LOGIC Fractional-N Clock Synthesizer & Clock Multiplier
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible: "cirrus,cs2000-cp"
|
||||
- reg: The chip select number on the I2C bus
|
||||
- clocks: common clock binding for CLK_IN, XTI/REF_CLK
|
||||
- clock-names: CLK_IN : clk_in, XTI/REF_CLK : ref_clk
|
||||
- #clock-cells: must be <0>
|
||||
|
||||
Example:
|
||||
|
||||
&i2c2 {
|
||||
...
|
||||
cs2000: clk_multiplier@4f {
|
||||
#clock-cells = <0>;
|
||||
compatible = "cirrus,cs2000-cp";
|
||||
reg = <0x4f>;
|
||||
clocks = <&rcar_sound 0>, <&x12_clk>;
|
||||
clock-names = "clk_in", "ref_clk";
|
||||
};
|
||||
};
|
@ -13,6 +13,7 @@ Required properties :
|
||||
"qcom,gcc-msm8974"
|
||||
"qcom,gcc-msm8974pro"
|
||||
"qcom,gcc-msm8974pro-ac"
|
||||
"qcom,gcc-msm8996"
|
||||
|
||||
- reg : shall contain base register location and length
|
||||
- #clock-cells : shall contain 1
|
||||
|
@ -9,6 +9,7 @@ Required properties :
|
||||
"qcom,mmcc-msm8660"
|
||||
"qcom,mmcc-msm8960"
|
||||
"qcom,mmcc-msm8974"
|
||||
"qcom,mmcc-msm8996"
|
||||
|
||||
- reg : shall contain base register location and length
|
||||
- #clock-cells : shall contain 1
|
||||
|
@ -20,6 +20,10 @@ Required Properties:
|
||||
clocks must be specified. For clocks with multiple parents, invalid
|
||||
settings must be specified as "<0>".
|
||||
- #clock-cells: Must be 0
|
||||
|
||||
|
||||
Optional Properties:
|
||||
|
||||
- clock-output-names: The name of the clock as a free-form string
|
||||
|
||||
|
||||
|
@ -0,0 +1,56 @@
|
||||
* Rockchip RK3036 Clock and Reset Unit
|
||||
|
||||
The RK3036 clock controller generates and supplies clock to various
|
||||
controllers within the SoC and also implements a reset controller for SoC
|
||||
peripherals.
|
||||
|
||||
Required Properties:
|
||||
|
||||
- compatible: should be "rockchip,rk3036-cru"
|
||||
- reg: physical base address of the controller and length of memory mapped
|
||||
region.
|
||||
- #clock-cells: should be 1.
|
||||
- #reset-cells: should be 1.
|
||||
|
||||
Optional Properties:
|
||||
|
||||
- rockchip,grf: phandle to the syscon managing the "general register files"
|
||||
If missing pll rates are not changeable, due to the missing pll lock status.
|
||||
|
||||
Each clock is assigned an identifier and client nodes can use this identifier
|
||||
to specify the clock which they consume. All available clocks are defined as
|
||||
preprocessor macros in the dt-bindings/clock/rk3036-cru.h headers and can be
|
||||
used in device tree sources. Similar macros exist for the reset sources in
|
||||
these files.
|
||||
|
||||
External clocks:
|
||||
|
||||
There are several clocks that are generated outside the SoC. It is expected
|
||||
that they are defined using standard clock bindings with following
|
||||
clock-output-names:
|
||||
- "xin24m" - crystal input - required,
|
||||
- "ext_i2s" - external I2S clock - optional,
|
||||
- "ext_gmac" - external GMAC clock - optional
|
||||
|
||||
Example: Clock controller node:
|
||||
|
||||
cru: cru@20000000 {
|
||||
compatible = "rockchip,rk3036-cru";
|
||||
reg = <0x20000000 0x1000>;
|
||||
rockchip,grf = <&grf>;
|
||||
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
|
||||
Example: UART controller node that consumes the clock generated by the clock
|
||||
controller:
|
||||
|
||||
uart0: serial@20060000 {
|
||||
compatible = "snps,dw-apb-uart";
|
||||
reg = <0x20060000 0x100>;
|
||||
interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
|
||||
reg-shift = <2>;
|
||||
reg-io-width = <4>;
|
||||
clocks = <&cru SCLK_UART0>;
|
||||
};
|
@ -0,0 +1,58 @@
|
||||
* Rockchip RK3228 Clock and Reset Unit
|
||||
|
||||
The RK3228 clock controller generates and supplies clock to various
|
||||
controllers within the SoC and also implements a reset controller for SoC
|
||||
peripherals.
|
||||
|
||||
Required Properties:
|
||||
|
||||
- compatible: should be "rockchip,rk3228-cru"
|
||||
- reg: physical base address of the controller and length of memory mapped
|
||||
region.
|
||||
- #clock-cells: should be 1.
|
||||
- #reset-cells: should be 1.
|
||||
|
||||
Optional Properties:
|
||||
|
||||
- rockchip,grf: phandle to the syscon managing the "general register files"
|
||||
If missing pll rates are not changeable, due to the missing pll lock status.
|
||||
|
||||
Each clock is assigned an identifier and client nodes can use this identifier
|
||||
to specify the clock which they consume. All available clocks are defined as
|
||||
preprocessor macros in the dt-bindings/clock/rk3228-cru.h headers and can be
|
||||
used in device tree sources. Similar macros exist for the reset sources in
|
||||
these files.
|
||||
|
||||
External clocks:
|
||||
|
||||
There are several clocks that are generated outside the SoC. It is expected
|
||||
that they are defined using standard clock bindings with following
|
||||
clock-output-names:
|
||||
- "xin24m" - crystal input - required,
|
||||
- "ext_i2s" - external I2S clock - optional,
|
||||
- "ext_gmac" - external GMAC clock - optional
|
||||
- "ext_hsadc" - external HSADC clock - optional
|
||||
- "phy_50m_out" - output clock of the pll in the mac phy
|
||||
|
||||
Example: Clock controller node:
|
||||
|
||||
cru: cru@20000000 {
|
||||
compatible = "rockchip,rk3228-cru";
|
||||
reg = <0x20000000 0x1000>;
|
||||
rockchip,grf = <&grf>;
|
||||
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
|
||||
Example: UART controller node that consumes the clock generated by the clock
|
||||
controller:
|
||||
|
||||
uart0: serial@10110000 {
|
||||
compatible = "snps,dw-apb-uart";
|
||||
reg = <0x10110000 0x100>;
|
||||
interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
|
||||
reg-shift = <2>;
|
||||
reg-io-width = <4>;
|
||||
clocks = <&cru SCLK_UART0>;
|
||||
};
|
23
Documentation/devicetree/bindings/clock/tango4-clock.txt
Normal file
23
Documentation/devicetree/bindings/clock/tango4-clock.txt
Normal file
@ -0,0 +1,23 @@
|
||||
* Sigma Designs Tango4 Clock Generator
|
||||
|
||||
The Tango4 clock generator outputs cpu_clk and sys_clk (the latter is used
|
||||
for RAM and various peripheral devices). The clock binding described here
|
||||
is applicable to all Tango4 SoCs.
|
||||
|
||||
Required Properties:
|
||||
|
||||
- compatible: should be "sigma,tango4-clkgen".
|
||||
- reg: physical base address of the device and length of memory mapped region.
|
||||
- clocks: phandle of the input clock (crystal oscillator).
|
||||
- clock-output-names: should be "cpuclk" and "sysclk".
|
||||
- #clock-cells: should be set to 1.
|
||||
|
||||
Example:
|
||||
|
||||
clkgen: clkgen@10000 {
|
||||
compatible = "sigma,tango4-clkgen";
|
||||
reg = <0x10000 0x40>;
|
||||
clocks = <&xtal>;
|
||||
clock-output-names = "cpuclk", "sysclk";
|
||||
#clock-cells = <1>;
|
||||
};
|
@ -225,5 +225,9 @@ void __init ti_clk_init_features(void)
|
||||
if (omap_rev() == OMAP3430_REV_ES1_0)
|
||||
features.flags |= TI_CLK_DPLL4_DENY_REPROGRAM;
|
||||
|
||||
/* Errata I810 for omap5 / dra7 */
|
||||
if (soc_is_omap54xx() || soc_is_dra7xx())
|
||||
features.flags |= TI_CLK_ERRATA_I810;
|
||||
|
||||
ti_clk_setup_features(&features);
|
||||
}
|
||||
|
@ -116,6 +116,12 @@ config COMMON_CLK_CDCE925
|
||||
Given a target output frequency, the driver will set the PLL and
|
||||
divider to best approximate the desired output.
|
||||
|
||||
config COMMON_CLK_CS2000_CP
|
||||
tristate "Clock driver for CS2000 Fractional-N Clock Synthesizer & Clock Multiplier"
|
||||
depends on I2C
|
||||
help
|
||||
If you say yes here you get support for the CS2000 clock multiplier.
|
||||
|
||||
config COMMON_CLK_S2MPS11
|
||||
tristate "Clock driver for S2MPS1X/S5M8767 MFD"
|
||||
depends on MFD_SEC_CORE
|
||||
|
@ -21,6 +21,7 @@ obj-$(CONFIG_MACH_ASM9260) += clk-asm9260.o
|
||||
obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN) += clk-axi-clkgen.o
|
||||
obj-$(CONFIG_ARCH_AXXIA) += clk-axm5516.o
|
||||
obj-$(CONFIG_COMMON_CLK_CDCE706) += clk-cdce706.o
|
||||
obj-$(CONFIG_COMMON_CLK_CS2000_CP) += clk-cs2000-cp.o
|
||||
obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o
|
||||
obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o
|
||||
obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o
|
||||
@ -42,6 +43,7 @@ obj-$(CONFIG_COMMON_CLK_SI514) += clk-si514.o
|
||||
obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o
|
||||
obj-$(CONFIG_COMMON_CLK_CDCE925) += clk-cdce925.o
|
||||
obj-$(CONFIG_ARCH_STM32) += clk-stm32f4.o
|
||||
obj-$(CONFIG_ARCH_TANGOX) += clk-tango4.o
|
||||
obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o
|
||||
obj-$(CONFIG_ARCH_U300) += clk-u300.o
|
||||
obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o
|
||||
@ -69,6 +71,7 @@ obj-$(CONFIG_COMMON_CLK_QCOM) += qcom/
|
||||
obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
|
||||
obj-$(CONFIG_COMMON_CLK_SAMSUNG) += samsung/
|
||||
obj-$(CONFIG_ARCH_SHMOBILE_MULTI) += shmobile/
|
||||
obj-$(CONFIG_ARCH_RENESAS) += shmobile/
|
||||
obj-$(CONFIG_ARCH_SIRF) += sirf/
|
||||
obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/
|
||||
obj-$(CONFIG_PLAT_SPEAR) += spear/
|
||||
|
@ -10,7 +10,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/slab.h>
|
||||
@ -72,8 +71,6 @@ struct clk_sam9x5_slow {
|
||||
|
||||
#define to_clk_sam9x5_slow(hw) container_of(hw, struct clk_sam9x5_slow, hw)
|
||||
|
||||
static struct clk *slow_clk;
|
||||
|
||||
static int clk_slow_osc_prepare(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_slow_osc *osc = to_clk_slow_osc(hw);
|
||||
@ -360,8 +357,6 @@ at91_clk_register_sam9x5_slow(void __iomem *sckcr,
|
||||
clk = clk_register(NULL, &slowck->hw);
|
||||
if (IS_ERR(clk))
|
||||
kfree(slowck);
|
||||
else
|
||||
slow_clk = clk;
|
||||
|
||||
return clk;
|
||||
}
|
||||
@ -433,8 +428,6 @@ at91_clk_register_sam9260_slow(struct at91_pmc *pmc,
|
||||
clk = clk_register(NULL, &slowck->hw);
|
||||
if (IS_ERR(clk))
|
||||
kfree(slowck);
|
||||
else
|
||||
slow_clk = clk;
|
||||
|
||||
return clk;
|
||||
}
|
||||
@ -462,25 +455,3 @@ void __init of_at91sam9260_clk_slow_setup(struct device_node *np,
|
||||
|
||||
of_clk_add_provider(np, of_clk_src_simple_get, clk);
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: All slow clk users are not properly claiming it (get + prepare +
|
||||
* enable) before using it.
|
||||
* If all users properly claiming this clock decide that they don't need it
|
||||
* anymore (or are removed), it is disabled while faulty users are still
|
||||
* requiring it, and the system hangs.
|
||||
* Prevent this clock from being disabled until all users are properly
|
||||
* requesting it.
|
||||
* Once this is done we should remove this function and the slow_clk variable.
|
||||
*/
|
||||
static int __init of_at91_clk_slow_retain(void)
|
||||
{
|
||||
if (!slow_clk)
|
||||
return 0;
|
||||
|
||||
__clk_get(slow_clk);
|
||||
clk_prepare_enable(slow_clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(of_at91_clk_slow_retain);
|
||||
|
@ -1,3 +1,13 @@
|
||||
config CLK_BCM_63XX
|
||||
bool "Broadcom BCM63xx clock support"
|
||||
depends on ARCH_BCM_63XX || COMPILE_TEST
|
||||
depends on COMMON_CLK
|
||||
select COMMON_CLK_IPROC
|
||||
default ARCH_BCM_63XX
|
||||
help
|
||||
Enable common clock framework support for Broadcom BCM63xx DSL SoCs
|
||||
based on the ARM architecture
|
||||
|
||||
config CLK_BCM_KONA
|
||||
bool "Broadcom Kona CCU clock support"
|
||||
depends on ARCH_BCM_MOBILE || COMPILE_TEST
|
||||
|
@ -1,3 +1,4 @@
|
||||
obj-$(CONFIG_CLK_BCM_63XX) += clk-bcm63xx.o
|
||||
obj-$(CONFIG_CLK_BCM_KONA) += clk-kona.o
|
||||
obj-$(CONFIG_CLK_BCM_KONA) += clk-kona-setup.o
|
||||
obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281xx.o
|
||||
|
22
drivers/clk/bcm/clk-bcm63xx.c
Normal file
22
drivers/clk/bcm/clk-bcm63xx.c
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Broadcom Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation version 2.
|
||||
*
|
||||
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
|
||||
* kind, whether express or implied; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/of.h>
|
||||
#include "clk-iproc.h"
|
||||
|
||||
static void __init bcm63138_armpll_init(struct device_node *node)
|
||||
{
|
||||
iproc_armpll_setup(node);
|
||||
}
|
||||
CLK_OF_DECLARE(bcm63138_armpll, "brcm,bcm63138-armpll", bcm63138_armpll_init);
|
510
drivers/clk/clk-cs2000-cp.c
Normal file
510
drivers/clk/clk-cs2000-cp.c
Normal file
@ -0,0 +1,510 @@
|
||||
/*
|
||||
* CS2000 -- CIRRUS LOGIC Fractional-N Clock Synthesizer & Clock Multiplier
|
||||
*
|
||||
* Copyright (C) 2015 Renesas Electronics Corporation
|
||||
* Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#define CH_MAX 4
|
||||
#define RATIO_REG_SIZE 4
|
||||
|
||||
#define DEVICE_ID 0x1
|
||||
#define DEVICE_CTRL 0x2
|
||||
#define DEVICE_CFG1 0x3
|
||||
#define DEVICE_CFG2 0x4
|
||||
#define GLOBAL_CFG 0x5
|
||||
#define Ratio_Add(x, nth) (6 + (x * 4) + (nth))
|
||||
#define Ratio_Val(x, nth) ((x >> (24 - (8 * nth))) & 0xFF)
|
||||
#define Val_Ratio(x, nth) ((x & 0xFF) << (24 - (8 * nth)))
|
||||
#define FUNC_CFG1 0x16
|
||||
#define FUNC_CFG2 0x17
|
||||
|
||||
/* DEVICE_ID */
|
||||
#define REVISION_MASK (0x7)
|
||||
#define REVISION_B2_B3 (0x4)
|
||||
#define REVISION_C1 (0x6)
|
||||
|
||||
/* DEVICE_CTRL */
|
||||
#define PLL_UNLOCK (1 << 7)
|
||||
|
||||
/* DEVICE_CFG1 */
|
||||
#define RSEL(x) (((x) & 0x3) << 3)
|
||||
#define RSEL_MASK RSEL(0x3)
|
||||
#define ENDEV1 (0x1)
|
||||
|
||||
/* GLOBAL_CFG */
|
||||
#define ENDEV2 (0x1)
|
||||
|
||||
#define CH_SIZE_ERR(ch) ((ch < 0) || (ch >= CH_MAX))
|
||||
#define hw_to_priv(_hw) container_of(_hw, struct cs2000_priv, hw)
|
||||
#define priv_to_client(priv) (priv->client)
|
||||
#define priv_to_dev(priv) (&(priv_to_client(priv)->dev))
|
||||
|
||||
#define CLK_IN 0
|
||||
#define REF_CLK 1
|
||||
#define CLK_MAX 2
|
||||
|
||||
struct cs2000_priv {
|
||||
struct clk_hw hw;
|
||||
struct i2c_client *client;
|
||||
struct clk *clk_in;
|
||||
struct clk *ref_clk;
|
||||
struct clk *clk_out;
|
||||
};
|
||||
|
||||
static const struct of_device_id cs2000_of_match[] = {
|
||||
{ .compatible = "cirrus,cs2000-cp", },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, cs2000_of_match);
|
||||
|
||||
static const struct i2c_device_id cs2000_id[] = {
|
||||
{ "cs2000-cp", },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, cs2000_id);
|
||||
|
||||
#define cs2000_read(priv, addr) \
|
||||
i2c_smbus_read_byte_data(priv_to_client(priv), addr)
|
||||
#define cs2000_write(priv, addr, val) \
|
||||
i2c_smbus_write_byte_data(priv_to_client(priv), addr, val)
|
||||
|
||||
static int cs2000_bset(struct cs2000_priv *priv, u8 addr, u8 mask, u8 val)
|
||||
{
|
||||
s32 data;
|
||||
|
||||
data = cs2000_read(priv, addr);
|
||||
if (data < 0)
|
||||
return data;
|
||||
|
||||
data &= ~mask;
|
||||
data |= (val & mask);
|
||||
|
||||
return cs2000_write(priv, addr, data);
|
||||
}
|
||||
|
||||
static int cs2000_enable_dev_config(struct cs2000_priv *priv, bool enable)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = cs2000_bset(priv, DEVICE_CFG1, ENDEV1,
|
||||
enable ? ENDEV1 : 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = cs2000_bset(priv, GLOBAL_CFG, ENDEV2,
|
||||
enable ? ENDEV2 : 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cs2000_clk_in_bound_rate(struct cs2000_priv *priv,
|
||||
u32 rate_in)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
if (rate_in >= 32000000 && rate_in < 56000000)
|
||||
val = 0x0;
|
||||
else if (rate_in >= 16000000 && rate_in < 28000000)
|
||||
val = 0x1;
|
||||
else if (rate_in >= 8000000 && rate_in < 14000000)
|
||||
val = 0x2;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
return cs2000_bset(priv, FUNC_CFG1, 0x3 << 3, val << 3);
|
||||
}
|
||||
|
||||
static int cs2000_wait_pll_lock(struct cs2000_priv *priv)
|
||||
{
|
||||
struct device *dev = priv_to_dev(priv);
|
||||
s32 val;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
val = cs2000_read(priv, DEVICE_CTRL);
|
||||
if (val < 0)
|
||||
return val;
|
||||
if (!(val & PLL_UNLOCK))
|
||||
return 0;
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
dev_err(dev, "pll lock failed\n");
|
||||
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static int cs2000_clk_out_enable(struct cs2000_priv *priv, bool enable)
|
||||
{
|
||||
/* enable both AUX_OUT, CLK_OUT */
|
||||
return cs2000_write(priv, DEVICE_CTRL, enable ? 0 : 0x3);
|
||||
}
|
||||
|
||||
static u32 cs2000_rate_to_ratio(u32 rate_in, u32 rate_out)
|
||||
{
|
||||
u64 ratio;
|
||||
|
||||
/*
|
||||
* ratio = rate_out / rate_in * 2^20
|
||||
*
|
||||
* To avoid over flow, rate_out is u64.
|
||||
* The result should be u32.
|
||||
*/
|
||||
ratio = (u64)rate_out << 20;
|
||||
do_div(ratio, rate_in);
|
||||
|
||||
return ratio;
|
||||
}
|
||||
|
||||
static unsigned long cs2000_ratio_to_rate(u32 ratio, u32 rate_in)
|
||||
{
|
||||
u64 rate_out;
|
||||
|
||||
/*
|
||||
* ratio = rate_out / rate_in * 2^20
|
||||
*
|
||||
* To avoid over flow, rate_out is u64.
|
||||
* The result should be u32 or unsigned long.
|
||||
*/
|
||||
|
||||
rate_out = (u64)ratio * rate_in;
|
||||
return rate_out >> 20;
|
||||
}
|
||||
|
||||
static int cs2000_ratio_set(struct cs2000_priv *priv,
|
||||
int ch, u32 rate_in, u32 rate_out)
|
||||
{
|
||||
u32 val;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
if (CH_SIZE_ERR(ch))
|
||||
return -EINVAL;
|
||||
|
||||
val = cs2000_rate_to_ratio(rate_in, rate_out);
|
||||
for (i = 0; i < RATIO_REG_SIZE; i++) {
|
||||
ret = cs2000_write(priv,
|
||||
Ratio_Add(ch, i),
|
||||
Ratio_Val(val, i));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 cs2000_ratio_get(struct cs2000_priv *priv, int ch)
|
||||
{
|
||||
s32 tmp;
|
||||
u32 val;
|
||||
unsigned int i;
|
||||
|
||||
val = 0;
|
||||
for (i = 0; i < RATIO_REG_SIZE; i++) {
|
||||
tmp = cs2000_read(priv, Ratio_Add(ch, i));
|
||||
if (tmp < 0)
|
||||
return 0;
|
||||
|
||||
val |= Val_Ratio(tmp, i);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static int cs2000_ratio_select(struct cs2000_priv *priv, int ch)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (CH_SIZE_ERR(ch))
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* FIXME
|
||||
*
|
||||
* this driver supports static ratio mode only at this point.
|
||||
*/
|
||||
ret = cs2000_bset(priv, DEVICE_CFG1, RSEL_MASK, RSEL(ch));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = cs2000_write(priv, DEVICE_CFG2, 0x0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned long cs2000_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct cs2000_priv *priv = hw_to_priv(hw);
|
||||
int ch = 0; /* it uses ch0 only at this point */
|
||||
u32 ratio;
|
||||
|
||||
ratio = cs2000_ratio_get(priv, ch);
|
||||
|
||||
return cs2000_ratio_to_rate(ratio, parent_rate);
|
||||
}
|
||||
|
||||
static long cs2000_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *parent_rate)
|
||||
{
|
||||
u32 ratio;
|
||||
|
||||
ratio = cs2000_rate_to_ratio(*parent_rate, rate);
|
||||
|
||||
return cs2000_ratio_to_rate(ratio, *parent_rate);
|
||||
}
|
||||
|
||||
static int __cs2000_set_rate(struct cs2000_priv *priv, int ch,
|
||||
unsigned long rate, unsigned long parent_rate)
|
||||
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = cs2000_clk_in_bound_rate(priv, parent_rate);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = cs2000_ratio_set(priv, ch, parent_rate, rate);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = cs2000_ratio_select(priv, ch);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cs2000_set_rate(struct clk_hw *hw,
|
||||
unsigned long rate, unsigned long parent_rate)
|
||||
{
|
||||
struct cs2000_priv *priv = hw_to_priv(hw);
|
||||
int ch = 0; /* it uses ch0 only at this point */
|
||||
|
||||
return __cs2000_set_rate(priv, ch, rate, parent_rate);
|
||||
}
|
||||
|
||||
static int cs2000_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct cs2000_priv *priv = hw_to_priv(hw);
|
||||
int ret;
|
||||
|
||||
ret = cs2000_enable_dev_config(priv, true);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = cs2000_clk_out_enable(priv, true);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = cs2000_wait_pll_lock(priv);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void cs2000_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct cs2000_priv *priv = hw_to_priv(hw);
|
||||
|
||||
cs2000_enable_dev_config(priv, false);
|
||||
|
||||
cs2000_clk_out_enable(priv, false);
|
||||
}
|
||||
|
||||
static u8 cs2000_get_parent(struct clk_hw *hw)
|
||||
{
|
||||
/* always return REF_CLK */
|
||||
return REF_CLK;
|
||||
}
|
||||
|
||||
static const struct clk_ops cs2000_ops = {
|
||||
.get_parent = cs2000_get_parent,
|
||||
.recalc_rate = cs2000_recalc_rate,
|
||||
.round_rate = cs2000_round_rate,
|
||||
.set_rate = cs2000_set_rate,
|
||||
.prepare = cs2000_enable,
|
||||
.unprepare = cs2000_disable,
|
||||
};
|
||||
|
||||
static int cs2000_clk_get(struct cs2000_priv *priv)
|
||||
{
|
||||
struct i2c_client *client = priv_to_client(priv);
|
||||
struct device *dev = &client->dev;
|
||||
struct clk *clk_in, *ref_clk;
|
||||
|
||||
clk_in = devm_clk_get(dev, "clk_in");
|
||||
/* not yet provided */
|
||||
if (IS_ERR(clk_in))
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
ref_clk = devm_clk_get(dev, "ref_clk");
|
||||
/* not yet provided */
|
||||
if (IS_ERR(ref_clk))
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
priv->clk_in = clk_in;
|
||||
priv->ref_clk = ref_clk;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cs2000_clk_register(struct cs2000_priv *priv)
|
||||
{
|
||||
struct device *dev = priv_to_dev(priv);
|
||||
struct device_node *np = dev->of_node;
|
||||
struct clk_init_data init;
|
||||
const char *name = np->name;
|
||||
struct clk *clk;
|
||||
static const char *parent_names[CLK_MAX];
|
||||
int ch = 0; /* it uses ch0 only at this point */
|
||||
int rate;
|
||||
int ret;
|
||||
|
||||
of_property_read_string(np, "clock-output-names", &name);
|
||||
|
||||
/*
|
||||
* set default rate as 1/1.
|
||||
* otherwise .set_rate which setup ratio
|
||||
* is never called if user requests 1/1 rate
|
||||
*/
|
||||
rate = clk_get_rate(priv->ref_clk);
|
||||
ret = __cs2000_set_rate(priv, ch, rate, rate);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
parent_names[CLK_IN] = __clk_get_name(priv->clk_in);
|
||||
parent_names[REF_CLK] = __clk_get_name(priv->ref_clk);
|
||||
|
||||
init.name = name;
|
||||
init.ops = &cs2000_ops;
|
||||
init.flags = CLK_SET_RATE_GATE;
|
||||
init.parent_names = parent_names;
|
||||
init.num_parents = ARRAY_SIZE(parent_names);
|
||||
|
||||
priv->hw.init = &init;
|
||||
|
||||
clk = clk_register(dev, &priv->hw);
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
|
||||
ret = of_clk_add_provider(np, of_clk_src_simple_get, clk);
|
||||
if (ret < 0) {
|
||||
clk_unregister(clk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
priv->clk_out = clk;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cs2000_version_print(struct cs2000_priv *priv)
|
||||
{
|
||||
struct i2c_client *client = priv_to_client(priv);
|
||||
struct device *dev = &client->dev;
|
||||
s32 val;
|
||||
const char *revision;
|
||||
|
||||
val = cs2000_read(priv, DEVICE_ID);
|
||||
if (val < 0)
|
||||
return val;
|
||||
|
||||
/* CS2000 should be 0x0 */
|
||||
if (val >> 3)
|
||||
return -EIO;
|
||||
|
||||
switch (val & REVISION_MASK) {
|
||||
case REVISION_B2_B3:
|
||||
revision = "B2 / B3";
|
||||
break;
|
||||
case REVISION_C1:
|
||||
revision = "C1";
|
||||
break;
|
||||
default:
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
dev_info(dev, "revision - %s\n", revision);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cs2000_remove(struct i2c_client *client)
|
||||
{
|
||||
struct cs2000_priv *priv = i2c_get_clientdata(client);
|
||||
struct device *dev = &client->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
|
||||
of_clk_del_provider(np);
|
||||
|
||||
clk_unregister(priv->clk_out);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cs2000_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct cs2000_priv *priv;
|
||||
struct device *dev = &client->dev;
|
||||
int ret;
|
||||
|
||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->client = client;
|
||||
i2c_set_clientdata(client, priv);
|
||||
|
||||
ret = cs2000_clk_get(priv);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = cs2000_clk_register(priv);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = cs2000_version_print(priv);
|
||||
if (ret < 0)
|
||||
goto probe_err;
|
||||
|
||||
return 0;
|
||||
|
||||
probe_err:
|
||||
cs2000_remove(client);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct i2c_driver cs2000_driver = {
|
||||
.driver = {
|
||||
.name = "cs2000-cp",
|
||||
.of_match_table = cs2000_of_match,
|
||||
},
|
||||
.probe = cs2000_probe,
|
||||
.remove = cs2000_remove,
|
||||
.id_table = cs2000_id,
|
||||
};
|
||||
|
||||
module_i2c_driver(cs2000_driver);
|
||||
|
||||
MODULE_DESCRIPTION("CS2000-CP driver");
|
||||
MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -32,13 +32,14 @@
|
||||
|
||||
#define div_mask(width) ((1 << (width)) - 1)
|
||||
|
||||
static unsigned int _get_table_maxdiv(const struct clk_div_table *table)
|
||||
static unsigned int _get_table_maxdiv(const struct clk_div_table *table,
|
||||
u8 width)
|
||||
{
|
||||
unsigned int maxdiv = 0;
|
||||
unsigned int maxdiv = 0, mask = div_mask(width);
|
||||
const struct clk_div_table *clkt;
|
||||
|
||||
for (clkt = table; clkt->div; clkt++)
|
||||
if (clkt->div > maxdiv)
|
||||
if (clkt->div > maxdiv && clkt->val <= mask)
|
||||
maxdiv = clkt->div;
|
||||
return maxdiv;
|
||||
}
|
||||
@ -62,7 +63,7 @@ static unsigned int _get_maxdiv(const struct clk_div_table *table, u8 width,
|
||||
if (flags & CLK_DIVIDER_POWER_OF_TWO)
|
||||
return 1 << div_mask(width);
|
||||
if (table)
|
||||
return _get_table_maxdiv(table);
|
||||
return _get_table_maxdiv(table, width);
|
||||
return div_mask(width) + 1;
|
||||
}
|
||||
|
||||
|
@ -71,10 +71,9 @@ static int clk_mux_set_parent(struct clk_hw *hw, u8 index)
|
||||
u32 val;
|
||||
unsigned long flags = 0;
|
||||
|
||||
if (mux->table)
|
||||
if (mux->table) {
|
||||
index = mux->table[index];
|
||||
|
||||
else {
|
||||
} else {
|
||||
if (mux->flags & CLK_MUX_INDEX_BIT)
|
||||
index = 1 << index;
|
||||
|
||||
|
@ -1091,6 +1091,13 @@ static int si5351_clkout_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
si5351_set_bits(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num,
|
||||
SI5351_CLK_POWERDOWN, 0);
|
||||
|
||||
/*
|
||||
* Do a pll soft reset on both plls, needed in some cases to get
|
||||
* all outputs running.
|
||||
*/
|
||||
si5351_reg_write(hwdata->drvdata, SI5351_PLL_RESET,
|
||||
SI5351_PLL_RESET_A | SI5351_PLL_RESET_B);
|
||||
|
||||
dev_dbg(&hwdata->drvdata->client->dev,
|
||||
"%s - %s: rdiv = %u, parent_rate = %lu, rate = %lu\n",
|
||||
__func__, clk_hw_get_name(hw), (1 << rdiv),
|
||||
|
61
drivers/clk/clk-tango4.c
Normal file
61
drivers/clk/clk-tango4.c
Normal file
@ -0,0 +1,61 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
static struct clk *out[2];
|
||||
static struct clk_onecell_data clk_data = { out, 2 };
|
||||
|
||||
#define SYSCLK_CTRL 0x20
|
||||
#define CPUCLK_CTRL 0x24
|
||||
#define LEGACY_DIV 0x3c
|
||||
|
||||
#define PLL_N(val) (((val) >> 0) & 0x7f)
|
||||
#define PLL_K(val) (((val) >> 13) & 0x7)
|
||||
#define PLL_M(val) (((val) >> 16) & 0x7)
|
||||
#define DIV_INDEX(val) (((val) >> 8) & 0xf)
|
||||
|
||||
static void __init make_pll(int idx, const char *parent, void __iomem *base)
|
||||
{
|
||||
char name[8];
|
||||
u32 val, mul, div;
|
||||
|
||||
sprintf(name, "pll%d", idx);
|
||||
val = readl_relaxed(base + idx*8);
|
||||
mul = PLL_N(val) + 1;
|
||||
div = (PLL_M(val) + 1) << PLL_K(val);
|
||||
clk_register_fixed_factor(NULL, name, parent, 0, mul, div);
|
||||
}
|
||||
|
||||
static int __init get_div(void __iomem *base)
|
||||
{
|
||||
u8 sysclk_tab[16] = { 2, 4, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4 };
|
||||
int idx = DIV_INDEX(readl_relaxed(base + LEGACY_DIV));
|
||||
|
||||
return sysclk_tab[idx];
|
||||
}
|
||||
|
||||
static void __init tango4_clkgen_setup(struct device_node *np)
|
||||
{
|
||||
int div, ret;
|
||||
void __iomem *base = of_iomap(np, 0);
|
||||
const char *parent = of_clk_get_parent_name(np, 0);
|
||||
|
||||
if (!base)
|
||||
panic("%s: invalid address\n", np->full_name);
|
||||
|
||||
make_pll(0, parent, base);
|
||||
make_pll(1, parent, base);
|
||||
|
||||
out[0] = clk_register_divider(NULL, "cpuclk", "pll0", 0,
|
||||
base + CPUCLK_CTRL, 8, 8, CLK_DIVIDER_ONE_BASED, NULL);
|
||||
|
||||
div = readl_relaxed(base + SYSCLK_CTRL) & BIT(23) ? get_div(base) : 4;
|
||||
out[1] = clk_register_fixed_factor(NULL, "sysclk", "pll1", 0, 1, div);
|
||||
|
||||
ret = of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
|
||||
if (IS_ERR(out[0]) || IS_ERR(out[1]) || ret < 0)
|
||||
panic("%s: clk registration failed\n", np->full_name);
|
||||
}
|
||||
CLK_OF_DECLARE(tango4_clkgen, "sigma,tango4-clkgen", tango4_clkgen_setup);
|
@ -351,7 +351,8 @@ static int xgene_clk_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
/* Set new divider */
|
||||
data = xgene_clk_read(pclk->param.divider_reg +
|
||||
pclk->param.reg_divider_offset);
|
||||
data &= ~((1 << pclk->param.reg_divider_width) - 1);
|
||||
data &= ~((1 << pclk->param.reg_divider_width) - 1)
|
||||
<< pclk->param.reg_divider_shift;
|
||||
data |= divider;
|
||||
xgene_clk_write(data, pclk->param.divider_reg +
|
||||
pclk->param.reg_divider_offset);
|
||||
|
@ -1944,7 +1944,7 @@ bool clk_is_match(const struct clk *p, const struct clk *q)
|
||||
if (p == q)
|
||||
return true;
|
||||
|
||||
/* true if clk->core pointers match. Avoid derefing garbage */
|
||||
/* true if clk->core pointers match. Avoid dereferencing garbage */
|
||||
if (!IS_ERR_OR_NULL(p) && !IS_ERR_OR_NULL(q))
|
||||
if (p->core == q->core)
|
||||
return true;
|
||||
@ -2482,7 +2482,7 @@ struct clk *__clk_create_clk(struct clk_hw *hw, const char *dev_id,
|
||||
struct clk *clk;
|
||||
|
||||
/* This is to allow this function to be chained to others */
|
||||
if (!hw || IS_ERR(hw))
|
||||
if (IS_ERR_OR_NULL(hw))
|
||||
return (struct clk *) hw;
|
||||
|
||||
clk = kzalloc(sizeof(*clk), GFP_KERNEL);
|
||||
@ -2806,10 +2806,9 @@ void __clk_put(struct clk *clk)
|
||||
* re-enter into the clk framework by calling any top-level clk APIs;
|
||||
* this will cause a nested prepare_lock mutex.
|
||||
*
|
||||
* In all notification cases cases (pre, post and abort rate change) the
|
||||
* original clock rate is passed to the callback via struct
|
||||
* clk_notifier_data.old_rate and the new frequency is passed via struct
|
||||
* clk_notifier_data.new_rate.
|
||||
* In all notification cases (pre, post and abort rate change) the original
|
||||
* clock rate is passed to the callback via struct clk_notifier_data.old_rate
|
||||
* and the new frequency is passed via struct clk_notifier_data.new_rate.
|
||||
*
|
||||
* clk_notifier_register() must be called from non-atomic context.
|
||||
* Returns -EINVAL if called with null arguments, -ENOMEM upon
|
||||
@ -3062,9 +3061,6 @@ const char *of_clk_get_parent_name(struct device_node *np, int index)
|
||||
int count;
|
||||
struct clk *clk;
|
||||
|
||||
if (index < 0)
|
||||
return NULL;
|
||||
|
||||
rc = of_parse_phandle_with_args(np, "clocks", "#clock-cells", index,
|
||||
&clkspec);
|
||||
if (rc)
|
||||
@ -3083,6 +3079,9 @@ const char *of_clk_get_parent_name(struct device_node *np, int index)
|
||||
}
|
||||
count++;
|
||||
}
|
||||
/* We went off the end of 'clock-indices' without finding it */
|
||||
if (prop && !vp)
|
||||
return NULL;
|
||||
|
||||
if (of_property_read_string_index(clkspec.np, "clock-output-names",
|
||||
index,
|
||||
|
@ -96,13 +96,11 @@ static struct clk ** const uart_clks[] __initconst = {
|
||||
NULL
|
||||
};
|
||||
|
||||
static int __init __mx25_clocks_init(unsigned long osc_rate,
|
||||
void __iomem *ccm_base)
|
||||
static int __init __mx25_clocks_init(void __iomem *ccm_base)
|
||||
{
|
||||
BUG_ON(!ccm_base);
|
||||
|
||||
clk[dummy] = imx_clk_fixed("dummy", 0);
|
||||
clk[osc] = imx_clk_fixed("osc", osc_rate);
|
||||
clk[mpll] = imx_clk_pllv1(IMX_PLLV1_IMX25, "mpll", "osc", ccm(CCM_MPCTL));
|
||||
clk[upll] = imx_clk_pllv1(IMX_PLLV1_IMX25, "upll", "osc", ccm(CCM_UPCTL));
|
||||
clk[mpll_cpu_3_4] = imx_clk_fixed_factor("mpll_cpu_3_4", "mpll", 3, 4);
|
||||
@ -250,22 +248,10 @@ static int __init __mx25_clocks_init(unsigned long osc_rate,
|
||||
|
||||
static void __init mx25_clocks_init_dt(struct device_node *np)
|
||||
{
|
||||
struct device_node *refnp;
|
||||
unsigned long osc_rate = 24000000;
|
||||
void __iomem *ccm;
|
||||
|
||||
/* retrieve the freqency of fixed clocks from device tree */
|
||||
for_each_compatible_node(refnp, NULL, "fixed-clock") {
|
||||
u32 rate;
|
||||
if (of_property_read_u32(refnp, "clock-frequency", &rate))
|
||||
continue;
|
||||
|
||||
if (of_device_is_compatible(refnp, "fsl,imx-osc"))
|
||||
osc_rate = rate;
|
||||
}
|
||||
|
||||
ccm = of_iomap(np, 0);
|
||||
__mx25_clocks_init(osc_rate, ccm);
|
||||
__mx25_clocks_init(ccm);
|
||||
|
||||
clk_data.clks = clk;
|
||||
clk_data.clk_num = ARRAY_SIZE(clk);
|
||||
|
@ -519,10 +519,10 @@ static void __init mx53_clocks_init(struct device_node *np)
|
||||
mx53_ldb_di0_sel, ARRAY_SIZE(mx53_ldb_di0_sel), CLK_SET_RATE_PARENT);
|
||||
clk[IMX5_CLK_LDB_DI0_GATE] = imx_clk_gate2("ldb_di0_gate", "ldb_di0_div", MXC_CCM_CCGR6, 28);
|
||||
clk[IMX5_CLK_LDB_DI1_GATE] = imx_clk_gate2("ldb_di1_gate", "ldb_di1_div", MXC_CCM_CCGR6, 30);
|
||||
clk[IMX5_CLK_IPU_DI0_SEL] = imx_clk_mux("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3,
|
||||
mx53_ipu_di0_sel, ARRAY_SIZE(mx53_ipu_di0_sel));
|
||||
clk[IMX5_CLK_IPU_DI1_SEL] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3,
|
||||
mx53_ipu_di1_sel, ARRAY_SIZE(mx53_ipu_di1_sel));
|
||||
clk[IMX5_CLK_IPU_DI0_SEL] = imx_clk_mux_flags("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3,
|
||||
mx53_ipu_di0_sel, ARRAY_SIZE(mx53_ipu_di0_sel), CLK_SET_RATE_PARENT);
|
||||
clk[IMX5_CLK_IPU_DI1_SEL] = imx_clk_mux_flags("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3,
|
||||
mx53_ipu_di1_sel, ARRAY_SIZE(mx53_ipu_di1_sel), CLK_SET_RATE_PARENT);
|
||||
clk[IMX5_CLK_TVE_EXT_SEL] = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1,
|
||||
mx53_tve_ext_sel, ARRAY_SIZE(mx53_tve_ext_sel), CLK_SET_RATE_PARENT);
|
||||
clk[IMX5_CLK_TVE_GATE] = imx_clk_gate2("tve_gate", "tve_pred", MXC_CCM_CCGR2, 30);
|
||||
|
@ -70,7 +70,8 @@ static const char *cko_sels[] = { "cko1", "cko2", };
|
||||
static const char *lvds_sels[] = {
|
||||
"dummy", "dummy", "dummy", "dummy", "dummy", "dummy",
|
||||
"pll4_audio", "pll5_video", "pll8_mlb", "enet_ref",
|
||||
"pcie_ref_125m", "sata_ref_100m",
|
||||
"pcie_ref_125m", "sata_ref_100m", "usbphy1", "usbphy2",
|
||||
"dummy", "dummy", "dummy", "dummy", "osc",
|
||||
};
|
||||
static const char *pll_bypass_src_sels[] = { "osc", "lvds1_in", "lvds2_in", "dummy", };
|
||||
static const char *pll1_bypass_sels[] = { "pll1", "pll1_bypass_src", };
|
||||
|
@ -399,9 +399,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
|
||||
/* mask handshake of mmdc */
|
||||
writel_relaxed(BM_CCM_CCDR_MMDC_CH0_MASK, base + CCDR);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(clks); i++)
|
||||
if (IS_ERR(clks[i]))
|
||||
pr_err("i.MX6UL clk %d: register failed with %ld\n", i, PTR_ERR(clks[i]));
|
||||
imx_check_clocks(clks, ARRAY_SIZE(clks));
|
||||
|
||||
clk_data.clks = clks;
|
||||
clk_data.clk_num = ARRAY_SIZE(clks);
|
||||
|
@ -833,10 +833,13 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
|
||||
|
||||
clks[IMX7D_GPT_3M_CLK] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(clks); i++)
|
||||
if (IS_ERR(clks[i]))
|
||||
pr_err("i.MX7D clk %d: register failed with %ld\n",
|
||||
i, PTR_ERR(clks[i]));
|
||||
clks[IMX7D_CLK_ARM] = imx_clk_cpu("arm", "arm_a7_root_clk",
|
||||
clks[IMX7D_ARM_A7_ROOT_CLK],
|
||||
clks[IMX7D_ARM_A7_ROOT_SRC],
|
||||
clks[IMX7D_PLL_ARM_MAIN_CLK],
|
||||
clks[IMX7D_PLL_SYS_MAIN_CLK]);
|
||||
|
||||
imx_check_clocks(clks, ARRAY_SIZE(clks));
|
||||
|
||||
clk_data.clks = clks;
|
||||
clk_data.clk_num = ARRAY_SIZE(clks);
|
||||
|
@ -97,6 +97,16 @@ static void clk_pllv3_unprepare(struct clk_hw *hw)
|
||||
writel_relaxed(val, pll->base);
|
||||
}
|
||||
|
||||
static int clk_pllv3_is_prepared(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_pllv3 *pll = to_clk_pllv3(hw);
|
||||
|
||||
if (readl_relaxed(pll->base) & BM_PLL_LOCK)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned long clk_pllv3_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
@ -139,6 +149,7 @@ static int clk_pllv3_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
static const struct clk_ops clk_pllv3_ops = {
|
||||
.prepare = clk_pllv3_prepare,
|
||||
.unprepare = clk_pllv3_unprepare,
|
||||
.is_prepared = clk_pllv3_is_prepared,
|
||||
.recalc_rate = clk_pllv3_recalc_rate,
|
||||
.round_rate = clk_pllv3_round_rate,
|
||||
.set_rate = clk_pllv3_set_rate,
|
||||
@ -193,6 +204,7 @@ static int clk_pllv3_sys_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
static const struct clk_ops clk_pllv3_sys_ops = {
|
||||
.prepare = clk_pllv3_prepare,
|
||||
.unprepare = clk_pllv3_unprepare,
|
||||
.is_prepared = clk_pllv3_is_prepared,
|
||||
.recalc_rate = clk_pllv3_sys_recalc_rate,
|
||||
.round_rate = clk_pllv3_sys_round_rate,
|
||||
.set_rate = clk_pllv3_sys_set_rate,
|
||||
@ -265,6 +277,7 @@ static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
static const struct clk_ops clk_pllv3_av_ops = {
|
||||
.prepare = clk_pllv3_prepare,
|
||||
.unprepare = clk_pllv3_unprepare,
|
||||
.is_prepared = clk_pllv3_is_prepared,
|
||||
.recalc_rate = clk_pllv3_av_recalc_rate,
|
||||
.round_rate = clk_pllv3_av_round_rate,
|
||||
.set_rate = clk_pllv3_av_set_rate,
|
||||
@ -279,6 +292,7 @@ static unsigned long clk_pllv3_enet_recalc_rate(struct clk_hw *hw,
|
||||
static const struct clk_ops clk_pllv3_enet_ops = {
|
||||
.prepare = clk_pllv3_prepare,
|
||||
.unprepare = clk_pllv3_unprepare,
|
||||
.is_prepared = clk_pllv3_is_prepared,
|
||||
.recalc_rate = clk_pllv3_enet_recalc_rate,
|
||||
};
|
||||
|
||||
|
@ -106,3 +106,20 @@ config MSM_MMCC_8974
|
||||
Support for the multimedia clock controller on msm8974 devices.
|
||||
Say Y if you want to support multimedia devices such as display,
|
||||
graphics, video encode/decode, camera, etc.
|
||||
|
||||
config MSM_GCC_8996
|
||||
tristate "MSM8996 Global Clock Controller"
|
||||
depends on COMMON_CLK_QCOM
|
||||
help
|
||||
Support for the global clock controller on msm8996 devices.
|
||||
Say Y if you want to use peripheral devices such as UART, SPI,
|
||||
i2c, USB, UFS, SD/eMMC, PCIe, etc.
|
||||
|
||||
config MSM_MMCC_8996
|
||||
tristate "MSM8996 Multimedia Clock Controller"
|
||||
select MSM_GCC_8996
|
||||
depends on COMMON_CLK_QCOM
|
||||
help
|
||||
Support for the multimedia clock controller on msm8996 devices.
|
||||
Say Y if you want to support multimedia devices such as display,
|
||||
graphics, video encode/decode, camera, etc.
|
||||
|
@ -2,6 +2,7 @@ obj-$(CONFIG_COMMON_CLK_QCOM) += clk-qcom.o
|
||||
|
||||
clk-qcom-y += common.o
|
||||
clk-qcom-y += clk-regmap.o
|
||||
clk-qcom-y += clk-alpha-pll.o
|
||||
clk-qcom-y += clk-pll.o
|
||||
clk-qcom-y += clk-rcg.o
|
||||
clk-qcom-y += clk-rcg2.o
|
||||
@ -20,5 +21,7 @@ obj-$(CONFIG_MSM_GCC_8916) += gcc-msm8916.o
|
||||
obj-$(CONFIG_MSM_GCC_8960) += gcc-msm8960.o
|
||||
obj-$(CONFIG_MSM_LCC_8960) += lcc-msm8960.o
|
||||
obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o
|
||||
obj-$(CONFIG_MSM_GCC_8996) += gcc-msm8996.o
|
||||
obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o
|
||||
obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o
|
||||
obj-$(CONFIG_MSM_MMCC_8996) += mmcc-msm8996.o
|
||||
|
355
drivers/clk/qcom/clk-alpha-pll.c
Normal file
355
drivers/clk/qcom/clk-alpha-pll.c
Normal file
@ -0,0 +1,355 @@
|
||||
/*
|
||||
* Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include "clk-alpha-pll.h"
|
||||
|
||||
#define PLL_MODE 0x00
|
||||
# define PLL_OUTCTRL BIT(0)
|
||||
# define PLL_BYPASSNL BIT(1)
|
||||
# define PLL_RESET_N BIT(2)
|
||||
# define PLL_LOCK_COUNT_SHIFT 8
|
||||
# define PLL_LOCK_COUNT_MASK 0x3f
|
||||
# define PLL_BIAS_COUNT_SHIFT 14
|
||||
# define PLL_BIAS_COUNT_MASK 0x3f
|
||||
# define PLL_VOTE_FSM_ENA BIT(20)
|
||||
# define PLL_VOTE_FSM_RESET BIT(21)
|
||||
# define PLL_ACTIVE_FLAG BIT(30)
|
||||
# define PLL_LOCK_DET BIT(31)
|
||||
|
||||
#define PLL_L_VAL 0x04
|
||||
#define PLL_ALPHA_VAL 0x08
|
||||
#define PLL_ALPHA_VAL_U 0x0c
|
||||
|
||||
#define PLL_USER_CTL 0x10
|
||||
# define PLL_POST_DIV_SHIFT 8
|
||||
# define PLL_POST_DIV_MASK 0xf
|
||||
# define PLL_ALPHA_EN BIT(24)
|
||||
# define PLL_VCO_SHIFT 20
|
||||
# define PLL_VCO_MASK 0x3
|
||||
|
||||
#define PLL_USER_CTL_U 0x14
|
||||
|
||||
#define PLL_CONFIG_CTL 0x18
|
||||
#define PLL_TEST_CTL 0x1c
|
||||
#define PLL_TEST_CTL_U 0x20
|
||||
#define PLL_STATUS 0x24
|
||||
|
||||
/*
|
||||
* Even though 40 bits are present, use only 32 for ease of calculation.
|
||||
*/
|
||||
#define ALPHA_REG_BITWIDTH 40
|
||||
#define ALPHA_BITWIDTH 32
|
||||
|
||||
#define to_clk_alpha_pll(_hw) container_of(to_clk_regmap(_hw), \
|
||||
struct clk_alpha_pll, clkr)
|
||||
|
||||
#define to_clk_alpha_pll_postdiv(_hw) container_of(to_clk_regmap(_hw), \
|
||||
struct clk_alpha_pll_postdiv, clkr)
|
||||
|
||||
static int wait_for_pll(struct clk_alpha_pll *pll)
|
||||
{
|
||||
u32 val, mask, off;
|
||||
int count;
|
||||
int ret;
|
||||
const char *name = clk_hw_get_name(&pll->clkr.hw);
|
||||
|
||||
off = pll->offset;
|
||||
ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (val & PLL_VOTE_FSM_ENA)
|
||||
mask = PLL_ACTIVE_FLAG;
|
||||
else
|
||||
mask = PLL_LOCK_DET;
|
||||
|
||||
/* Wait for pll to enable. */
|
||||
for (count = 100; count > 0; count--) {
|
||||
ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
if ((val & mask) == mask)
|
||||
return 0;
|
||||
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
WARN(1, "%s didn't enable after voting for it!\n", name);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static int clk_alpha_pll_enable(struct clk_hw *hw)
|
||||
{
|
||||
int ret;
|
||||
struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
|
||||
u32 val, mask, off;
|
||||
|
||||
off = pll->offset;
|
||||
|
||||
mask = PLL_OUTCTRL | PLL_RESET_N | PLL_BYPASSNL;
|
||||
ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* If in FSM mode, just vote for it */
|
||||
if (val & PLL_VOTE_FSM_ENA) {
|
||||
ret = clk_enable_regmap(hw);
|
||||
if (ret)
|
||||
return ret;
|
||||
return wait_for_pll(pll);
|
||||
}
|
||||
|
||||
/* Skip if already enabled */
|
||||
if ((val & mask) == mask)
|
||||
return 0;
|
||||
|
||||
ret = regmap_update_bits(pll->clkr.regmap, off + PLL_MODE,
|
||||
PLL_BYPASSNL, PLL_BYPASSNL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* H/W requires a 5us delay between disabling the bypass and
|
||||
* de-asserting the reset.
|
||||
*/
|
||||
mb();
|
||||
udelay(5);
|
||||
|
||||
ret = regmap_update_bits(pll->clkr.regmap, off + PLL_MODE,
|
||||
PLL_RESET_N, PLL_RESET_N);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = wait_for_pll(pll);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = regmap_update_bits(pll->clkr.regmap, off + PLL_MODE,
|
||||
PLL_OUTCTRL, PLL_OUTCTRL);
|
||||
|
||||
/* Ensure that the write above goes through before returning. */
|
||||
mb();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void clk_alpha_pll_disable(struct clk_hw *hw)
|
||||
{
|
||||
int ret;
|
||||
struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
|
||||
u32 val, mask, off;
|
||||
|
||||
off = pll->offset;
|
||||
|
||||
ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, &val);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
/* If in FSM mode, just unvote it */
|
||||
if (val & PLL_VOTE_FSM_ENA) {
|
||||
clk_disable_regmap(hw);
|
||||
return;
|
||||
}
|
||||
|
||||
mask = PLL_OUTCTRL;
|
||||
regmap_update_bits(pll->clkr.regmap, off + PLL_MODE, mask, 0);
|
||||
|
||||
/* Delay of 2 output clock ticks required until output is disabled */
|
||||
mb();
|
||||
udelay(1);
|
||||
|
||||
mask = PLL_RESET_N | PLL_BYPASSNL;
|
||||
regmap_update_bits(pll->clkr.regmap, off + PLL_MODE, mask, 0);
|
||||
}
|
||||
|
||||
static unsigned long alpha_pll_calc_rate(u64 prate, u32 l, u32 a)
|
||||
{
|
||||
return (prate * l) + ((prate * a) >> ALPHA_BITWIDTH);
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
alpha_pll_round_rate(unsigned long rate, unsigned long prate, u32 *l, u64 *a)
|
||||
{
|
||||
u64 remainder;
|
||||
u64 quotient;
|
||||
|
||||
quotient = rate;
|
||||
remainder = do_div(quotient, prate);
|
||||
*l = quotient;
|
||||
|
||||
if (!remainder) {
|
||||
*a = 0;
|
||||
return rate;
|
||||
}
|
||||
|
||||
/* Upper ALPHA_BITWIDTH bits of Alpha */
|
||||
quotient = remainder << ALPHA_BITWIDTH;
|
||||
remainder = do_div(quotient, prate);
|
||||
|
||||
if (remainder)
|
||||
quotient++;
|
||||
|
||||
*a = quotient;
|
||||
return alpha_pll_calc_rate(prate, *l, *a);
|
||||
}
|
||||
|
||||
static const struct pll_vco *
|
||||
alpha_pll_find_vco(const struct clk_alpha_pll *pll, unsigned long rate)
|
||||
{
|
||||
const struct pll_vco *v = pll->vco_table;
|
||||
const struct pll_vco *end = v + pll->num_vco;
|
||||
|
||||
for (; v < end; v++)
|
||||
if (rate >= v->min_freq && rate <= v->max_freq)
|
||||
return v;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
clk_alpha_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
|
||||
{
|
||||
u32 l, low, high, ctl;
|
||||
u64 a = 0, prate = parent_rate;
|
||||
struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
|
||||
u32 off = pll->offset;
|
||||
|
||||
regmap_read(pll->clkr.regmap, off + PLL_L_VAL, &l);
|
||||
|
||||
regmap_read(pll->clkr.regmap, off + PLL_USER_CTL, &ctl);
|
||||
if (ctl & PLL_ALPHA_EN) {
|
||||
regmap_read(pll->clkr.regmap, off + PLL_ALPHA_VAL, &low);
|
||||
regmap_read(pll->clkr.regmap, off + PLL_ALPHA_VAL_U, &high);
|
||||
a = (u64)high << 32 | low;
|
||||
a >>= ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH;
|
||||
}
|
||||
|
||||
return alpha_pll_calc_rate(prate, l, a);
|
||||
}
|
||||
|
||||
static int clk_alpha_pll_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long prate)
|
||||
{
|
||||
struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
|
||||
const struct pll_vco *vco;
|
||||
u32 l, off = pll->offset;
|
||||
u64 a;
|
||||
|
||||
rate = alpha_pll_round_rate(rate, prate, &l, &a);
|
||||
vco = alpha_pll_find_vco(pll, rate);
|
||||
if (!vco) {
|
||||
pr_err("alpha pll not in a valid vco range\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
a <<= (ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH);
|
||||
|
||||
regmap_write(pll->clkr.regmap, off + PLL_L_VAL, l);
|
||||
regmap_write(pll->clkr.regmap, off + PLL_ALPHA_VAL, a);
|
||||
regmap_write(pll->clkr.regmap, off + PLL_ALPHA_VAL_U, a >> 32);
|
||||
|
||||
regmap_update_bits(pll->clkr.regmap, off + PLL_USER_CTL,
|
||||
PLL_VCO_MASK << PLL_VCO_SHIFT,
|
||||
vco->val << PLL_VCO_SHIFT);
|
||||
|
||||
regmap_update_bits(pll->clkr.regmap, off + PLL_USER_CTL, PLL_ALPHA_EN,
|
||||
PLL_ALPHA_EN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long clk_alpha_pll_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *prate)
|
||||
{
|
||||
struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
|
||||
u32 l;
|
||||
u64 a;
|
||||
unsigned long min_freq, max_freq;
|
||||
|
||||
rate = alpha_pll_round_rate(rate, *prate, &l, &a);
|
||||
if (alpha_pll_find_vco(pll, rate))
|
||||
return rate;
|
||||
|
||||
min_freq = pll->vco_table[0].min_freq;
|
||||
max_freq = pll->vco_table[pll->num_vco - 1].max_freq;
|
||||
|
||||
return clamp(rate, min_freq, max_freq);
|
||||
}
|
||||
|
||||
const struct clk_ops clk_alpha_pll_ops = {
|
||||
.enable = clk_alpha_pll_enable,
|
||||
.disable = clk_alpha_pll_disable,
|
||||
.recalc_rate = clk_alpha_pll_recalc_rate,
|
||||
.round_rate = clk_alpha_pll_round_rate,
|
||||
.set_rate = clk_alpha_pll_set_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(clk_alpha_pll_ops);
|
||||
|
||||
static unsigned long
|
||||
clk_alpha_pll_postdiv_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
|
||||
{
|
||||
struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);
|
||||
u32 ctl;
|
||||
|
||||
regmap_read(pll->clkr.regmap, pll->offset + PLL_USER_CTL, &ctl);
|
||||
|
||||
ctl >>= PLL_POST_DIV_SHIFT;
|
||||
ctl &= PLL_POST_DIV_MASK;
|
||||
|
||||
return parent_rate >> fls(ctl);
|
||||
}
|
||||
|
||||
static const struct clk_div_table clk_alpha_div_table[] = {
|
||||
{ 0x0, 1 },
|
||||
{ 0x1, 2 },
|
||||
{ 0x3, 4 },
|
||||
{ 0x7, 8 },
|
||||
{ 0xf, 16 },
|
||||
{ }
|
||||
};
|
||||
|
||||
static long
|
||||
clk_alpha_pll_postdiv_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *prate)
|
||||
{
|
||||
struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);
|
||||
|
||||
return divider_round_rate(hw, rate, prate, clk_alpha_div_table,
|
||||
pll->width, CLK_DIVIDER_POWER_OF_TWO);
|
||||
}
|
||||
|
||||
static int clk_alpha_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);
|
||||
int div;
|
||||
|
||||
/* 16 -> 0xf, 8 -> 0x7, 4 -> 0x3, 2 -> 0x1, 1 -> 0x0 */
|
||||
div = DIV_ROUND_UP_ULL((u64)parent_rate, rate) - 1;
|
||||
|
||||
return regmap_update_bits(pll->clkr.regmap, pll->offset + PLL_USER_CTL,
|
||||
PLL_POST_DIV_MASK << PLL_POST_DIV_SHIFT,
|
||||
div << PLL_POST_DIV_SHIFT);
|
||||
}
|
||||
|
||||
const struct clk_ops clk_alpha_pll_postdiv_ops = {
|
||||
.recalc_rate = clk_alpha_pll_postdiv_recalc_rate,
|
||||
.round_rate = clk_alpha_pll_postdiv_round_rate,
|
||||
.set_rate = clk_alpha_pll_postdiv_set_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_ops);
|
57
drivers/clk/qcom/clk-alpha-pll.h
Normal file
57
drivers/clk/qcom/clk-alpha-pll.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef __QCOM_CLK_ALPHA_PLL_H__
|
||||
#define __QCOM_CLK_ALPHA_PLL_H__
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include "clk-regmap.h"
|
||||
|
||||
struct pll_vco {
|
||||
unsigned long min_freq;
|
||||
unsigned long max_freq;
|
||||
u32 val;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct clk_alpha_pll - phase locked loop (PLL)
|
||||
* @offset: base address of registers
|
||||
* @vco_table: array of VCO settings
|
||||
* @clkr: regmap clock handle
|
||||
*/
|
||||
struct clk_alpha_pll {
|
||||
u32 offset;
|
||||
|
||||
const struct pll_vco *vco_table;
|
||||
size_t num_vco;
|
||||
|
||||
struct clk_regmap clkr;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct clk_alpha_pll_postdiv - phase locked loop (PLL) post-divider
|
||||
* @offset: base address of registers
|
||||
* @width: width of post-divider
|
||||
* @clkr: regmap clock handle
|
||||
*/
|
||||
struct clk_alpha_pll_postdiv {
|
||||
u32 offset;
|
||||
u8 width;
|
||||
|
||||
struct clk_regmap clkr;
|
||||
};
|
||||
|
||||
extern const struct clk_ops clk_alpha_pll_ops;
|
||||
extern const struct clk_ops clk_alpha_pll_postdiv_ops;
|
||||
|
||||
#endif
|
@ -178,5 +178,6 @@ extern const struct clk_ops clk_edp_pixel_ops;
|
||||
extern const struct clk_ops clk_byte_ops;
|
||||
extern const struct clk_ops clk_byte2_ops;
|
||||
extern const struct clk_ops clk_pixel_ops;
|
||||
extern const struct clk_ops clk_gfx3d_ops;
|
||||
|
||||
#endif
|
||||
|
@ -723,3 +723,90 @@ const struct clk_ops clk_pixel_ops = {
|
||||
.determine_rate = clk_pixel_determine_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(clk_pixel_ops);
|
||||
|
||||
static int clk_gfx3d_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
struct clk_rate_request parent_req = { };
|
||||
struct clk_hw *p2, *p8, *p9, *xo;
|
||||
unsigned long p9_rate;
|
||||
int ret;
|
||||
|
||||
xo = clk_hw_get_parent_by_index(hw, 0);
|
||||
if (req->rate == clk_hw_get_rate(xo)) {
|
||||
req->best_parent_hw = xo;
|
||||
return 0;
|
||||
}
|
||||
|
||||
p9 = clk_hw_get_parent_by_index(hw, 2);
|
||||
p2 = clk_hw_get_parent_by_index(hw, 3);
|
||||
p8 = clk_hw_get_parent_by_index(hw, 4);
|
||||
|
||||
/* PLL9 is a fixed rate PLL */
|
||||
p9_rate = clk_hw_get_rate(p9);
|
||||
|
||||
parent_req.rate = req->rate = min(req->rate, p9_rate);
|
||||
if (req->rate == p9_rate) {
|
||||
req->rate = req->best_parent_rate = p9_rate;
|
||||
req->best_parent_hw = p9;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (req->best_parent_hw == p9) {
|
||||
/* Are we going back to a previously used rate? */
|
||||
if (clk_hw_get_rate(p8) == req->rate)
|
||||
req->best_parent_hw = p8;
|
||||
else
|
||||
req->best_parent_hw = p2;
|
||||
} else if (req->best_parent_hw == p8) {
|
||||
req->best_parent_hw = p2;
|
||||
} else {
|
||||
req->best_parent_hw = p8;
|
||||
}
|
||||
|
||||
ret = __clk_determine_rate(req->best_parent_hw, &parent_req);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
req->rate = req->best_parent_rate = parent_req.rate;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int clk_gfx3d_set_rate_and_parent(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate, u8 index)
|
||||
{
|
||||
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
|
||||
u32 cfg;
|
||||
int ret;
|
||||
|
||||
/* Just mux it, we don't use the division or m/n hardware */
|
||||
cfg = rcg->parent_map[index].cfg << CFG_SRC_SEL_SHIFT;
|
||||
ret = regmap_write(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, cfg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return update_config(rcg);
|
||||
}
|
||||
|
||||
static int clk_gfx3d_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
/*
|
||||
* We should never get here; clk_gfx3d_determine_rate() should always
|
||||
* make us use a different parent than what we're currently using, so
|
||||
* clk_gfx3d_set_rate_and_parent() should always be called.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct clk_ops clk_gfx3d_ops = {
|
||||
.is_enabled = clk_rcg2_is_enabled,
|
||||
.get_parent = clk_rcg2_get_parent,
|
||||
.set_parent = clk_rcg2_set_parent,
|
||||
.recalc_rate = clk_rcg2_recalc_rate,
|
||||
.set_rate = clk_gfx3d_set_rate,
|
||||
.set_rate_and_parent = clk_gfx3d_set_rate_and_parent,
|
||||
.determine_rate = clk_gfx3d_determine_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(clk_gfx3d_ops);
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/reset-controller.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "clk-rcg.h"
|
||||
@ -88,6 +89,92 @@ static void qcom_cc_gdsc_unregister(void *data)
|
||||
gdsc_unregister(data);
|
||||
}
|
||||
|
||||
/*
|
||||
* Backwards compatibility with old DTs. Register a pass-through factor 1/1
|
||||
* clock to translate 'path' clk into 'name' clk and regsiter the 'path'
|
||||
* clk as a fixed rate clock if it isn't present.
|
||||
*/
|
||||
static int _qcom_cc_register_board_clk(struct device *dev, const char *path,
|
||||
const char *name, unsigned long rate,
|
||||
bool add_factor)
|
||||
{
|
||||
struct device_node *node = NULL;
|
||||
struct device_node *clocks_node;
|
||||
struct clk_fixed_factor *factor;
|
||||
struct clk_fixed_rate *fixed;
|
||||
struct clk *clk;
|
||||
struct clk_init_data init_data = { };
|
||||
|
||||
clocks_node = of_find_node_by_path("/clocks");
|
||||
if (clocks_node)
|
||||
node = of_find_node_by_name(clocks_node, path);
|
||||
of_node_put(clocks_node);
|
||||
|
||||
if (!node) {
|
||||
fixed = devm_kzalloc(dev, sizeof(*fixed), GFP_KERNEL);
|
||||
if (!fixed)
|
||||
return -EINVAL;
|
||||
|
||||
fixed->fixed_rate = rate;
|
||||
fixed->hw.init = &init_data;
|
||||
|
||||
init_data.name = path;
|
||||
init_data.flags = CLK_IS_ROOT;
|
||||
init_data.ops = &clk_fixed_rate_ops;
|
||||
|
||||
clk = devm_clk_register(dev, &fixed->hw);
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
}
|
||||
of_node_put(node);
|
||||
|
||||
if (add_factor) {
|
||||
factor = devm_kzalloc(dev, sizeof(*factor), GFP_KERNEL);
|
||||
if (!factor)
|
||||
return -EINVAL;
|
||||
|
||||
factor->mult = factor->div = 1;
|
||||
factor->hw.init = &init_data;
|
||||
|
||||
init_data.name = name;
|
||||
init_data.parent_names = &path;
|
||||
init_data.num_parents = 1;
|
||||
init_data.flags = 0;
|
||||
init_data.ops = &clk_fixed_factor_ops;
|
||||
|
||||
clk = devm_clk_register(dev, &factor->hw);
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int qcom_cc_register_board_clk(struct device *dev, const char *path,
|
||||
const char *name, unsigned long rate)
|
||||
{
|
||||
bool add_factor = true;
|
||||
struct device_node *node;
|
||||
|
||||
/* The RPM clock driver will add the factor clock if present */
|
||||
if (IS_ENABLED(CONFIG_QCOM_RPMCC)) {
|
||||
node = of_find_compatible_node(NULL, NULL, "qcom,rpmcc");
|
||||
if (of_device_is_available(node))
|
||||
add_factor = false;
|
||||
of_node_put(node);
|
||||
}
|
||||
|
||||
return _qcom_cc_register_board_clk(dev, path, name, rate, add_factor);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qcom_cc_register_board_clk);
|
||||
|
||||
int qcom_cc_register_sleep_clk(struct device *dev)
|
||||
{
|
||||
return _qcom_cc_register_board_clk(dev, "sleep_clk", "sleep_clk_src",
|
||||
32768, true);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qcom_cc_register_sleep_clk);
|
||||
|
||||
int qcom_cc_really_probe(struct platform_device *pdev,
|
||||
const struct qcom_cc_desc *desc, struct regmap *regmap)
|
||||
{
|
||||
|
@ -37,6 +37,10 @@ extern const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f,
|
||||
extern int qcom_find_src_index(struct clk_hw *hw, const struct parent_map *map,
|
||||
u8 src);
|
||||
|
||||
extern int qcom_cc_register_board_clk(struct device *dev, const char *path,
|
||||
const char *name, unsigned long rate);
|
||||
extern int qcom_cc_register_sleep_clk(struct device *dev);
|
||||
|
||||
extern struct regmap *qcom_cc_map(struct platform_device *pdev,
|
||||
const struct qcom_cc_desc *desc);
|
||||
extern int qcom_cc_really_probe(struct platform_device *pdev,
|
||||
|
@ -3587,6 +3587,7 @@ static const struct regmap_config gcc_apq8084_regmap_config = {
|
||||
.val_bits = 32,
|
||||
.max_register = 0x1fc0,
|
||||
.fast_io = true,
|
||||
.val_format_endian = REGMAP_ENDIAN_LITTLE,
|
||||
};
|
||||
|
||||
static const struct qcom_cc_desc gcc_apq8084_desc = {
|
||||
@ -3607,18 +3608,16 @@ MODULE_DEVICE_TABLE(of, gcc_apq8084_match_table);
|
||||
|
||||
static int gcc_apq8084_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct clk *clk;
|
||||
int ret;
|
||||
struct device *dev = &pdev->dev;
|
||||
|
||||
/* Temporary until RPM clocks supported */
|
||||
clk = clk_register_fixed_rate(dev, "xo", NULL, CLK_IS_ROOT, 19200000);
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
ret = qcom_cc_register_board_clk(dev, "xo_board", "xo", 19200000);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
clk = clk_register_fixed_rate(dev, "sleep_clk_src", NULL,
|
||||
CLK_IS_ROOT, 32768);
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
ret = qcom_cc_register_sleep_clk(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return qcom_cc_probe(pdev, &gcc_apq8084_desc);
|
||||
}
|
||||
|
@ -3005,6 +3005,7 @@ static const struct regmap_config gcc_ipq806x_regmap_config = {
|
||||
.val_bits = 32,
|
||||
.max_register = 0x3e40,
|
||||
.fast_io = true,
|
||||
.val_format_endian = REGMAP_ENDIAN_LITTLE,
|
||||
};
|
||||
|
||||
static const struct qcom_cc_desc gcc_ipq806x_desc = {
|
||||
@ -3023,19 +3024,17 @@ MODULE_DEVICE_TABLE(of, gcc_ipq806x_match_table);
|
||||
|
||||
static int gcc_ipq806x_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct clk *clk;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct regmap *regmap;
|
||||
int ret;
|
||||
|
||||
/* Temporary until RPM clocks supported */
|
||||
clk = clk_register_fixed_rate(dev, "cxo", NULL, CLK_IS_ROOT, 25000000);
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
ret = qcom_cc_register_board_clk(dev, "cxo_board", "cxo", 19200000);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
clk = clk_register_fixed_rate(dev, "pxo", NULL, CLK_IS_ROOT, 25000000);
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
ret = qcom_cc_register_board_clk(dev, "pxo_board", "pxo", 27000000);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = qcom_cc_probe(pdev, &gcc_ipq806x_desc);
|
||||
if (ret)
|
||||
|
@ -2702,6 +2702,7 @@ static const struct regmap_config gcc_msm8660_regmap_config = {
|
||||
.val_bits = 32,
|
||||
.max_register = 0x363c,
|
||||
.fast_io = true,
|
||||
.val_format_endian = REGMAP_ENDIAN_LITTLE,
|
||||
};
|
||||
|
||||
static const struct qcom_cc_desc gcc_msm8660_desc = {
|
||||
@ -2720,17 +2721,16 @@ MODULE_DEVICE_TABLE(of, gcc_msm8660_match_table);
|
||||
|
||||
static int gcc_msm8660_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct clk *clk;
|
||||
int ret;
|
||||
struct device *dev = &pdev->dev;
|
||||
|
||||
/* Temporary until RPM clocks supported */
|
||||
clk = clk_register_fixed_rate(dev, "cxo", NULL, CLK_IS_ROOT, 19200000);
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
ret = qcom_cc_register_board_clk(dev, "cxo_board", "cxo", 19200000);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
clk = clk_register_fixed_rate(dev, "pxo", NULL, CLK_IS_ROOT, 27000000);
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
ret = qcom_cc_register_board_clk(dev, "pxo_board", "pxo", 27000000);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return qcom_cc_probe(pdev, &gcc_msm8660_desc);
|
||||
}
|
||||
|
@ -3336,6 +3336,7 @@ static const struct regmap_config gcc_msm8916_regmap_config = {
|
||||
.val_bits = 32,
|
||||
.max_register = 0x80000,
|
||||
.fast_io = true,
|
||||
.val_format_endian = REGMAP_ENDIAN_LITTLE,
|
||||
};
|
||||
|
||||
static const struct qcom_cc_desc gcc_msm8916_desc = {
|
||||
@ -3356,18 +3357,16 @@ MODULE_DEVICE_TABLE(of, gcc_msm8916_match_table);
|
||||
|
||||
static int gcc_msm8916_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct clk *clk;
|
||||
int ret;
|
||||
struct device *dev = &pdev->dev;
|
||||
|
||||
/* Temporary until RPM clocks supported */
|
||||
clk = clk_register_fixed_rate(dev, "xo", NULL, CLK_IS_ROOT, 19200000);
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
ret = qcom_cc_register_board_clk(dev, "xo_board", "xo", 19200000);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
clk = clk_register_fixed_rate(dev, "sleep_clk_src", NULL,
|
||||
CLK_IS_ROOT, 32768);
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
ret = qcom_cc_register_sleep_clk(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return qcom_cc_probe(pdev, &gcc_msm8916_desc);
|
||||
}
|
||||
|
@ -3468,6 +3468,7 @@ static const struct regmap_config gcc_msm8960_regmap_config = {
|
||||
.val_bits = 32,
|
||||
.max_register = 0x3660,
|
||||
.fast_io = true,
|
||||
.val_format_endian = REGMAP_ENDIAN_LITTLE,
|
||||
};
|
||||
|
||||
static const struct regmap_config gcc_apq8064_regmap_config = {
|
||||
@ -3476,6 +3477,7 @@ static const struct regmap_config gcc_apq8064_regmap_config = {
|
||||
.val_bits = 32,
|
||||
.max_register = 0x3880,
|
||||
.fast_io = true,
|
||||
.val_format_endian = REGMAP_ENDIAN_LITTLE,
|
||||
};
|
||||
|
||||
static const struct qcom_cc_desc gcc_msm8960_desc = {
|
||||
@ -3503,7 +3505,6 @@ MODULE_DEVICE_TABLE(of, gcc_msm8960_match_table);
|
||||
|
||||
static int gcc_msm8960_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct clk *clk;
|
||||
struct device *dev = &pdev->dev;
|
||||
const struct of_device_id *match;
|
||||
struct platform_device *tsens;
|
||||
@ -3513,14 +3514,13 @@ static int gcc_msm8960_probe(struct platform_device *pdev)
|
||||
if (!match)
|
||||
return -EINVAL;
|
||||
|
||||
/* Temporary until RPM clocks supported */
|
||||
clk = clk_register_fixed_rate(dev, "cxo", NULL, CLK_IS_ROOT, 19200000);
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
ret = qcom_cc_register_board_clk(dev, "cxo_board", "cxo", 19200000);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
clk = clk_register_fixed_rate(dev, "pxo", NULL, CLK_IS_ROOT, 27000000);
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
ret = qcom_cc_register_board_clk(dev, "pxo_board", "pxo", 27000000);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = qcom_cc_probe(pdev, match->data);
|
||||
if (ret)
|
||||
|
@ -2680,6 +2680,7 @@ static const struct regmap_config gcc_msm8974_regmap_config = {
|
||||
.val_bits = 32,
|
||||
.max_register = 0x1fc0,
|
||||
.fast_io = true,
|
||||
.val_format_endian = REGMAP_ENDIAN_LITTLE,
|
||||
};
|
||||
|
||||
static const struct qcom_cc_desc gcc_msm8974_desc = {
|
||||
@ -2717,7 +2718,7 @@ static void msm8974_pro_clock_override(void)
|
||||
|
||||
static int gcc_msm8974_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct clk *clk;
|
||||
int ret;
|
||||
struct device *dev = &pdev->dev;
|
||||
bool pro;
|
||||
const struct of_device_id *id;
|
||||
@ -2730,16 +2731,13 @@ static int gcc_msm8974_probe(struct platform_device *pdev)
|
||||
if (pro)
|
||||
msm8974_pro_clock_override();
|
||||
|
||||
/* Temporary until RPM clocks supported */
|
||||
clk = clk_register_fixed_rate(dev, "xo", NULL, CLK_IS_ROOT, 19200000);
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
ret = qcom_cc_register_board_clk(dev, "xo_board", "xo", 19200000);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Should move to DT node? */
|
||||
clk = clk_register_fixed_rate(dev, "sleep_clk_src", NULL,
|
||||
CLK_IS_ROOT, 32768);
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
ret = qcom_cc_register_sleep_clk(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return qcom_cc_probe(pdev, &gcc_msm8974_desc);
|
||||
}
|
||||
|
3422
drivers/clk/qcom/gcc-msm8996.c
Normal file
3422
drivers/clk/qcom/gcc-msm8996.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -419,6 +419,7 @@ static const struct regmap_config lcc_ipq806x_regmap_config = {
|
||||
.val_bits = 32,
|
||||
.max_register = 0xfc,
|
||||
.fast_io = true,
|
||||
.val_format_endian = REGMAP_ENDIAN_LITTLE,
|
||||
};
|
||||
|
||||
static const struct qcom_cc_desc lcc_ipq806x_desc = {
|
||||
|
@ -524,6 +524,7 @@ static const struct regmap_config lcc_msm8960_regmap_config = {
|
||||
.val_bits = 32,
|
||||
.max_register = 0xfc,
|
||||
.fast_io = true,
|
||||
.val_format_endian = REGMAP_ENDIAN_LITTLE,
|
||||
};
|
||||
|
||||
static const struct qcom_cc_desc lcc_msm8960_desc = {
|
||||
|
@ -3368,6 +3368,7 @@ static const struct regmap_config mmcc_apq8084_regmap_config = {
|
||||
.val_bits = 32,
|
||||
.max_register = 0x5104,
|
||||
.fast_io = true,
|
||||
.val_format_endian = REGMAP_ENDIAN_LITTLE,
|
||||
};
|
||||
|
||||
static const struct qcom_cc_desc mmcc_apq8084_desc = {
|
||||
|
@ -3029,6 +3029,7 @@ static const struct regmap_config mmcc_msm8960_regmap_config = {
|
||||
.val_bits = 32,
|
||||
.max_register = 0x334,
|
||||
.fast_io = true,
|
||||
.val_format_endian = REGMAP_ENDIAN_LITTLE,
|
||||
};
|
||||
|
||||
static const struct regmap_config mmcc_apq8064_regmap_config = {
|
||||
@ -3037,6 +3038,7 @@ static const struct regmap_config mmcc_apq8064_regmap_config = {
|
||||
.val_bits = 32,
|
||||
.max_register = 0x350,
|
||||
.fast_io = true,
|
||||
.val_format_endian = REGMAP_ENDIAN_LITTLE,
|
||||
};
|
||||
|
||||
static const struct qcom_cc_desc mmcc_msm8960_desc = {
|
||||
|
@ -2594,6 +2594,7 @@ static const struct regmap_config mmcc_msm8974_regmap_config = {
|
||||
.val_bits = 32,
|
||||
.max_register = 0x5104,
|
||||
.fast_io = true,
|
||||
.val_format_endian = REGMAP_ENDIAN_LITTLE,
|
||||
};
|
||||
|
||||
static const struct qcom_cc_desc mmcc_msm8974_desc = {
|
||||
|
3217
drivers/clk/qcom/mmcc-msm8996.c
Normal file
3217
drivers/clk/qcom/mmcc-msm8996.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -10,6 +10,8 @@ obj-y += clk-inverter.o
|
||||
obj-y += clk-mmc-phase.o
|
||||
obj-$(CONFIG_RESET_CONTROLLER) += softrst.o
|
||||
|
||||
obj-y += clk-rk3036.o
|
||||
obj-y += clk-rk3188.o
|
||||
obj-y += clk-rk3228.o
|
||||
obj-y += clk-rk3288.o
|
||||
obj-y += clk-rk3368.o
|
||||
|
@ -242,8 +242,8 @@ struct clk *rockchip_clk_register_cpuclk(const char *name,
|
||||
struct clk *clk, *cclk;
|
||||
int ret;
|
||||
|
||||
if (num_parents != 2) {
|
||||
pr_err("%s: needs two parent clocks\n", __func__);
|
||||
if (num_parents < 2) {
|
||||
pr_err("%s: needs at least two parent clocks\n", __func__);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,9 @@
|
||||
* Copyright (c) 2014 MundoReader S.L.
|
||||
* Author: Heiko Stuebner <heiko@sntech.de>
|
||||
*
|
||||
* Copyright (c) 2015 Rockchip Electronics Co. Ltd.
|
||||
* Author: Xing Zheng <zhengxing@rock-chips.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
@ -19,6 +22,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/clk.h>
|
||||
#include "clk.h"
|
||||
|
||||
#define PLL_MODE_MASK 0x3
|
||||
@ -107,6 +111,252 @@ static int rockchip_pll_wait_lock(struct rockchip_clk_pll *pll)
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
/**
|
||||
* PLL used in RK3036
|
||||
*/
|
||||
|
||||
#define RK3036_PLLCON(i) (i * 0x4)
|
||||
#define RK3036_PLLCON0_FBDIV_MASK 0xfff
|
||||
#define RK3036_PLLCON0_FBDIV_SHIFT 0
|
||||
#define RK3036_PLLCON0_POSTDIV1_MASK 0x7
|
||||
#define RK3036_PLLCON0_POSTDIV1_SHIFT 12
|
||||
#define RK3036_PLLCON1_REFDIV_MASK 0x3f
|
||||
#define RK3036_PLLCON1_REFDIV_SHIFT 0
|
||||
#define RK3036_PLLCON1_POSTDIV2_MASK 0x7
|
||||
#define RK3036_PLLCON1_POSTDIV2_SHIFT 6
|
||||
#define RK3036_PLLCON1_DSMPD_MASK 0x1
|
||||
#define RK3036_PLLCON1_DSMPD_SHIFT 12
|
||||
#define RK3036_PLLCON2_FRAC_MASK 0xffffff
|
||||
#define RK3036_PLLCON2_FRAC_SHIFT 0
|
||||
|
||||
#define RK3036_PLLCON1_PWRDOWN (1 << 13)
|
||||
|
||||
static void rockchip_rk3036_pll_get_params(struct rockchip_clk_pll *pll,
|
||||
struct rockchip_pll_rate_table *rate)
|
||||
{
|
||||
u32 pllcon;
|
||||
|
||||
pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(0));
|
||||
rate->fbdiv = ((pllcon >> RK3036_PLLCON0_FBDIV_SHIFT)
|
||||
& RK3036_PLLCON0_FBDIV_MASK);
|
||||
rate->postdiv1 = ((pllcon >> RK3036_PLLCON0_POSTDIV1_SHIFT)
|
||||
& RK3036_PLLCON0_POSTDIV1_MASK);
|
||||
|
||||
pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(1));
|
||||
rate->refdiv = ((pllcon >> RK3036_PLLCON1_REFDIV_SHIFT)
|
||||
& RK3036_PLLCON1_REFDIV_MASK);
|
||||
rate->postdiv2 = ((pllcon >> RK3036_PLLCON1_POSTDIV2_SHIFT)
|
||||
& RK3036_PLLCON1_POSTDIV2_MASK);
|
||||
rate->dsmpd = ((pllcon >> RK3036_PLLCON1_DSMPD_SHIFT)
|
||||
& RK3036_PLLCON1_DSMPD_MASK);
|
||||
|
||||
pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(2));
|
||||
rate->frac = ((pllcon >> RK3036_PLLCON2_FRAC_SHIFT)
|
||||
& RK3036_PLLCON2_FRAC_MASK);
|
||||
}
|
||||
|
||||
static unsigned long rockchip_rk3036_pll_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long prate)
|
||||
{
|
||||
struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
|
||||
struct rockchip_pll_rate_table cur;
|
||||
u64 rate64 = prate;
|
||||
|
||||
rockchip_rk3036_pll_get_params(pll, &cur);
|
||||
|
||||
rate64 *= cur.fbdiv;
|
||||
do_div(rate64, cur.refdiv);
|
||||
|
||||
if (cur.dsmpd == 0) {
|
||||
/* fractional mode */
|
||||
u64 frac_rate64 = prate * cur.frac;
|
||||
|
||||
do_div(frac_rate64, cur.refdiv);
|
||||
rate64 += frac_rate64 >> 24;
|
||||
}
|
||||
|
||||
do_div(rate64, cur.postdiv1);
|
||||
do_div(rate64, cur.postdiv2);
|
||||
|
||||
return (unsigned long)rate64;
|
||||
}
|
||||
|
||||
static int rockchip_rk3036_pll_set_params(struct rockchip_clk_pll *pll,
|
||||
const struct rockchip_pll_rate_table *rate)
|
||||
{
|
||||
const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
|
||||
struct clk_mux *pll_mux = &pll->pll_mux;
|
||||
struct rockchip_pll_rate_table cur;
|
||||
u32 pllcon;
|
||||
int rate_change_remuxed = 0;
|
||||
int cur_parent;
|
||||
int ret;
|
||||
|
||||
pr_debug("%s: rate settings for %lu fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
|
||||
__func__, rate->rate, rate->fbdiv, rate->postdiv1, rate->refdiv,
|
||||
rate->postdiv2, rate->dsmpd, rate->frac);
|
||||
|
||||
rockchip_rk3036_pll_get_params(pll, &cur);
|
||||
cur.rate = 0;
|
||||
|
||||
cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);
|
||||
if (cur_parent == PLL_MODE_NORM) {
|
||||
pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
|
||||
rate_change_remuxed = 1;
|
||||
}
|
||||
|
||||
/* update pll values */
|
||||
writel_relaxed(HIWORD_UPDATE(rate->fbdiv, RK3036_PLLCON0_FBDIV_MASK,
|
||||
RK3036_PLLCON0_FBDIV_SHIFT) |
|
||||
HIWORD_UPDATE(rate->postdiv1, RK3036_PLLCON0_POSTDIV1_MASK,
|
||||
RK3036_PLLCON0_POSTDIV1_SHIFT),
|
||||
pll->reg_base + RK3036_PLLCON(0));
|
||||
|
||||
writel_relaxed(HIWORD_UPDATE(rate->refdiv, RK3036_PLLCON1_REFDIV_MASK,
|
||||
RK3036_PLLCON1_REFDIV_SHIFT) |
|
||||
HIWORD_UPDATE(rate->postdiv2, RK3036_PLLCON1_POSTDIV2_MASK,
|
||||
RK3036_PLLCON1_POSTDIV2_SHIFT) |
|
||||
HIWORD_UPDATE(rate->dsmpd, RK3036_PLLCON1_DSMPD_MASK,
|
||||
RK3036_PLLCON1_DSMPD_SHIFT),
|
||||
pll->reg_base + RK3036_PLLCON(1));
|
||||
|
||||
/* GPLL CON2 is not HIWORD_MASK */
|
||||
pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(2));
|
||||
pllcon &= ~(RK3036_PLLCON2_FRAC_MASK << RK3036_PLLCON2_FRAC_SHIFT);
|
||||
pllcon |= rate->frac << RK3036_PLLCON2_FRAC_SHIFT;
|
||||
writel_relaxed(pllcon, pll->reg_base + RK3036_PLLCON(2));
|
||||
|
||||
/* wait for the pll to lock */
|
||||
ret = rockchip_pll_wait_lock(pll);
|
||||
if (ret) {
|
||||
pr_warn("%s: pll update unsucessful, trying to restore old params\n",
|
||||
__func__);
|
||||
rockchip_rk3036_pll_set_params(pll, &cur);
|
||||
}
|
||||
|
||||
if (rate_change_remuxed)
|
||||
pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rockchip_rk3036_pll_set_rate(struct clk_hw *hw, unsigned long drate,
|
||||
unsigned long prate)
|
||||
{
|
||||
struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
|
||||
const struct rockchip_pll_rate_table *rate;
|
||||
unsigned long old_rate = rockchip_rk3036_pll_recalc_rate(hw, prate);
|
||||
struct regmap *grf = rockchip_clk_get_grf();
|
||||
|
||||
if (IS_ERR(grf)) {
|
||||
pr_debug("%s: grf regmap not available, aborting rate change\n",
|
||||
__func__);
|
||||
return PTR_ERR(grf);
|
||||
}
|
||||
|
||||
pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n",
|
||||
__func__, __clk_get_name(hw->clk), old_rate, drate, prate);
|
||||
|
||||
/* Get required rate settings from table */
|
||||
rate = rockchip_get_pll_settings(pll, drate);
|
||||
if (!rate) {
|
||||
pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
|
||||
drate, __clk_get_name(hw->clk));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return rockchip_rk3036_pll_set_params(pll, rate);
|
||||
}
|
||||
|
||||
static int rockchip_rk3036_pll_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
|
||||
|
||||
writel(HIWORD_UPDATE(0, RK3036_PLLCON1_PWRDOWN, 0),
|
||||
pll->reg_base + RK3036_PLLCON(1));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rockchip_rk3036_pll_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
|
||||
|
||||
writel(HIWORD_UPDATE(RK3036_PLLCON1_PWRDOWN,
|
||||
RK3036_PLLCON1_PWRDOWN, 0),
|
||||
pll->reg_base + RK3036_PLLCON(1));
|
||||
}
|
||||
|
||||
static int rockchip_rk3036_pll_is_enabled(struct clk_hw *hw)
|
||||
{
|
||||
struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
|
||||
u32 pllcon = readl(pll->reg_base + RK3036_PLLCON(1));
|
||||
|
||||
return !(pllcon & RK3036_PLLCON1_PWRDOWN);
|
||||
}
|
||||
|
||||
static void rockchip_rk3036_pll_init(struct clk_hw *hw)
|
||||
{
|
||||
struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
|
||||
const struct rockchip_pll_rate_table *rate;
|
||||
struct rockchip_pll_rate_table cur;
|
||||
unsigned long drate;
|
||||
|
||||
if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
|
||||
return;
|
||||
|
||||
drate = clk_hw_get_rate(hw);
|
||||
rate = rockchip_get_pll_settings(pll, drate);
|
||||
|
||||
/* when no rate setting for the current rate, rely on clk_set_rate */
|
||||
if (!rate)
|
||||
return;
|
||||
|
||||
rockchip_rk3036_pll_get_params(pll, &cur);
|
||||
|
||||
pr_debug("%s: pll %s@%lu: Hz\n", __func__, __clk_get_name(hw->clk),
|
||||
drate);
|
||||
pr_debug("old - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
|
||||
cur.fbdiv, cur.postdiv1, cur.refdiv, cur.postdiv2,
|
||||
cur.dsmpd, cur.frac);
|
||||
pr_debug("new - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
|
||||
rate->fbdiv, rate->postdiv1, rate->refdiv, rate->postdiv2,
|
||||
rate->dsmpd, rate->frac);
|
||||
|
||||
if (rate->fbdiv != cur.fbdiv || rate->postdiv1 != cur.postdiv1 ||
|
||||
rate->refdiv != cur.refdiv || rate->postdiv2 != cur.postdiv2 ||
|
||||
rate->dsmpd != cur.dsmpd || rate->frac != cur.frac) {
|
||||
struct clk *parent = clk_get_parent(hw->clk);
|
||||
|
||||
if (!parent) {
|
||||
pr_warn("%s: parent of %s not available\n",
|
||||
__func__, __clk_get_name(hw->clk));
|
||||
return;
|
||||
}
|
||||
|
||||
pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
|
||||
__func__, __clk_get_name(hw->clk));
|
||||
rockchip_rk3036_pll_set_params(pll, rate);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct clk_ops rockchip_rk3036_pll_clk_norate_ops = {
|
||||
.recalc_rate = rockchip_rk3036_pll_recalc_rate,
|
||||
.enable = rockchip_rk3036_pll_enable,
|
||||
.disable = rockchip_rk3036_pll_disable,
|
||||
.is_enabled = rockchip_rk3036_pll_is_enabled,
|
||||
};
|
||||
|
||||
static const struct clk_ops rockchip_rk3036_pll_clk_ops = {
|
||||
.recalc_rate = rockchip_rk3036_pll_recalc_rate,
|
||||
.round_rate = rockchip_pll_round_rate,
|
||||
.set_rate = rockchip_rk3036_pll_set_rate,
|
||||
.enable = rockchip_rk3036_pll_enable,
|
||||
.disable = rockchip_rk3036_pll_disable,
|
||||
.is_enabled = rockchip_rk3036_pll_is_enabled,
|
||||
.init = rockchip_rk3036_pll_init,
|
||||
};
|
||||
|
||||
/**
|
||||
* PLL used in RK3066, RK3188 and RK3288
|
||||
*/
|
||||
@ -376,7 +626,7 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type,
|
||||
pll_mux->lock = lock;
|
||||
pll_mux->hw.init = &init;
|
||||
|
||||
if (pll_type == pll_rk3066)
|
||||
if (pll_type == pll_rk3036 || pll_type == pll_rk3066)
|
||||
pll_mux->flags |= CLK_MUX_HIWORD_MASK;
|
||||
|
||||
/* the actual muxing is xin24m, pll-output, xin32k */
|
||||
@ -421,6 +671,12 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type,
|
||||
}
|
||||
|
||||
switch (pll_type) {
|
||||
case pll_rk3036:
|
||||
if (!pll->rate_table)
|
||||
init.ops = &rockchip_rk3036_pll_clk_norate_ops;
|
||||
else
|
||||
init.ops = &rockchip_rk3036_pll_clk_ops;
|
||||
break;
|
||||
case pll_rk3066:
|
||||
if (!pll->rate_table)
|
||||
init.ops = &rockchip_rk3066_pll_clk_norate_ops;
|
||||
|
478
drivers/clk/rockchip/clk-rk3036.c
Normal file
478
drivers/clk/rockchip/clk-rk3036.c
Normal file
@ -0,0 +1,478 @@
|
||||
/*
|
||||
* Copyright (c) 2014 MundoReader S.L.
|
||||
* Author: Heiko Stuebner <heiko@sntech.de>
|
||||
*
|
||||
* Copyright (c) 2015 Rockchip Electronics Co. Ltd.
|
||||
* Author: Xing Zheng <zhengxing@rock-chips.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/syscore_ops.h>
|
||||
#include <dt-bindings/clock/rk3036-cru.h>
|
||||
#include "clk.h"
|
||||
|
||||
#define RK3036_GRF_SOC_STATUS0 0x14c
|
||||
|
||||
enum rk3036_plls {
|
||||
apll, dpll, gpll,
|
||||
};
|
||||
|
||||
static struct rockchip_pll_rate_table rk3036_pll_rates[] = {
|
||||
/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
|
||||
RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1584000000, 1, 66, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1560000000, 1, 65, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1536000000, 1, 64, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1512000000, 1, 63, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1488000000, 1, 62, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1464000000, 1, 61, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1440000000, 1, 60, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1416000000, 1, 59, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1392000000, 1, 58, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1368000000, 1, 57, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1344000000, 1, 56, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1320000000, 1, 55, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1296000000, 1, 54, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1272000000, 1, 53, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1248000000, 1, 52, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1188000000, 2, 99, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1104000000, 1, 46, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1100000000, 12, 550, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1000000000, 6, 500, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE( 984000000, 1, 82, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE( 960000000, 1, 80, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE( 936000000, 1, 78, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE( 912000000, 1, 76, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE( 900000000, 4, 300, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE( 888000000, 1, 74, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE( 864000000, 1, 72, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE( 840000000, 1, 70, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE( 816000000, 1, 68, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE( 800000000, 6, 400, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE( 700000000, 6, 350, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE( 696000000, 1, 58, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE( 600000000, 1, 75, 3, 1, 1, 0),
|
||||
RK3036_PLL_RATE( 594000000, 2, 99, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE( 504000000, 1, 63, 3, 1, 1, 0),
|
||||
RK3036_PLL_RATE( 500000000, 6, 250, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE( 408000000, 1, 68, 2, 2, 1, 0),
|
||||
RK3036_PLL_RATE( 312000000, 1, 52, 2, 2, 1, 0),
|
||||
RK3036_PLL_RATE( 216000000, 1, 72, 4, 2, 1, 0),
|
||||
RK3036_PLL_RATE( 96000000, 1, 64, 4, 4, 1, 0),
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
||||
#define RK3036_DIV_CPU_MASK 0x1f
|
||||
#define RK3036_DIV_CPU_SHIFT 8
|
||||
|
||||
#define RK3036_DIV_PERI_MASK 0xf
|
||||
#define RK3036_DIV_PERI_SHIFT 0
|
||||
#define RK3036_DIV_ACLK_MASK 0x7
|
||||
#define RK3036_DIV_ACLK_SHIFT 4
|
||||
#define RK3036_DIV_HCLK_MASK 0x3
|
||||
#define RK3036_DIV_HCLK_SHIFT 8
|
||||
#define RK3036_DIV_PCLK_MASK 0x7
|
||||
#define RK3036_DIV_PCLK_SHIFT 12
|
||||
|
||||
#define RK3036_CLKSEL1(_core_periph_div) \
|
||||
{ \
|
||||
.reg = RK2928_CLKSEL_CON(1), \
|
||||
.val = HIWORD_UPDATE(_core_periph_div, RK3036_DIV_PERI_MASK, \
|
||||
RK3036_DIV_PERI_SHIFT) \
|
||||
}
|
||||
|
||||
#define RK3036_CPUCLK_RATE(_prate, _core_periph_div) \
|
||||
{ \
|
||||
.prate = _prate, \
|
||||
.divs = { \
|
||||
RK3036_CLKSEL1(_core_periph_div), \
|
||||
}, \
|
||||
}
|
||||
|
||||
static struct rockchip_cpuclk_rate_table rk3036_cpuclk_rates[] __initdata = {
|
||||
RK3036_CPUCLK_RATE(816000000, 4),
|
||||
RK3036_CPUCLK_RATE(600000000, 4),
|
||||
RK3036_CPUCLK_RATE(312000000, 4),
|
||||
};
|
||||
|
||||
static const struct rockchip_cpuclk_reg_data rk3036_cpuclk_data = {
|
||||
.core_reg = RK2928_CLKSEL_CON(0),
|
||||
.div_core_shift = 0,
|
||||
.div_core_mask = 0x1f,
|
||||
.mux_core_shift = 7,
|
||||
};
|
||||
|
||||
PNAME(mux_pll_p) = { "xin24m", "xin24m" };
|
||||
|
||||
PNAME(mux_armclk_p) = { "apll", "gpll_armclk" };
|
||||
PNAME(mux_busclk_p) = { "apll", "dpll_cpu", "gpll_cpu" };
|
||||
PNAME(mux_ddrphy_p) = { "dpll_ddr", "gpll_ddr" };
|
||||
PNAME(mux_pll_src_3plls_p) = { "apll", "dpll", "gpll" };
|
||||
PNAME(mux_timer_p) = { "xin24m", "pclk_peri_src" };
|
||||
|
||||
PNAME(mux_pll_src_apll_dpll_gpll_usb480m_p) = { "apll", "dpll", "gpll" "usb480m" };
|
||||
|
||||
PNAME(mux_mmc_src_p) = { "apll", "dpll", "gpll", "xin24m" };
|
||||
PNAME(mux_i2s_pre_p) = { "i2s_src", "i2s_frac", "ext_i2s", "xin12m" };
|
||||
PNAME(mux_i2s_clkout_p) = { "i2s_pre", "xin12m" };
|
||||
PNAME(mux_spdif_p) = { "spdif_src", "spdif_frac", "xin12m" };
|
||||
PNAME(mux_uart0_p) = { "uart0_src", "uart0_frac", "xin24m" };
|
||||
PNAME(mux_uart1_p) = { "uart1_src", "uart1_frac", "xin24m" };
|
||||
PNAME(mux_uart2_p) = { "uart2_src", "uart2_frac", "xin24m" };
|
||||
PNAME(mux_mac_p) = { "mac_pll_src", "ext_gmac" };
|
||||
PNAME(mux_dclk_p) = { "dclk_lcdc", "dclk_cru" };
|
||||
|
||||
static struct rockchip_pll_clock rk3036_pll_clks[] __initdata = {
|
||||
[apll] = PLL(pll_rk3036, PLL_APLL, "apll", mux_pll_p, 0, RK2928_PLL_CON(0),
|
||||
RK2928_MODE_CON, 0, 5, 0, rk3036_pll_rates),
|
||||
[dpll] = PLL(pll_rk3036, PLL_DPLL, "dpll", mux_pll_p, 0, RK2928_PLL_CON(4),
|
||||
RK2928_MODE_CON, 4, 4, 0, NULL),
|
||||
[gpll] = PLL(pll_rk3036, PLL_GPLL, "gpll", mux_pll_p, 0, RK2928_PLL_CON(12),
|
||||
RK2928_MODE_CON, 12, 6, ROCKCHIP_PLL_SYNC_RATE, rk3036_pll_rates),
|
||||
};
|
||||
|
||||
#define MFLAGS CLK_MUX_HIWORD_MASK
|
||||
#define DFLAGS CLK_DIVIDER_HIWORD_MASK
|
||||
#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE)
|
||||
|
||||
static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = {
|
||||
/*
|
||||
* Clock-Architecture Diagram 1
|
||||
*/
|
||||
|
||||
GATE(0, "gpll_armclk", "gpll", CLK_IGNORE_UNUSED,
|
||||
RK2928_CLKGATE_CON(0), 6, GFLAGS),
|
||||
|
||||
/*
|
||||
* Clock-Architecture Diagram 2
|
||||
*/
|
||||
|
||||
GATE(0, "dpll_ddr", "dpll", CLK_IGNORE_UNUSED,
|
||||
RK2928_CLKGATE_CON(0), 2, GFLAGS),
|
||||
GATE(0, "gpll_ddr", "gpll", CLK_IGNORE_UNUSED,
|
||||
RK2928_CLKGATE_CON(0), 8, GFLAGS),
|
||||
COMPOSITE_NOGATE(0, "ddrphy2x", mux_ddrphy_p, CLK_IGNORE_UNUSED,
|
||||
RK2928_CLKSEL_CON(26), 8, 1, MFLAGS, 0, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO),
|
||||
|
||||
COMPOSITE_NOMUX(0, "pclk_dbg", "armclk", CLK_IGNORE_UNUSED,
|
||||
RK2928_CLKSEL_CON(1), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
|
||||
RK2928_CLKGATE_CON(0), 7, GFLAGS),
|
||||
COMPOSITE_NOMUX(0, "aclk_core_pre", "armclk", CLK_IGNORE_UNUSED,
|
||||
RK2928_CLKSEL_CON(1), 4, 3, DFLAGS | CLK_DIVIDER_READ_ONLY,
|
||||
RK2928_CLKGATE_CON(0), 7, GFLAGS),
|
||||
|
||||
GATE(0, "dpll_cpu", "dpll", 0, RK2928_CLKGATE_CON(10), 8, GFLAGS),
|
||||
GATE(0, "gpll_cpu", "gpll", 0, RK2928_CLKGATE_CON(0), 1, GFLAGS),
|
||||
COMPOSITE_NOGATE(0, "aclk_cpu_src", mux_busclk_p, 0,
|
||||
RK2928_CLKSEL_CON(0), 14, 2, MFLAGS, 8, 5, DFLAGS),
|
||||
GATE(ACLK_CPU, "aclk_cpu", "aclk_cpu_src", CLK_IGNORE_UNUSED,
|
||||
RK2928_CLKGATE_CON(0), 3, GFLAGS),
|
||||
COMPOSITE_NOMUX(PCLK_CPU, "pclk_cpu", "aclk_cpu_src", CLK_IGNORE_UNUSED,
|
||||
RK2928_CLKSEL_CON(1), 12, 3, DFLAGS | CLK_DIVIDER_READ_ONLY,
|
||||
RK2928_CLKGATE_CON(0), 5, GFLAGS),
|
||||
COMPOSITE_NOMUX(HCLK_CPU, "hclk_cpu", "aclk_cpu_src", CLK_IGNORE_UNUSED,
|
||||
RK2928_CLKSEL_CON(1), 8, 2, DFLAGS | CLK_DIVIDER_READ_ONLY,
|
||||
RK2928_CLKGATE_CON(0), 4, GFLAGS),
|
||||
|
||||
COMPOSITE(0, "aclk_peri_src", mux_pll_src_3plls_p, 0,
|
||||
RK2928_CLKSEL_CON(10), 14, 2, MFLAGS, 0, 5, DFLAGS,
|
||||
RK2928_CLKGATE_CON(2), 0, GFLAGS),
|
||||
|
||||
GATE(ACLK_PERI, "aclk_peri", "aclk_peri_src", 0,
|
||||
RK2928_CLKGATE_CON(2), 1, GFLAGS),
|
||||
DIV(0, "pclk_peri_src", "aclk_peri_src", CLK_IGNORE_UNUSED,
|
||||
RK2928_CLKSEL_CON(10), 12, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO),
|
||||
GATE(PCLK_PERI, "pclk_peri", "pclk_peri_src", 0,
|
||||
RK2928_CLKGATE_CON(2), 3, GFLAGS),
|
||||
DIV(0, "hclk_peri_src", "aclk_peri_src", CLK_IGNORE_UNUSED,
|
||||
RK2928_CLKSEL_CON(10), 8, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO),
|
||||
GATE(HCLK_PERI, "hclk_peri", "hclk_peri_src", 0,
|
||||
RK2928_CLKGATE_CON(2), 2, GFLAGS),
|
||||
|
||||
COMPOSITE_NODIV(SCLK_TIMER0, "sclk_timer0", mux_timer_p, CLK_IGNORE_UNUSED,
|
||||
RK2928_CLKSEL_CON(2), 4, 1, DFLAGS,
|
||||
RK2928_CLKGATE_CON(1), 0, GFLAGS),
|
||||
COMPOSITE_NODIV(SCLK_TIMER1, "sclk_timer1", mux_timer_p, CLK_IGNORE_UNUSED,
|
||||
RK2928_CLKSEL_CON(2), 5, 1, DFLAGS,
|
||||
RK2928_CLKGATE_CON(1), 1, GFLAGS),
|
||||
COMPOSITE_NODIV(SCLK_TIMER2, "sclk_timer2", mux_timer_p, CLK_IGNORE_UNUSED,
|
||||
RK2928_CLKSEL_CON(2), 6, 1, DFLAGS,
|
||||
RK2928_CLKGATE_CON(2), 4, GFLAGS),
|
||||
COMPOSITE_NODIV(SCLK_TIMER3, "sclk_timer3", mux_timer_p, CLK_IGNORE_UNUSED,
|
||||
RK2928_CLKSEL_CON(2), 7, 1, DFLAGS,
|
||||
RK2928_CLKGATE_CON(2), 5, GFLAGS),
|
||||
|
||||
MUX(0, "uart_pll_clk", mux_pll_src_apll_dpll_gpll_usb480m_p, 0,
|
||||
RK2928_CLKSEL_CON(13), 10, 2, MFLAGS),
|
||||
COMPOSITE_NOMUX(0, "uart0_src", "uart_pll_clk", 0,
|
||||
RK2928_CLKSEL_CON(13), 0, 7, DFLAGS,
|
||||
RK2928_CLKGATE_CON(1), 8, GFLAGS),
|
||||
COMPOSITE_NOMUX(0, "uart1_src", "uart_pll_clk", 0,
|
||||
RK2928_CLKSEL_CON(13), 0, 7, DFLAGS,
|
||||
RK2928_CLKGATE_CON(1), 8, GFLAGS),
|
||||
COMPOSITE_NOMUX(0, "uart2_src", "uart_pll_clk", 0,
|
||||
RK2928_CLKSEL_CON(13), 0, 7, DFLAGS,
|
||||
RK2928_CLKGATE_CON(1), 8, GFLAGS),
|
||||
COMPOSITE_FRAC(0, "uart0_frac", "uart0_src", CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKSEL_CON(17), 0,
|
||||
RK2928_CLKGATE_CON(1), 9, GFLAGS),
|
||||
COMPOSITE_FRAC(0, "uart1_frac", "uart1_src", CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKSEL_CON(18), 0,
|
||||
RK2928_CLKGATE_CON(1), 11, GFLAGS),
|
||||
COMPOSITE_FRAC(0, "uart2_frac", "uart2_src", CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKSEL_CON(19), 0,
|
||||
RK2928_CLKGATE_CON(1), 13, GFLAGS),
|
||||
MUX(SCLK_UART0, "sclk_uart0", mux_uart0_p, CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKSEL_CON(13), 8, 2, MFLAGS),
|
||||
MUX(SCLK_UART1, "sclk_uart1", mux_uart1_p, CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKSEL_CON(14), 8, 2, MFLAGS),
|
||||
MUX(SCLK_UART2, "sclk_uart2", mux_uart2_p, CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKSEL_CON(15), 8, 2, MFLAGS),
|
||||
|
||||
COMPOSITE(0, "aclk_vcodec", mux_pll_src_3plls_p, 0,
|
||||
RK2928_CLKSEL_CON(32), 14, 2, MFLAGS, 8, 5, DFLAGS,
|
||||
RK2928_CLKGATE_CON(3), 11, GFLAGS),
|
||||
|
||||
COMPOSITE(0, "aclk_hvec", mux_pll_src_3plls_p, 0,
|
||||
RK2928_CLKSEL_CON(20), 0, 2, MFLAGS, 2, 5, DFLAGS,
|
||||
RK2928_CLKGATE_CON(10), 6, GFLAGS),
|
||||
|
||||
COMPOSITE(0, "aclk_disp1_pre", mux_pll_src_3plls_p, 0,
|
||||
RK2928_CLKSEL_CON(31), 14, 2, MFLAGS, 8, 5, DFLAGS,
|
||||
RK2928_CLKGATE_CON(1), 4, GFLAGS),
|
||||
COMPOSITE(0, "hclk_disp_pre", mux_pll_src_3plls_p, 0,
|
||||
RK2928_CLKSEL_CON(30), 14, 2, MFLAGS, 8, 5, DFLAGS,
|
||||
RK2928_CLKGATE_CON(0), 11, GFLAGS),
|
||||
COMPOSITE(SCLK_LCDC, "dclk_lcdc", mux_pll_src_3plls_p, 0,
|
||||
RK2928_CLKSEL_CON(28), 0, 2, MFLAGS, 8, 8, DFLAGS,
|
||||
RK2928_CLKGATE_CON(3), 2, GFLAGS),
|
||||
|
||||
COMPOSITE_NODIV(0, "sclk_sdmmc_src", mux_mmc_src_p, 0,
|
||||
RK2928_CLKSEL_CON(12), 8, 2, DFLAGS,
|
||||
RK2928_CLKGATE_CON(2), 11, GFLAGS),
|
||||
DIV(SCLK_SDMMC, "sclk_sdmmc", "sclk_sdmmc_src", 0,
|
||||
RK2928_CLKSEL_CON(11), 0, 7, DFLAGS),
|
||||
|
||||
COMPOSITE_NODIV(0, "sclk_sdio_src", mux_mmc_src_p, 0,
|
||||
RK2928_CLKSEL_CON(12), 10, 2, DFLAGS,
|
||||
RK2928_CLKGATE_CON(2), 13, GFLAGS),
|
||||
DIV(SCLK_SDIO, "sclk_sdio", "sclk_sdio_src", 0,
|
||||
RK2928_CLKSEL_CON(11), 8, 7, DFLAGS),
|
||||
|
||||
COMPOSITE(SCLK_EMMC, "sclk_emmc", mux_mmc_src_p, 0,
|
||||
RK2928_CLKSEL_CON(12), 12, 2, MFLAGS, 0, 7, DFLAGS,
|
||||
RK2928_CLKGATE_CON(2), 14, GFLAGS),
|
||||
|
||||
MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "sclk_sdmmc", RK3036_SDMMC_CON0, 1),
|
||||
MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "sclk_sdmmc", RK3036_SDMMC_CON1, 0),
|
||||
|
||||
MMC(SCLK_SDIO_DRV, "sdio_drv", "sclk_sdio", RK3036_SDIO_CON0, 1),
|
||||
MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "sclk_sdio", RK3036_SDIO_CON1, 0),
|
||||
|
||||
MMC(SCLK_EMMC_DRV, "emmc_drv", "sclk_emmc", RK3036_EMMC_CON0, 1),
|
||||
MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "sclk_emmc", RK3036_EMMC_CON1, 0),
|
||||
|
||||
COMPOSITE(0, "i2s_src", mux_pll_src_3plls_p, 0,
|
||||
RK2928_CLKSEL_CON(3), 14, 2, MFLAGS, 0, 7, DFLAGS,
|
||||
RK2928_CLKGATE_CON(0), 9, GFLAGS),
|
||||
COMPOSITE_FRAC(0, "i2s_frac", "i2s_src", CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKSEL_CON(7), 0,
|
||||
RK2928_CLKGATE_CON(0), 10, GFLAGS),
|
||||
MUX(0, "i2s_pre", mux_i2s_pre_p, CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKSEL_CON(3), 8, 2, MFLAGS),
|
||||
COMPOSITE_NODIV(SCLK_I2S_OUT, "i2s_clkout", mux_i2s_clkout_p, 0,
|
||||
RK2928_CLKSEL_CON(3), 12, 1, MFLAGS,
|
||||
RK2928_CLKGATE_CON(0), 13, GFLAGS),
|
||||
GATE(SCLK_I2S, "sclk_i2s", "i2s_pre", CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKGATE_CON(0), 14, GFLAGS),
|
||||
|
||||
COMPOSITE(0, "spdif_src", mux_pll_src_3plls_p, 0,
|
||||
RK2928_CLKSEL_CON(5), 10, 2, MFLAGS, 0, 7, DFLAGS,
|
||||
RK2928_CLKGATE_CON(2), 10, GFLAGS),
|
||||
COMPOSITE_FRAC(0, "spdif_frac", "spdif_src", 0,
|
||||
RK2928_CLKSEL_CON(9), 0,
|
||||
RK2928_CLKGATE_CON(2), 12, GFLAGS),
|
||||
MUX(SCLK_SPDIF, "sclk_spdif", mux_spdif_p, 0,
|
||||
RK2928_CLKSEL_CON(5), 8, 2, MFLAGS),
|
||||
|
||||
GATE(SCLK_OTGPHY0, "sclk_otgphy0", "xin12m", CLK_IGNORE_UNUSED,
|
||||
RK2928_CLKGATE_CON(1), 5, GFLAGS),
|
||||
|
||||
COMPOSITE(SCLK_GPU, "sclk_gpu", mux_pll_src_3plls_p, 0,
|
||||
RK2928_CLKSEL_CON(34), 8, 2, MFLAGS, 0, 5, DFLAGS,
|
||||
RK2928_CLKGATE_CON(3), 13, GFLAGS),
|
||||
|
||||
COMPOSITE(SCLK_SPI, "sclk_spi", mux_pll_src_3plls_p, 0,
|
||||
RK2928_CLKSEL_CON(25), 8, 2, MFLAGS, 0, 7, DFLAGS,
|
||||
RK2928_CLKGATE_CON(2), 9, GFLAGS),
|
||||
|
||||
COMPOSITE(SCLK_NANDC, "sclk_nandc", mux_pll_src_3plls_p, 0,
|
||||
RK2928_CLKSEL_CON(16), 8, 2, MFLAGS, 10, 5, DFLAGS,
|
||||
RK2928_CLKGATE_CON(10), 4, GFLAGS),
|
||||
|
||||
COMPOSITE(SCLK_SFC, "sclk_sfc", mux_pll_src_apll_dpll_gpll_usb480m_p, 0,
|
||||
RK2928_CLKSEL_CON(16), 0, 2, MFLAGS, 2, 5, DFLAGS,
|
||||
RK2928_CLKGATE_CON(10), 5, GFLAGS),
|
||||
|
||||
COMPOSITE_NOGATE(0, "mac_pll_src", mux_pll_src_3plls_p, 0,
|
||||
RK2928_CLKSEL_CON(21), 0, 2, MFLAGS, 4, 5, DFLAGS),
|
||||
MUX(SCLK_MACREF, "mac_clk_ref", mux_mac_p, CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKSEL_CON(21), 3, 1, MFLAGS),
|
||||
|
||||
COMPOSITE_NOMUX(SCLK_MAC, "mac_clk", "mac_clk_ref", 0,
|
||||
RK2928_CLKSEL_CON(21), 9, 5, DFLAGS,
|
||||
RK2928_CLKGATE_CON(2), 6, GFLAGS),
|
||||
|
||||
MUX(SCLK_HDMI, "dclk_hdmi", mux_dclk_p, 0,
|
||||
RK2928_CLKSEL_CON(31), 0, 1, MFLAGS),
|
||||
|
||||
/*
|
||||
* Clock-Architecture Diagram 3
|
||||
*/
|
||||
|
||||
/* aclk_cpu gates */
|
||||
GATE(0, "sclk_intmem", "aclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 12, GFLAGS),
|
||||
GATE(0, "aclk_strc_sys", "aclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 10, GFLAGS),
|
||||
|
||||
/* hclk_cpu gates */
|
||||
GATE(HCLK_ROM, "hclk_rom", "hclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 6, GFLAGS),
|
||||
|
||||
/* pclk_cpu gates */
|
||||
GATE(PCLK_GRF, "pclk_grf", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 4, GFLAGS),
|
||||
GATE(PCLK_DDRUPCTL, "pclk_ddrupctl", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 7, GFLAGS),
|
||||
GATE(PCLK_ACODEC, "pclk_acodec", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 14, GFLAGS),
|
||||
GATE(PCLK_HDMI, "pclk_hdmi", "pclk_cpu", 0, RK2928_CLKGATE_CON(3), 8, GFLAGS),
|
||||
|
||||
/* aclk_vio gates */
|
||||
GATE(ACLK_VIO, "aclk_vio", "aclk_disp1_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(6), 13, GFLAGS),
|
||||
GATE(ACLK_LCDC, "aclk_lcdc", "aclk_disp1_pre", 0, RK2928_CLKGATE_CON(9), 6, GFLAGS),
|
||||
|
||||
GATE(HCLK_VIO_BUS, "hclk_vio_bus", "hclk_disp_pre", 0, RK2928_CLKGATE_CON(6), 12, GFLAGS),
|
||||
GATE(HCLK_LCDC, "hclk_lcdc", "hclk_disp_pre", 0, RK2928_CLKGATE_CON(9), 5, GFLAGS),
|
||||
|
||||
/* hclk_video gates */
|
||||
GATE(HCLK_VCODEC, "hclk_vcodec", "hclk_disp_pre", 0, RK2928_CLKGATE_CON(3), 12, GFLAGS),
|
||||
|
||||
/* xin24m gates */
|
||||
GATE(SCLK_PVTM_CORE, "sclk_pvtm_core", "xin24m", 0, RK2928_CLKGATE_CON(10), 0, GFLAGS),
|
||||
GATE(SCLK_PVTM_GPU, "sclk_pvtm_gpu", "xin24m", 0, RK2928_CLKGATE_CON(10), 1, GFLAGS),
|
||||
|
||||
/* aclk_peri gates */
|
||||
GATE(0, "aclk_peri_axi_matrix", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 3, GFLAGS),
|
||||
GATE(0, "aclk_cpu_peri", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 2, GFLAGS),
|
||||
GATE(ACLK_DMAC2, "aclk_dmac2", "aclk_peri", 0, RK2928_CLKGATE_CON(5), 1, GFLAGS),
|
||||
GATE(0, "aclk_peri_niu", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 15, GFLAGS),
|
||||
|
||||
/* hclk_peri gates */
|
||||
GATE(0, "hclk_peri_matrix", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 0, GFLAGS),
|
||||
GATE(0, "hclk_usb_peri", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 13, GFLAGS),
|
||||
GATE(0, "hclk_peri_arbi", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 14, GFLAGS),
|
||||
GATE(HCLK_NANDC, "hclk_nandc", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 9, GFLAGS),
|
||||
GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 10, GFLAGS),
|
||||
GATE(HCLK_SDIO, "hclk_sdio", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 11, GFLAGS),
|
||||
GATE(HCLK_EMMC, "hclk_emmc", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 0, GFLAGS),
|
||||
GATE(HCLK_OTG0, "hclk_otg0", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 13, GFLAGS),
|
||||
GATE(HCLK_OTG1, "hclk_otg1", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(7), 3, GFLAGS),
|
||||
GATE(HCLK_I2S, "hclk_i2s", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 2, GFLAGS),
|
||||
GATE(0, "hclk_sfc", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(3), 14, GFLAGS),
|
||||
GATE(0, "hclk_mac", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(3), 15, GFLAGS),
|
||||
|
||||
/* pclk_peri gates */
|
||||
GATE(0, "pclk_peri_matrix", "pclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 1, GFLAGS),
|
||||
GATE(0, "pclk_efuse", "pclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 2, GFLAGS),
|
||||
GATE(PCLK_TIMER, "pclk_timer", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 7, GFLAGS),
|
||||
GATE(PCLK_PWM, "pclk_pwm", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 10, GFLAGS),
|
||||
GATE(PCLK_SPI, "pclk_spi", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 12, GFLAGS),
|
||||
GATE(PCLK_WDT, "pclk_wdt", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 15, GFLAGS),
|
||||
GATE(PCLK_UART0, "pclk_uart0", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 0, GFLAGS),
|
||||
GATE(PCLK_UART1, "pclk_uart1", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 1, GFLAGS),
|
||||
GATE(PCLK_UART2, "pclk_uart2", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 2, GFLAGS),
|
||||
GATE(PCLK_I2C0, "pclk_i2c0", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 4, GFLAGS),
|
||||
GATE(PCLK_I2C1, "pclk_i2c1", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 5, GFLAGS),
|
||||
GATE(PCLK_I2C2, "pclk_i2c2", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 6, GFLAGS),
|
||||
GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 9, GFLAGS),
|
||||
GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 10, GFLAGS),
|
||||
GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 11, GFLAGS),
|
||||
};
|
||||
|
||||
static const char *const rk3036_critical_clocks[] __initconst = {
|
||||
"aclk_cpu",
|
||||
"aclk_peri",
|
||||
"hclk_peri",
|
||||
"pclk_peri",
|
||||
};
|
||||
|
||||
static void __init rk3036_clk_init(struct device_node *np)
|
||||
{
|
||||
void __iomem *reg_base;
|
||||
struct clk *clk;
|
||||
|
||||
reg_base = of_iomap(np, 0);
|
||||
if (!reg_base) {
|
||||
pr_err("%s: could not map cru region\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
|
||||
|
||||
/* xin12m is created by an cru-internal divider */
|
||||
clk = clk_register_fixed_factor(NULL, "xin12m", "xin24m", 0, 1, 2);
|
||||
if (IS_ERR(clk))
|
||||
pr_warn("%s: could not register clock xin12m: %ld\n",
|
||||
__func__, PTR_ERR(clk));
|
||||
|
||||
clk = clk_register_fixed_factor(NULL, "usb480m", "xin24m", 0, 20, 1);
|
||||
if (IS_ERR(clk))
|
||||
pr_warn("%s: could not register clock usb480m: %ld\n",
|
||||
__func__, PTR_ERR(clk));
|
||||
|
||||
clk = clk_register_fixed_factor(NULL, "ddrphy", "ddrphy2x", 0, 1, 2);
|
||||
if (IS_ERR(clk))
|
||||
pr_warn("%s: could not register clock ddrphy: %ld\n",
|
||||
__func__, PTR_ERR(clk));
|
||||
|
||||
clk = clk_register_fixed_factor(NULL, "hclk_vcodec_pre",
|
||||
"aclk_vcodec", 0, 1, 4);
|
||||
if (IS_ERR(clk))
|
||||
pr_warn("%s: could not register clock hclk_vcodec_pre: %ld\n",
|
||||
__func__, PTR_ERR(clk));
|
||||
|
||||
clk = clk_register_fixed_factor(NULL, "sclk_macref_out",
|
||||
"hclk_peri_src", 0, 1, 2);
|
||||
if (IS_ERR(clk))
|
||||
pr_warn("%s: could not register clock sclk_macref_out: %ld\n",
|
||||
__func__, PTR_ERR(clk));
|
||||
|
||||
rockchip_clk_register_plls(rk3036_pll_clks,
|
||||
ARRAY_SIZE(rk3036_pll_clks),
|
||||
RK3036_GRF_SOC_STATUS0);
|
||||
rockchip_clk_register_branches(rk3036_clk_branches,
|
||||
ARRAY_SIZE(rk3036_clk_branches));
|
||||
rockchip_clk_protect_critical(rk3036_critical_clocks,
|
||||
ARRAY_SIZE(rk3036_critical_clocks));
|
||||
|
||||
rockchip_clk_register_armclk(ARMCLK, "armclk",
|
||||
mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
|
||||
&rk3036_cpuclk_data, rk3036_cpuclk_rates,
|
||||
ARRAY_SIZE(rk3036_cpuclk_rates));
|
||||
|
||||
rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0),
|
||||
ROCKCHIP_SOFTRST_HIWORD_MASK);
|
||||
|
||||
rockchip_register_restart_notifier(RK2928_GLB_SRST_FST, NULL);
|
||||
}
|
||||
CLK_OF_DECLARE(rk3036_cru, "rockchip,rk3036-cru", rk3036_clk_init);
|
@ -750,7 +750,7 @@ static void __init rk3188_common_clk_init(struct device_node *np)
|
||||
rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0),
|
||||
ROCKCHIP_SOFTRST_HIWORD_MASK);
|
||||
|
||||
rockchip_register_restart_notifier(RK2928_GLB_SRST_FST);
|
||||
rockchip_register_restart_notifier(RK2928_GLB_SRST_FST, NULL);
|
||||
}
|
||||
|
||||
static void __init rk3066a_clk_init(struct device_node *np)
|
||||
|
678
drivers/clk/rockchip/clk-rk3228.c
Normal file
678
drivers/clk/rockchip/clk-rk3228.c
Normal file
@ -0,0 +1,678 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Rockchip Electronics Co. Ltd.
|
||||
* Author: Xing Zheng <zhengxing@rock-chips.com>
|
||||
* Jeffy Chen <jeffy.chen@rock-chips.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/syscore_ops.h>
|
||||
#include <dt-bindings/clock/rk3228-cru.h>
|
||||
#include "clk.h"
|
||||
|
||||
#define RK3228_GRF_SOC_STATUS0 0x480
|
||||
|
||||
enum rk3228_plls {
|
||||
apll, dpll, cpll, gpll,
|
||||
};
|
||||
|
||||
static struct rockchip_pll_rate_table rk3228_pll_rates[] = {
|
||||
/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
|
||||
RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1584000000, 1, 66, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1560000000, 1, 65, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1536000000, 1, 64, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1512000000, 1, 63, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1488000000, 1, 62, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1464000000, 1, 61, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1440000000, 1, 60, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1416000000, 1, 59, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1392000000, 1, 58, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1368000000, 1, 57, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1344000000, 1, 56, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1320000000, 1, 55, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1296000000, 1, 54, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1272000000, 1, 53, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1248000000, 1, 52, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1188000000, 2, 99, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1104000000, 1, 46, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1100000000, 12, 550, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1000000000, 6, 500, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE( 984000000, 1, 82, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE( 960000000, 1, 80, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE( 936000000, 1, 78, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE( 912000000, 1, 76, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE( 900000000, 4, 300, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE( 888000000, 1, 74, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE( 864000000, 1, 72, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE( 840000000, 1, 70, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE( 816000000, 1, 68, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE( 800000000, 6, 400, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE( 700000000, 6, 350, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE( 696000000, 1, 58, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE( 600000000, 1, 75, 3, 1, 1, 0),
|
||||
RK3036_PLL_RATE( 594000000, 2, 99, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE( 504000000, 1, 63, 3, 1, 1, 0),
|
||||
RK3036_PLL_RATE( 500000000, 6, 250, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE( 408000000, 1, 68, 2, 2, 1, 0),
|
||||
RK3036_PLL_RATE( 312000000, 1, 52, 2, 2, 1, 0),
|
||||
RK3036_PLL_RATE( 216000000, 1, 72, 4, 2, 1, 0),
|
||||
RK3036_PLL_RATE( 96000000, 1, 64, 4, 4, 1, 0),
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
||||
#define RK3228_DIV_CPU_MASK 0x1f
|
||||
#define RK3228_DIV_CPU_SHIFT 8
|
||||
|
||||
#define RK3228_DIV_PERI_MASK 0xf
|
||||
#define RK3228_DIV_PERI_SHIFT 0
|
||||
#define RK3228_DIV_ACLK_MASK 0x7
|
||||
#define RK3228_DIV_ACLK_SHIFT 4
|
||||
#define RK3228_DIV_HCLK_MASK 0x3
|
||||
#define RK3228_DIV_HCLK_SHIFT 8
|
||||
#define RK3228_DIV_PCLK_MASK 0x7
|
||||
#define RK3228_DIV_PCLK_SHIFT 12
|
||||
|
||||
#define RK3228_CLKSEL1(_core_peri_div) \
|
||||
{ \
|
||||
.reg = RK2928_CLKSEL_CON(1), \
|
||||
.val = HIWORD_UPDATE(_core_peri_div, RK3228_DIV_PERI_MASK, \
|
||||
RK3228_DIV_PERI_SHIFT) \
|
||||
}
|
||||
|
||||
#define RK3228_CPUCLK_RATE(_prate, _core_peri_div) \
|
||||
{ \
|
||||
.prate = _prate, \
|
||||
.divs = { \
|
||||
RK3228_CLKSEL1(_core_peri_div), \
|
||||
}, \
|
||||
}
|
||||
|
||||
static struct rockchip_cpuclk_rate_table rk3228_cpuclk_rates[] __initdata = {
|
||||
RK3228_CPUCLK_RATE(816000000, 4),
|
||||
RK3228_CPUCLK_RATE(600000000, 4),
|
||||
RK3228_CPUCLK_RATE(312000000, 4),
|
||||
};
|
||||
|
||||
static const struct rockchip_cpuclk_reg_data rk3228_cpuclk_data = {
|
||||
.core_reg = RK2928_CLKSEL_CON(0),
|
||||
.div_core_shift = 0,
|
||||
.div_core_mask = 0x1f,
|
||||
.mux_core_shift = 6,
|
||||
};
|
||||
|
||||
PNAME(mux_pll_p) = { "clk_24m", "xin24m" };
|
||||
|
||||
PNAME(mux_ddrphy_p) = { "dpll_ddr", "gpll_ddr", "apll_ddr" };
|
||||
PNAME(mux_armclk_p) = { "apll_core", "gpll_core", "dpll_core" };
|
||||
PNAME(mux_usb480m_phy_p) = { "usb480m_phy0", "usb480m_phy1" };
|
||||
PNAME(mux_usb480m_p) = { "usb480m_phy", "xin24m" };
|
||||
PNAME(mux_hdmiphy_p) = { "hdmiphy_phy", "xin24m" };
|
||||
PNAME(mux_aclk_cpu_src_p) = { "cpll_aclk_cpu", "gpll_aclk_cpu", "hdmiphy_aclk_cpu" };
|
||||
|
||||
PNAME(mux_pll_src_4plls_p) = { "cpll", "gpll", "hdmiphy" "usb480m" };
|
||||
PNAME(mux_pll_src_3plls_p) = { "cpll", "gpll", "hdmiphy" };
|
||||
PNAME(mux_pll_src_2plls_p) = { "cpll", "gpll" };
|
||||
PNAME(mux_sclk_hdmi_cec_p) = { "cpll", "gpll", "xin24m" };
|
||||
PNAME(mux_aclk_peri_src_p) = { "cpll_peri", "gpll_peri", "hdmiphy_peri" };
|
||||
PNAME(mux_mmc_src_p) = { "cpll", "gpll", "xin24m", "usb480m" };
|
||||
PNAME(mux_pll_src_cpll_gpll_usb480m_p) = { "cpll", "gpll", "usb480m" };
|
||||
|
||||
PNAME(mux_sclk_rga_p) = { "gpll", "cpll", "sclk_rga_src" };
|
||||
|
||||
PNAME(mux_sclk_vop_src_p) = { "gpll_vop", "cpll_vop" };
|
||||
PNAME(mux_dclk_vop_p) = { "hdmiphy", "sclk_vop_pre" };
|
||||
|
||||
PNAME(mux_i2s0_p) = { "i2s0_src", "i2s0_frac", "ext_i2s", "xin12m" };
|
||||
PNAME(mux_i2s1_pre_p) = { "i2s1_src", "i2s1_frac", "ext_i2s", "xin12m" };
|
||||
PNAME(mux_i2s_out_p) = { "i2s1_pre", "xin12m" };
|
||||
PNAME(mux_i2s2_p) = { "i2s2_src", "i2s2_frac", "xin12m" };
|
||||
PNAME(mux_sclk_spdif_p) = { "sclk_spdif_src", "spdif_frac", "xin12m" };
|
||||
|
||||
PNAME(mux_aclk_gpu_pre_p) = { "cpll_gpu", "gpll_gpu", "hdmiphy_gpu", "usb480m_gpu" };
|
||||
|
||||
PNAME(mux_uart0_p) = { "uart0_src", "uart0_frac", "xin24m" };
|
||||
PNAME(mux_uart1_p) = { "uart1_src", "uart1_frac", "xin24m" };
|
||||
PNAME(mux_uart2_p) = { "uart2_src", "uart2_frac", "xin24m" };
|
||||
|
||||
PNAME(mux_sclk_macphy_50m_p) = { "ext_gmac", "phy_50m_out" };
|
||||
PNAME(mux_sclk_gmac_pre_p) = { "sclk_gmac_src", "sclk_macphy_50m" };
|
||||
PNAME(mux_sclk_macphy_p) = { "sclk_gmac_src", "ext_gmac" };
|
||||
|
||||
static struct rockchip_pll_clock rk3228_pll_clks[] __initdata = {
|
||||
[apll] = PLL(pll_rk3036, PLL_APLL, "apll", mux_pll_p, 0, RK2928_PLL_CON(0),
|
||||
RK2928_MODE_CON, 0, 7, 0, rk3228_pll_rates),
|
||||
[dpll] = PLL(pll_rk3036, PLL_DPLL, "dpll", mux_pll_p, 0, RK2928_PLL_CON(3),
|
||||
RK2928_MODE_CON, 4, 6, 0, NULL),
|
||||
[cpll] = PLL(pll_rk3036, PLL_CPLL, "cpll", mux_pll_p, 0, RK2928_PLL_CON(6),
|
||||
RK2928_MODE_CON, 8, 8, 0, NULL),
|
||||
[gpll] = PLL(pll_rk3036, PLL_GPLL, "gpll", mux_pll_p, 0, RK2928_PLL_CON(9),
|
||||
RK2928_MODE_CON, 12, 9, ROCKCHIP_PLL_SYNC_RATE, rk3228_pll_rates),
|
||||
};
|
||||
|
||||
#define MFLAGS CLK_MUX_HIWORD_MASK
|
||||
#define DFLAGS CLK_DIVIDER_HIWORD_MASK
|
||||
#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE)
|
||||
|
||||
static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
|
||||
/*
|
||||
* Clock-Architecture Diagram 1
|
||||
*/
|
||||
|
||||
DIV(0, "clk_24m", "xin24m", CLK_IGNORE_UNUSED,
|
||||
RK2928_CLKSEL_CON(4), 8, 5, DFLAGS),
|
||||
|
||||
/* PD_DDR */
|
||||
GATE(0, "apll_ddr", "apll", CLK_IGNORE_UNUSED,
|
||||
RK2928_CLKGATE_CON(0), 2, GFLAGS),
|
||||
GATE(0, "dpll_ddr", "dpll", CLK_IGNORE_UNUSED,
|
||||
RK2928_CLKGATE_CON(0), 2, GFLAGS),
|
||||
GATE(0, "gpll_ddr", "gpll", CLK_IGNORE_UNUSED,
|
||||
RK2928_CLKGATE_CON(0), 2, GFLAGS),
|
||||
COMPOSITE(0, "ddrphy4x", mux_ddrphy_p, CLK_IGNORE_UNUSED,
|
||||
RK2928_CLKSEL_CON(26), 8, 2, MFLAGS, 0, 3, DFLAGS | CLK_DIVIDER_POWER_OF_TWO,
|
||||
RK2928_CLKGATE_CON(7), 1, GFLAGS),
|
||||
GATE(0, "ddrc", "ddrphy_pre", CLK_IGNORE_UNUSED,
|
||||
RK2928_CLKGATE_CON(8), 5, GFLAGS),
|
||||
GATE(0, "ddrphy", "ddrphy_pre", CLK_IGNORE_UNUSED,
|
||||
RK2928_CLKGATE_CON(7), 0, GFLAGS),
|
||||
|
||||
/* PD_CORE */
|
||||
GATE(0, "dpll_core", "dpll", CLK_IGNORE_UNUSED,
|
||||
RK2928_CLKGATE_CON(0), 6, GFLAGS),
|
||||
GATE(0, "apll_core", "apll", CLK_IGNORE_UNUSED,
|
||||
RK2928_CLKGATE_CON(0), 6, GFLAGS),
|
||||
GATE(0, "gpll_core", "gpll", CLK_IGNORE_UNUSED,
|
||||
RK2928_CLKGATE_CON(0), 6, GFLAGS),
|
||||
COMPOSITE_NOMUX(0, "pclk_dbg", "armclk", CLK_IGNORE_UNUSED,
|
||||
RK2928_CLKSEL_CON(1), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
|
||||
RK2928_CLKGATE_CON(4), 1, GFLAGS),
|
||||
COMPOSITE_NOMUX(0, "armcore", "armclk", CLK_IGNORE_UNUSED,
|
||||
RK2928_CLKSEL_CON(1), 4, 3, DFLAGS | CLK_DIVIDER_READ_ONLY,
|
||||
RK2928_CLKGATE_CON(4), 0, GFLAGS),
|
||||
|
||||
/* PD_MISC */
|
||||
MUX(0, "hdmiphy", mux_hdmiphy_p, CLK_SET_RATE_PARENT,
|
||||
RK2928_MISC_CON, 13, 1, MFLAGS),
|
||||
MUX(0, "usb480m_phy", mux_usb480m_phy_p, CLK_SET_RATE_PARENT,
|
||||
RK2928_MISC_CON, 14, 1, MFLAGS),
|
||||
MUX(0, "usb480m", mux_usb480m_p, CLK_SET_RATE_PARENT,
|
||||
RK2928_MISC_CON, 15, 1, MFLAGS),
|
||||
|
||||
/* PD_BUS */
|
||||
GATE(0, "hdmiphy_aclk_cpu", "hdmiphy", CLK_IGNORE_UNUSED,
|
||||
RK2928_CLKGATE_CON(0), 1, GFLAGS),
|
||||
GATE(0, "gpll_aclk_cpu", "gpll", CLK_IGNORE_UNUSED,
|
||||
RK2928_CLKGATE_CON(0), 1, GFLAGS),
|
||||
GATE(0, "cpll_aclk_cpu", "cpll", CLK_IGNORE_UNUSED,
|
||||
RK2928_CLKGATE_CON(0), 1, GFLAGS),
|
||||
COMPOSITE_NOGATE(0, "aclk_cpu_src", mux_aclk_cpu_src_p, 0,
|
||||
RK2928_CLKSEL_CON(0), 13, 2, MFLAGS, 8, 5, DFLAGS),
|
||||
GATE(ARMCLK, "aclk_cpu", "aclk_cpu_src", 0,
|
||||
RK2928_CLKGATE_CON(6), 0, GFLAGS),
|
||||
COMPOSITE_NOMUX(0, "hclk_cpu", "aclk_cpu_src", 0,
|
||||
RK2928_CLKSEL_CON(1), 8, 2, DFLAGS,
|
||||
RK2928_CLKGATE_CON(6), 1, GFLAGS),
|
||||
COMPOSITE_NOMUX(0, "pclk_bus_src", "aclk_cpu_src", 0,
|
||||
RK2928_CLKSEL_CON(1), 12, 3, DFLAGS,
|
||||
RK2928_CLKGATE_CON(6), 2, GFLAGS),
|
||||
GATE(0, "pclk_cpu", "pclk_bus_src", 0,
|
||||
RK2928_CLKGATE_CON(6), 3, GFLAGS),
|
||||
GATE(0, "pclk_phy_pre", "pclk_bus_src", 0,
|
||||
RK2928_CLKGATE_CON(6), 4, GFLAGS),
|
||||
GATE(0, "pclk_ddr_pre", "pclk_bus_src", 0,
|
||||
RK2928_CLKGATE_CON(6), 13, GFLAGS),
|
||||
|
||||
/* PD_VIDEO */
|
||||
COMPOSITE(0, "aclk_vpu_pre", mux_pll_src_4plls_p, 0,
|
||||
RK2928_CLKSEL_CON(32), 5, 2, MFLAGS, 0, 5, DFLAGS,
|
||||
RK2928_CLKGATE_CON(3), 11, GFLAGS),
|
||||
GATE(0, "hclk_vpu_src", "aclk_vpu_pre", 0,
|
||||
RK2928_CLKGATE_CON(4), 4, GFLAGS),
|
||||
|
||||
COMPOSITE(0, "aclk_rkvdec_pre", mux_pll_src_4plls_p, 0,
|
||||
RK2928_CLKSEL_CON(28), 6, 2, MFLAGS, 0, 5, DFLAGS,
|
||||
RK2928_CLKGATE_CON(3), 2, GFLAGS),
|
||||
GATE(0, "hclk_rkvdec_src", "aclk_rkvdec_pre", 0,
|
||||
RK2928_CLKGATE_CON(4), 5, GFLAGS),
|
||||
|
||||
COMPOSITE(0, "sclk_vdec_cabac", mux_pll_src_4plls_p, 0,
|
||||
RK2928_CLKSEL_CON(28), 14, 2, MFLAGS, 8, 5, DFLAGS,
|
||||
RK2928_CLKGATE_CON(3), 3, GFLAGS),
|
||||
|
||||
COMPOSITE(0, "sclk_vdec_core", mux_pll_src_4plls_p, 0,
|
||||
RK2928_CLKSEL_CON(34), 13, 2, MFLAGS, 8, 5, DFLAGS,
|
||||
RK2928_CLKGATE_CON(3), 4, GFLAGS),
|
||||
|
||||
/* PD_VIO */
|
||||
COMPOSITE(0, "aclk_iep_pre", mux_pll_src_4plls_p, 0,
|
||||
RK2928_CLKSEL_CON(31), 5, 2, MFLAGS, 0, 5, DFLAGS,
|
||||
RK2928_CLKGATE_CON(3), 0, GFLAGS),
|
||||
DIV(0, "hclk_vio_pre", "aclk_iep_pre", 0,
|
||||
RK2928_CLKSEL_CON(2), 0, 5, DFLAGS),
|
||||
|
||||
COMPOSITE(0, "aclk_hdcp_pre", mux_pll_src_4plls_p, 0,
|
||||
RK2928_CLKSEL_CON(31), 13, 2, MFLAGS, 8, 5, DFLAGS,
|
||||
RK2928_CLKGATE_CON(1), 4, GFLAGS),
|
||||
|
||||
MUX(0, "sclk_rga_src", mux_pll_src_4plls_p, 0,
|
||||
RK2928_CLKSEL_CON(33), 13, 2, MFLAGS),
|
||||
COMPOSITE_NOMUX(0, "aclk_rga_pre", "sclk_rga_src", 0,
|
||||
RK2928_CLKSEL_CON(33), 8, 5, DFLAGS,
|
||||
RK2928_CLKGATE_CON(1), 2, GFLAGS),
|
||||
COMPOSITE(0, "sclk_rga", mux_sclk_rga_p, 0,
|
||||
RK2928_CLKSEL_CON(22), 5, 2, MFLAGS, 0, 5, DFLAGS,
|
||||
RK2928_CLKGATE_CON(3), 6, GFLAGS),
|
||||
|
||||
COMPOSITE(0, "aclk_vop_pre", mux_pll_src_4plls_p, 0,
|
||||
RK2928_CLKSEL_CON(33), 5, 2, MFLAGS, 0, 5, DFLAGS,
|
||||
RK2928_CLKGATE_CON(1), 1, GFLAGS),
|
||||
|
||||
COMPOSITE(0, "sclk_hdcp", mux_pll_src_3plls_p, 0,
|
||||
RK2928_CLKSEL_CON(23), 14, 2, MFLAGS, 8, 6, DFLAGS,
|
||||
RK2928_CLKGATE_CON(3), 5, GFLAGS),
|
||||
|
||||
GATE(0, "sclk_hdmi_hdcp", "xin24m", 0,
|
||||
RK2928_CLKGATE_CON(3), 7, GFLAGS),
|
||||
|
||||
COMPOSITE(0, "sclk_hdmi_cec", mux_sclk_hdmi_cec_p, 0,
|
||||
RK2928_CLKSEL_CON(21), 14, 2, MFLAGS, 0, 14, DFLAGS,
|
||||
RK2928_CLKGATE_CON(3), 8, GFLAGS),
|
||||
|
||||
/* PD_PERI */
|
||||
GATE(0, "cpll_peri", "cpll", CLK_IGNORE_UNUSED,
|
||||
RK2928_CLKGATE_CON(2), 0, GFLAGS),
|
||||
GATE(0, "gpll_peri", "gpll", CLK_IGNORE_UNUSED,
|
||||
RK2928_CLKGATE_CON(2), 0, GFLAGS),
|
||||
GATE(0, "hdmiphy_peri", "hdmiphy", CLK_IGNORE_UNUSED,
|
||||
RK2928_CLKGATE_CON(2), 0, GFLAGS),
|
||||
COMPOSITE_NOGATE(0, "aclk_peri_src", mux_aclk_peri_src_p, 0,
|
||||
RK2928_CLKSEL_CON(10), 10, 2, MFLAGS, 0, 5, DFLAGS),
|
||||
COMPOSITE_NOMUX(PCLK_PERI, "pclk_peri", "aclk_peri_src", 0,
|
||||
RK2928_CLKSEL_CON(10), 12, 3, DFLAGS,
|
||||
RK2928_CLKGATE_CON(5), 2, GFLAGS),
|
||||
COMPOSITE_NOMUX(HCLK_PERI, "hclk_peri", "aclk_peri_src", 0,
|
||||
RK2928_CLKSEL_CON(10), 8, 2, DFLAGS,
|
||||
RK2928_CLKGATE_CON(5), 1, GFLAGS),
|
||||
GATE(ACLK_PERI, "aclk_peri", "aclk_peri_src", 0,
|
||||
RK2928_CLKGATE_CON(5), 0, GFLAGS),
|
||||
|
||||
GATE(SCLK_TIMER0, "sclk_timer0", "xin24m", 0,
|
||||
RK2928_CLKGATE_CON(6), 5, GFLAGS),
|
||||
GATE(SCLK_TIMER1, "sclk_timer1", "xin24m", 0,
|
||||
RK2928_CLKGATE_CON(6), 6, GFLAGS),
|
||||
GATE(SCLK_TIMER2, "sclk_timer2", "xin24m", 0,
|
||||
RK2928_CLKGATE_CON(6), 7, GFLAGS),
|
||||
GATE(SCLK_TIMER3, "sclk_timer3", "xin24m", 0,
|
||||
RK2928_CLKGATE_CON(6), 8, GFLAGS),
|
||||
GATE(SCLK_TIMER4, "sclk_timer4", "xin24m", 0,
|
||||
RK2928_CLKGATE_CON(6), 9, GFLAGS),
|
||||
GATE(SCLK_TIMER5, "sclk_timer5", "xin24m", 0,
|
||||
RK2928_CLKGATE_CON(6), 10, GFLAGS),
|
||||
|
||||
COMPOSITE(0, "sclk_crypto", mux_pll_src_2plls_p, 0,
|
||||
RK2928_CLKSEL_CON(24), 5, 1, MFLAGS, 0, 5, DFLAGS,
|
||||
RK2928_CLKGATE_CON(2), 7, GFLAGS),
|
||||
|
||||
COMPOSITE(0, "sclk_tsp", mux_pll_src_2plls_p, 0,
|
||||
RK2928_CLKSEL_CON(22), 15, 1, MFLAGS, 8, 5, DFLAGS,
|
||||
RK2928_CLKGATE_CON(2), 6, GFLAGS),
|
||||
|
||||
GATE(0, "sclk_hsadc", "ext_hsadc", 0,
|
||||
RK3288_CLKGATE_CON(10), 12, GFLAGS),
|
||||
|
||||
COMPOSITE(0, "sclk_wifi", mux_pll_src_cpll_gpll_usb480m_p, 0,
|
||||
RK2928_CLKSEL_CON(23), 5, 2, MFLAGS, 0, 6, DFLAGS,
|
||||
RK2928_CLKGATE_CON(2), 15, GFLAGS),
|
||||
|
||||
COMPOSITE(SCLK_SDMMC, "sclk_sdmmc0", mux_mmc_src_p, 0,
|
||||
RK2928_CLKSEL_CON(11), 8, 2, MFLAGS, 0, 8, DFLAGS,
|
||||
RK2928_CLKGATE_CON(2), 11, GFLAGS),
|
||||
|
||||
COMPOSITE_NODIV(0, "sclk_sdio_src", mux_mmc_src_p, 0,
|
||||
RK2928_CLKSEL_CON(11), 10, 2, MFLAGS,
|
||||
RK2928_CLKGATE_CON(2), 13, GFLAGS),
|
||||
DIV(SCLK_SDIO, "sclk_sdio", "sclk_sdio_src", 0,
|
||||
RK2928_CLKSEL_CON(12), 0, 8, DFLAGS),
|
||||
|
||||
COMPOSITE_NODIV(0, "sclk_emmc_src", mux_mmc_src_p, 0,
|
||||
RK2928_CLKSEL_CON(11), 12, 2, MFLAGS,
|
||||
RK2928_CLKGATE_CON(2), 14, GFLAGS),
|
||||
DIV(SCLK_EMMC, "sclk_emmc", "sclk_emmc_src", 0,
|
||||
RK2928_CLKSEL_CON(12), 8, 8, DFLAGS),
|
||||
|
||||
/*
|
||||
* Clock-Architecture Diagram 2
|
||||
*/
|
||||
|
||||
GATE(0, "gpll_vop", "gpll", 0,
|
||||
RK2928_CLKGATE_CON(3), 1, GFLAGS),
|
||||
GATE(0, "cpll_vop", "cpll", 0,
|
||||
RK2928_CLKGATE_CON(3), 1, GFLAGS),
|
||||
MUX(0, "sclk_vop_src", mux_sclk_vop_src_p, 0,
|
||||
RK2928_CLKSEL_CON(27), 0, 1, MFLAGS),
|
||||
DIV(0, "dclk_hdmiphy", "sclk_vop_src", 0,
|
||||
RK2928_CLKSEL_CON(29), 0, 3, DFLAGS),
|
||||
DIV(0, "sclk_vop_pre", "sclk_vop_src", 0,
|
||||
RK2928_CLKSEL_CON(27), 8, 8, DFLAGS),
|
||||
MUX(0, "dclk_vop", mux_dclk_vop_p, 0,
|
||||
RK2928_CLKSEL_CON(27), 1, 1, MFLAGS),
|
||||
|
||||
COMPOSITE(0, "i2s0_src", mux_pll_src_2plls_p, 0,
|
||||
RK2928_CLKSEL_CON(9), 15, 1, MFLAGS, 0, 7, DFLAGS,
|
||||
RK2928_CLKGATE_CON(0), 3, GFLAGS),
|
||||
COMPOSITE_FRAC(0, "i2s0_frac", "i2s0_src", CLK_SET_RATE_PARENT,
|
||||
RK3288_CLKSEL_CON(8), 0,
|
||||
RK3288_CLKGATE_CON(0), 4, GFLAGS),
|
||||
COMPOSITE_NODIV(SCLK_I2S0, "sclk_i2s0", mux_i2s0_p, 0,
|
||||
RK2928_CLKSEL_CON(9), 8, 2, MFLAGS,
|
||||
RK2928_CLKGATE_CON(0), 5, GFLAGS),
|
||||
|
||||
COMPOSITE(0, "i2s1_src", mux_pll_src_2plls_p, 0,
|
||||
RK2928_CLKSEL_CON(3), 15, 1, MFLAGS, 0, 7, DFLAGS,
|
||||
RK2928_CLKGATE_CON(0), 10, GFLAGS),
|
||||
COMPOSITE_FRAC(0, "i2s1_frac", "i2s1_src", CLK_SET_RATE_PARENT,
|
||||
RK3288_CLKSEL_CON(7), 0,
|
||||
RK3288_CLKGATE_CON(0), 11, GFLAGS),
|
||||
MUX(0, "i2s1_pre", mux_i2s1_pre_p, 0,
|
||||
RK2928_CLKSEL_CON(3), 8, 2, MFLAGS),
|
||||
GATE(SCLK_I2S1, "sclk_i2s1", "i2s1_pre", 0,
|
||||
RK2928_CLKGATE_CON(0), 14, GFLAGS),
|
||||
COMPOSITE_NODIV(SCLK_I2S_OUT, "i2s_out", mux_i2s_out_p, 0,
|
||||
RK2928_CLKSEL_CON(3), 12, 1, MFLAGS,
|
||||
RK2928_CLKGATE_CON(0), 13, GFLAGS),
|
||||
|
||||
COMPOSITE(0, "i2s2_src", mux_pll_src_2plls_p, 0,
|
||||
RK2928_CLKSEL_CON(16), 15, 1, MFLAGS, 0, 7, DFLAGS,
|
||||
RK2928_CLKGATE_CON(0), 7, GFLAGS),
|
||||
COMPOSITE_FRAC(0, "i2s2_frac", "i2s2_src", CLK_SET_RATE_PARENT,
|
||||
RK3288_CLKSEL_CON(30), 0,
|
||||
RK3288_CLKGATE_CON(0), 8, GFLAGS),
|
||||
COMPOSITE_NODIV(SCLK_I2S2, "sclk_i2s2", mux_i2s2_p, 0,
|
||||
RK2928_CLKSEL_CON(16), 8, 2, MFLAGS,
|
||||
RK2928_CLKGATE_CON(0), 9, GFLAGS),
|
||||
|
||||
COMPOSITE(0, "sclk_spdif_src", mux_pll_src_2plls_p, 0,
|
||||
RK2928_CLKSEL_CON(6), 15, 1, MFLAGS, 0, 7, DFLAGS,
|
||||
RK2928_CLKGATE_CON(2), 10, GFLAGS),
|
||||
COMPOSITE_FRAC(0, "spdif_frac", "sclk_spdif_src", CLK_SET_RATE_PARENT,
|
||||
RK3288_CLKSEL_CON(20), 0,
|
||||
RK3288_CLKGATE_CON(2), 12, GFLAGS),
|
||||
MUX(SCLK_SPDIF, "sclk_spdif", mux_sclk_spdif_p, 0,
|
||||
RK2928_CLKSEL_CON(6), 8, 2, MFLAGS),
|
||||
|
||||
GATE(0, "jtag", "ext_jtag", 0,
|
||||
RK2928_CLKGATE_CON(1), 3, GFLAGS),
|
||||
|
||||
GATE(0, "sclk_otgphy0", "xin24m", 0,
|
||||
RK2928_CLKGATE_CON(1), 5, GFLAGS),
|
||||
GATE(0, "sclk_otgphy1", "xin24m", 0,
|
||||
RK2928_CLKGATE_CON(1), 6, GFLAGS),
|
||||
|
||||
COMPOSITE_NOMUX(0, "sclk_tsadc", "xin24m", 0,
|
||||
RK2928_CLKSEL_CON(24), 6, 10, DFLAGS,
|
||||
RK2928_CLKGATE_CON(2), 8, GFLAGS),
|
||||
|
||||
GATE(0, "cpll_gpu", "cpll", 0,
|
||||
RK2928_CLKGATE_CON(3), 13, GFLAGS),
|
||||
GATE(0, "gpll_gpu", "gpll", 0,
|
||||
RK2928_CLKGATE_CON(3), 13, GFLAGS),
|
||||
GATE(0, "hdmiphy_gpu", "hdmiphy", 0,
|
||||
RK2928_CLKGATE_CON(3), 13, GFLAGS),
|
||||
GATE(0, "usb480m_gpu", "usb480m", 0,
|
||||
RK2928_CLKGATE_CON(3), 13, GFLAGS),
|
||||
COMPOSITE_NOGATE(0, "aclk_gpu_pre", mux_aclk_gpu_pre_p, 0,
|
||||
RK2928_CLKSEL_CON(34), 5, 2, MFLAGS, 0, 5, DFLAGS),
|
||||
|
||||
COMPOSITE(SCLK_SPI0, "sclk_spi0", mux_pll_src_2plls_p, 0,
|
||||
RK2928_CLKSEL_CON(25), 8, 1, MFLAGS, 0, 7, DFLAGS,
|
||||
RK2928_CLKGATE_CON(2), 9, GFLAGS),
|
||||
|
||||
/* PD_UART */
|
||||
COMPOSITE(0, "uart0_src", mux_pll_src_cpll_gpll_usb480m_p, 0,
|
||||
RK2928_CLKSEL_CON(13), 12, 2, MFLAGS, 0, 7, DFLAGS,
|
||||
RK2928_CLKGATE_CON(1), 8, GFLAGS),
|
||||
COMPOSITE(0, "uart1_src", mux_pll_src_cpll_gpll_usb480m_p, 0,
|
||||
RK2928_CLKSEL_CON(14), 12, 2, MFLAGS, 0, 7, DFLAGS,
|
||||
RK2928_CLKGATE_CON(1), 10, GFLAGS),
|
||||
COMPOSITE(0, "uart2_src", mux_pll_src_cpll_gpll_usb480m_p,
|
||||
0, RK2928_CLKSEL_CON(15), 12, 2,
|
||||
MFLAGS, 0, 7, DFLAGS, RK2928_CLKGATE_CON(1), 12, GFLAGS),
|
||||
COMPOSITE_FRAC(0, "uart0_frac", "uart0_src", CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKSEL_CON(17), 0,
|
||||
RK2928_CLKGATE_CON(1), 9, GFLAGS),
|
||||
COMPOSITE_FRAC(0, "uart1_frac", "uart1_src", CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKSEL_CON(18), 0,
|
||||
RK2928_CLKGATE_CON(1), 11, GFLAGS),
|
||||
COMPOSITE_FRAC(0, "uart2_frac", "uart2_src", CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKSEL_CON(19), 0,
|
||||
RK2928_CLKGATE_CON(1), 13, GFLAGS),
|
||||
MUX(SCLK_UART0, "sclk_uart0", mux_uart0_p, CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKSEL_CON(13), 8, 2, MFLAGS),
|
||||
MUX(SCLK_UART1, "sclk_uart1", mux_uart1_p, CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKSEL_CON(14), 8, 2, MFLAGS),
|
||||
MUX(SCLK_UART2, "sclk_uart2", mux_uart2_p, CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKSEL_CON(15), 8, 2, MFLAGS),
|
||||
|
||||
COMPOSITE(SCLK_NANDC, "sclk_nandc", mux_pll_src_2plls_p, 0,
|
||||
RK2928_CLKSEL_CON(2), 14, 1, MFLAGS, 8, 5, DFLAGS,
|
||||
RK2928_CLKGATE_CON(1), 0, GFLAGS),
|
||||
|
||||
COMPOSITE(0, "sclk_gmac_src", mux_pll_src_2plls_p, 0,
|
||||
RK2928_CLKSEL_CON(5), 7, 1, MFLAGS, 0, 5, DFLAGS,
|
||||
RK2928_CLKGATE_CON(1), 7, GFLAGS),
|
||||
MUX(0, "sclk_macphy_50m", mux_sclk_macphy_50m_p, 0,
|
||||
RK2928_CLKSEL_CON(29), 10, 1, MFLAGS),
|
||||
MUX(0, "sclk_gmac_pre", mux_sclk_gmac_pre_p, 0,
|
||||
RK2928_CLKSEL_CON(5), 5, 1, MFLAGS),
|
||||
GATE(0, "sclk_mac_refout", "sclk_gmac_pre", 0,
|
||||
RK2928_CLKGATE_CON(5), 4, GFLAGS),
|
||||
GATE(0, "sclk_mac_ref", "sclk_gmac_pre", 0,
|
||||
RK2928_CLKGATE_CON(5), 3, GFLAGS),
|
||||
GATE(0, "sclk_mac_rx", "sclk_gmac_pre", 0,
|
||||
RK2928_CLKGATE_CON(5), 5, GFLAGS),
|
||||
GATE(0, "sclk_mac_tx", "sclk_gmac_pre", 0,
|
||||
RK2928_CLKGATE_CON(5), 6, GFLAGS),
|
||||
COMPOSITE(0, "sclk_macphy", mux_sclk_macphy_p, 0,
|
||||
RK2928_CLKSEL_CON(29), 12, 1, MFLAGS, 8, 2, DFLAGS,
|
||||
RK2928_CLKGATE_CON(5), 7, GFLAGS),
|
||||
COMPOSITE(0, "sclk_gmac_out", mux_pll_src_2plls_p, 0,
|
||||
RK2928_CLKSEL_CON(5), 15, 1, MFLAGS, 8, 5, DFLAGS,
|
||||
RK2928_CLKGATE_CON(2), 2, GFLAGS),
|
||||
|
||||
/*
|
||||
* Clock-Architecture Diagram 3
|
||||
*/
|
||||
|
||||
/* PD_VOP */
|
||||
GATE(0, "aclk_rga", "aclk_rga_pre", 0, RK2928_CLKGATE_CON(13), 0, GFLAGS),
|
||||
GATE(0, "aclk_rga_noc", "aclk_rga_pre", 0, RK2928_CLKGATE_CON(13), 11, GFLAGS),
|
||||
GATE(0, "aclk_iep", "aclk_iep_pre", 0, RK2928_CLKGATE_CON(13), 2, GFLAGS),
|
||||
GATE(0, "aclk_iep_noc", "aclk_iep_pre", 0, RK2928_CLKGATE_CON(13), 9, GFLAGS),
|
||||
|
||||
GATE(0, "aclk_vop", "aclk_vop_pre", 0, RK2928_CLKGATE_CON(13), 5, GFLAGS),
|
||||
GATE(0, "aclk_vop_noc", "aclk_vop_pre", 0, RK2928_CLKGATE_CON(13), 12, GFLAGS),
|
||||
|
||||
GATE(0, "aclk_hdcp", "aclk_hdcp_pre", 0, RK2928_CLKGATE_CON(14), 10, GFLAGS),
|
||||
GATE(0, "aclk_hdcp_noc", "aclk_hdcp_pre", 0, RK2928_CLKGATE_CON(13), 10, GFLAGS),
|
||||
|
||||
GATE(0, "hclk_rga", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 1, GFLAGS),
|
||||
GATE(0, "hclk_iep", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 3, GFLAGS),
|
||||
GATE(0, "hclk_vop", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 6, GFLAGS),
|
||||
GATE(0, "hclk_vio_ahb_arbi", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 7, GFLAGS),
|
||||
GATE(0, "hclk_vio_noc", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 8, GFLAGS),
|
||||
GATE(0, "hclk_vop_noc", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 13, GFLAGS),
|
||||
GATE(0, "hclk_vio_h2p", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 7, GFLAGS),
|
||||
GATE(0, "hclk_hdcp_mmu", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 12, GFLAGS),
|
||||
GATE(0, "pclk_hdmi_ctrl", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 6, GFLAGS),
|
||||
GATE(0, "pclk_vio_h2p", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 8, GFLAGS),
|
||||
GATE(0, "pclk_hdcp", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 11, GFLAGS),
|
||||
|
||||
/* PD_PERI */
|
||||
GATE(0, "aclk_peri_noc", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(12), 0, GFLAGS),
|
||||
GATE(0, "aclk_gmac", "aclk_peri", 0, RK2928_CLKGATE_CON(11), 4, GFLAGS),
|
||||
|
||||
GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 0, GFLAGS),
|
||||
GATE(HCLK_SDIO, "hclk_sdio", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 1, GFLAGS),
|
||||
GATE(HCLK_EMMC, "hclk_emmc", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 2, GFLAGS),
|
||||
GATE(HCLK_NANDC, "hclk_nandc", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 3, GFLAGS),
|
||||
GATE(0, "hclk_host0", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 6, GFLAGS),
|
||||
GATE(0, "hclk_host0_arb", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 7, GFLAGS),
|
||||
GATE(0, "hclk_host1", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 8, GFLAGS),
|
||||
GATE(0, "hclk_host1_arb", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 9, GFLAGS),
|
||||
GATE(0, "hclk_host2", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 10, GFLAGS),
|
||||
GATE(0, "hclk_otg", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 12, GFLAGS),
|
||||
GATE(0, "hclk_otg_pmu", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 13, GFLAGS),
|
||||
GATE(0, "hclk_host2_arb", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 14, GFLAGS),
|
||||
GATE(0, "hclk_peri_noc", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(12), 1, GFLAGS),
|
||||
|
||||
GATE(0, "pclk_gmac", "pclk_peri", 0, RK2928_CLKGATE_CON(11), 5, GFLAGS),
|
||||
GATE(0, "pclk_peri_noc", "pclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(12), 2, GFLAGS),
|
||||
|
||||
/* PD_GPU */
|
||||
GATE(0, "aclk_gpu", "aclk_gpu_pre", 0, RK2928_CLKGATE_CON(13), 14, GFLAGS),
|
||||
GATE(0, "aclk_gpu_noc", "aclk_gpu_pre", 0, RK2928_CLKGATE_CON(13), 15, GFLAGS),
|
||||
|
||||
/* PD_BUS */
|
||||
GATE(0, "sclk_initmem_mbist", "aclk_cpu", 0, RK2928_CLKGATE_CON(8), 1, GFLAGS),
|
||||
GATE(0, "aclk_initmem", "aclk_cpu", 0, RK2928_CLKGATE_CON(8), 0, GFLAGS),
|
||||
GATE(ACLK_DMAC, "aclk_dmac_bus", "aclk_cpu", 0, RK2928_CLKGATE_CON(8), 2, GFLAGS),
|
||||
GATE(0, "aclk_bus_noc", "aclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(10), 1, GFLAGS),
|
||||
|
||||
GATE(0, "hclk_rom", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 3, GFLAGS),
|
||||
GATE(0, "hclk_i2s0_8ch", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 7, GFLAGS),
|
||||
GATE(0, "hclk_i2s1_8ch", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 8, GFLAGS),
|
||||
GATE(0, "hclk_i2s2_2ch", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 9, GFLAGS),
|
||||
GATE(0, "hclk_spdif_8ch", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 10, GFLAGS),
|
||||
GATE(0, "hclk_tsp", "hclk_cpu", 0, RK2928_CLKGATE_CON(10), 11, GFLAGS),
|
||||
GATE(0, "hclk_crypto_mst", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 11, GFLAGS),
|
||||
GATE(0, "hclk_crypto_slv", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 12, GFLAGS),
|
||||
|
||||
GATE(0, "pclk_ddrupctl", "pclk_ddr_pre", 0, RK2928_CLKGATE_CON(8), 4, GFLAGS),
|
||||
GATE(0, "pclk_ddrmon", "pclk_ddr_pre", 0, RK2928_CLKGATE_CON(8), 6, GFLAGS),
|
||||
GATE(0, "pclk_msch_noc", "pclk_ddr_pre", 0, RK2928_CLKGATE_CON(10), 2, GFLAGS),
|
||||
|
||||
GATE(0, "pclk_efuse_1024", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 13, GFLAGS),
|
||||
GATE(0, "pclk_efuse_256", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 14, GFLAGS),
|
||||
GATE(PCLK_I2C0, "pclk_i2c0", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 15, GFLAGS),
|
||||
GATE(PCLK_I2C1, "pclk_i2c1", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 0, GFLAGS),
|
||||
GATE(PCLK_I2C2, "pclk_i2c2", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 1, GFLAGS),
|
||||
GATE(PCLK_I2C3, "pclk_i2c3", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 2, GFLAGS),
|
||||
GATE(PCLK_TIMER, "pclk_timer0", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 4, GFLAGS),
|
||||
GATE(0, "pclk_stimer", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 5, GFLAGS),
|
||||
GATE(PCLK_SPI0, "pclk_spi0", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 6, GFLAGS),
|
||||
GATE(PCLK_PWM, "pclk_rk_pwm", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 7, GFLAGS),
|
||||
GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 8, GFLAGS),
|
||||
GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 9, GFLAGS),
|
||||
GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 10, GFLAGS),
|
||||
GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 11, GFLAGS),
|
||||
GATE(PCLK_UART0, "pclk_uart0", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 12, GFLAGS),
|
||||
GATE(PCLK_UART1, "pclk_uart1", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 13, GFLAGS),
|
||||
GATE(PCLK_UART2, "pclk_uart2", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 14, GFLAGS),
|
||||
GATE(0, "pclk_tsadc", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 15, GFLAGS),
|
||||
GATE(PCLK_GRF, "pclk_grf", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(10), 0, GFLAGS),
|
||||
GATE(0, "pclk_cru", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(10), 1, GFLAGS),
|
||||
GATE(0, "pclk_sgrf", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(10), 2, GFLAGS),
|
||||
GATE(0, "pclk_sim", "pclk_cpu", 0, RK2928_CLKGATE_CON(10), 3, GFLAGS),
|
||||
|
||||
GATE(0, "pclk_ddrphy", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 3, GFLAGS),
|
||||
GATE(0, "pclk_acodecphy", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 5, GFLAGS),
|
||||
GATE(0, "pclk_hdmiphy", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 7, GFLAGS),
|
||||
GATE(0, "pclk_vdacphy", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 8, GFLAGS),
|
||||
GATE(0, "pclk_phy_noc", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 9, GFLAGS),
|
||||
|
||||
GATE(0, "aclk_vpu", "aclk_vpu_pre", 0, RK2928_CLKGATE_CON(15), 0, GFLAGS),
|
||||
GATE(0, "aclk_vpu_noc", "aclk_vpu_pre", 0, RK2928_CLKGATE_CON(15), 4, GFLAGS),
|
||||
GATE(0, "aclk_rkvdec", "aclk_rkvdec_pre", 0, RK2928_CLKGATE_CON(15), 2, GFLAGS),
|
||||
GATE(0, "aclk_rkvdec_noc", "aclk_rkvdec_pre", 0, RK2928_CLKGATE_CON(15), 6, GFLAGS),
|
||||
GATE(0, "hclk_vpu", "hclk_vpu_pre", 0, RK2928_CLKGATE_CON(15), 1, GFLAGS),
|
||||
GATE(0, "hclk_vpu_noc", "hclk_vpu_pre", 0, RK2928_CLKGATE_CON(15), 5, GFLAGS),
|
||||
GATE(0, "hclk_rkvdec", "hclk_rkvdec_pre", 0, RK2928_CLKGATE_CON(15), 3, GFLAGS),
|
||||
GATE(0, "hclk_rkvdec_noc", "hclk_rkvdec_pre", 0, RK2928_CLKGATE_CON(15), 7, GFLAGS),
|
||||
|
||||
/* PD_MMC */
|
||||
MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "sclk_sdmmc", RK3228_SDMMC_CON0, 1),
|
||||
MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "sclk_sdmmc", RK3228_SDMMC_CON1, 1),
|
||||
|
||||
MMC(SCLK_SDIO_DRV, "sdio_drv", "sclk_sdio", RK3228_SDIO_CON0, 1),
|
||||
MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "sclk_sdio", RK3228_SDIO_CON1, 1),
|
||||
|
||||
MMC(SCLK_EMMC_DRV, "emmc_drv", "sclk_emmc", RK3228_EMMC_CON0, 1),
|
||||
MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "sclk_emmc", RK3228_EMMC_CON1, 1),
|
||||
};
|
||||
|
||||
static const char *const rk3228_critical_clocks[] __initconst = {
|
||||
"aclk_cpu",
|
||||
"aclk_peri",
|
||||
"hclk_peri",
|
||||
"pclk_peri",
|
||||
};
|
||||
|
||||
static void __init rk3228_clk_init(struct device_node *np)
|
||||
{
|
||||
void __iomem *reg_base;
|
||||
struct clk *clk;
|
||||
|
||||
reg_base = of_iomap(np, 0);
|
||||
if (!reg_base) {
|
||||
pr_err("%s: could not map cru region\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
|
||||
|
||||
/* xin12m is created by an cru-internal divider */
|
||||
clk = clk_register_fixed_factor(NULL, "xin12m", "xin24m", 0, 1, 2);
|
||||
if (IS_ERR(clk))
|
||||
pr_warn("%s: could not register clock xin12m: %ld\n",
|
||||
__func__, PTR_ERR(clk));
|
||||
|
||||
clk = clk_register_fixed_factor(NULL, "ddrphy_pre", "ddrphy4x", 0, 1, 4);
|
||||
if (IS_ERR(clk))
|
||||
pr_warn("%s: could not register clock ddrphy_pre: %ld\n",
|
||||
__func__, PTR_ERR(clk));
|
||||
|
||||
clk = clk_register_fixed_factor(NULL, "hclk_vpu_pre",
|
||||
"hclk_vpu_src", 0, 1, 4);
|
||||
if (IS_ERR(clk))
|
||||
pr_warn("%s: could not register clock hclk_vpu_pre: %ld\n",
|
||||
__func__, PTR_ERR(clk));
|
||||
|
||||
clk = clk_register_fixed_factor(NULL, "hclk_rkvdec_pre",
|
||||
"hclk_rkvdec_src", 0, 1, 4);
|
||||
if (IS_ERR(clk))
|
||||
pr_warn("%s: could not register clock hclk_rkvdec_pre: %ld\n",
|
||||
__func__, PTR_ERR(clk));
|
||||
|
||||
rockchip_clk_register_plls(rk3228_pll_clks,
|
||||
ARRAY_SIZE(rk3228_pll_clks),
|
||||
RK3228_GRF_SOC_STATUS0);
|
||||
rockchip_clk_register_branches(rk3228_clk_branches,
|
||||
ARRAY_SIZE(rk3228_clk_branches));
|
||||
rockchip_clk_protect_critical(rk3228_critical_clocks,
|
||||
ARRAY_SIZE(rk3228_critical_clocks));
|
||||
|
||||
rockchip_clk_register_armclk(ARMCLK, "armclk",
|
||||
mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
|
||||
&rk3228_cpuclk_data, rk3228_cpuclk_rates,
|
||||
ARRAY_SIZE(rk3228_cpuclk_rates));
|
||||
|
||||
rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0),
|
||||
ROCKCHIP_SOFTRST_HIWORD_MASK);
|
||||
|
||||
rockchip_register_restart_notifier(RK3228_GLB_SRST_FST, NULL);
|
||||
}
|
||||
CLK_OF_DECLARE(rk3228_cru, "rockchip,rk3228-cru", rk3228_clk_init);
|
@ -295,7 +295,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
|
||||
RK3288_CLKGATE_CON(0), 4, GFLAGS),
|
||||
GATE(0, "c2c_host", "aclk_cpu_src", 0,
|
||||
RK3288_CLKGATE_CON(13), 8, GFLAGS),
|
||||
COMPOSITE_NOMUX(0, "crypto", "aclk_cpu_pre", 0,
|
||||
COMPOSITE_NOMUX(SCLK_CRYPTO, "crypto", "aclk_cpu_pre", 0,
|
||||
RK3288_CLKSEL_CON(26), 6, 2, DFLAGS,
|
||||
RK3288_CLKGATE_CON(5), 4, GFLAGS),
|
||||
GATE(0, "aclk_bus_2pmu", "aclk_cpu_pre", CLK_IGNORE_UNUSED,
|
||||
@ -644,10 +644,10 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
|
||||
GATE(PCLK_PUBL0, "pclk_publ0", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 15, GFLAGS),
|
||||
GATE(PCLK_DDRUPCTL1, "pclk_ddrupctl1", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 0, GFLAGS),
|
||||
GATE(PCLK_PUBL1, "pclk_publ1", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 1, GFLAGS),
|
||||
GATE(0, "pclk_efuse_1024", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 2, GFLAGS),
|
||||
GATE(PCLK_EFUSE1024, "pclk_efuse_1024", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 2, GFLAGS),
|
||||
GATE(PCLK_TZPC, "pclk_tzpc", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 3, GFLAGS),
|
||||
GATE(PCLK_UART2, "pclk_uart2", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 9, GFLAGS),
|
||||
GATE(0, "pclk_efuse_256", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 10, GFLAGS),
|
||||
GATE(PCLK_EFUSE256, "pclk_efuse_256", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 10, GFLAGS),
|
||||
GATE(PCLK_RKPWM, "pclk_rkpwm", "pclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(11), 11, GFLAGS),
|
||||
|
||||
/* ddrctrl [DDR Controller PHY clock] gates */
|
||||
@ -709,7 +709,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
|
||||
GATE(SCLK_LCDC_PWM1, "sclk_lcdc_pwm1", "xin24m", 0, RK3288_CLKGATE_CON(13), 11, GFLAGS),
|
||||
GATE(SCLK_PVTM_CORE, "sclk_pvtm_core", "xin24m", 0, RK3288_CLKGATE_CON(5), 9, GFLAGS),
|
||||
GATE(SCLK_PVTM_GPU, "sclk_pvtm_gpu", "xin24m", 0, RK3288_CLKGATE_CON(5), 10, GFLAGS),
|
||||
GATE(0, "sclk_mipidsi_24m", "xin24m", 0, RK3288_CLKGATE_CON(5), 15, GFLAGS),
|
||||
GATE(SCLK_MIPIDSI_24M, "sclk_mipidsi_24m", "xin24m", 0, RK3288_CLKGATE_CON(5), 15, GFLAGS),
|
||||
|
||||
/* sclk_gpu gates */
|
||||
GATE(ACLK_GPU, "aclk_gpu", "sclk_gpu", 0, RK3288_CLKGATE_CON(18), 0, GFLAGS),
|
||||
@ -783,10 +783,10 @@ static const char *const rk3288_critical_clocks[] __initconst = {
|
||||
"pclk_pd_pmu",
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static void __iomem *rk3288_cru_base;
|
||||
|
||||
/* Some CRU registers will be reset in maskrom when the system
|
||||
/*
|
||||
* Some CRU registers will be reset in maskrom when the system
|
||||
* wakes up from fastboot.
|
||||
* So save them before suspend, restore them after resume.
|
||||
*/
|
||||
@ -840,33 +840,27 @@ static void rk3288_clk_resume(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void rk3288_clk_shutdown(void)
|
||||
{
|
||||
writel_relaxed(0xf3030000, rk3288_cru_base + RK3288_MODE_CON);
|
||||
}
|
||||
|
||||
static struct syscore_ops rk3288_clk_syscore_ops = {
|
||||
.suspend = rk3288_clk_suspend,
|
||||
.resume = rk3288_clk_resume,
|
||||
};
|
||||
|
||||
static void rk3288_clk_sleep_init(void __iomem *reg_base)
|
||||
{
|
||||
rk3288_cru_base = reg_base;
|
||||
register_syscore_ops(&rk3288_clk_syscore_ops);
|
||||
}
|
||||
|
||||
#else /* CONFIG_PM_SLEEP */
|
||||
static void rk3288_clk_sleep_init(void __iomem *reg_base) {}
|
||||
#endif
|
||||
|
||||
static void __init rk3288_clk_init(struct device_node *np)
|
||||
{
|
||||
void __iomem *reg_base;
|
||||
struct clk *clk;
|
||||
|
||||
reg_base = of_iomap(np, 0);
|
||||
if (!reg_base) {
|
||||
rk3288_cru_base = of_iomap(np, 0);
|
||||
if (!rk3288_cru_base) {
|
||||
pr_err("%s: could not map cru region\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
|
||||
rockchip_clk_init(np, rk3288_cru_base, CLK_NR_CLKS);
|
||||
|
||||
/* xin12m is created by an cru-internal divider */
|
||||
clk = clk_register_fixed_factor(NULL, "xin12m", "xin24m", 0, 1, 2);
|
||||
@ -907,10 +901,12 @@ static void __init rk3288_clk_init(struct device_node *np)
|
||||
&rk3288_cpuclk_data, rk3288_cpuclk_rates,
|
||||
ARRAY_SIZE(rk3288_cpuclk_rates));
|
||||
|
||||
rockchip_register_softrst(np, 12, reg_base + RK3288_SOFTRST_CON(0),
|
||||
rockchip_register_softrst(np, 12,
|
||||
rk3288_cru_base + RK3288_SOFTRST_CON(0),
|
||||
ROCKCHIP_SOFTRST_HIWORD_MASK);
|
||||
|
||||
rockchip_register_restart_notifier(RK3288_GLB_SRST_FST);
|
||||
rk3288_clk_sleep_init(reg_base);
|
||||
rockchip_register_restart_notifier(RK3288_GLB_SRST_FST,
|
||||
rk3288_clk_shutdown);
|
||||
register_syscore_ops(&rk3288_clk_syscore_ops);
|
||||
}
|
||||
CLK_OF_DECLARE(rk3288_cru, "rockchip,rk3288-cru", rk3288_clk_init);
|
||||
|
@ -184,13 +184,13 @@ static const struct rockchip_cpuclk_reg_data rk3368_cpuclkl_data = {
|
||||
|
||||
#define RK3368_CLKSEL0(_offs, _aclkm) \
|
||||
{ \
|
||||
.reg = RK3288_CLKSEL_CON(0 + _offs), \
|
||||
.reg = RK3368_CLKSEL_CON(0 + _offs), \
|
||||
.val = HIWORD_UPDATE(_aclkm, RK3368_DIV_ACLKM_MASK, \
|
||||
RK3368_DIV_ACLKM_SHIFT), \
|
||||
}
|
||||
#define RK3368_CLKSEL1(_offs, _atclk, _pdbg) \
|
||||
{ \
|
||||
.reg = RK3288_CLKSEL_CON(1 + _offs), \
|
||||
.reg = RK3368_CLKSEL_CON(1 + _offs), \
|
||||
.val = HIWORD_UPDATE(_atclk, RK3368_DIV_ATCLK_MASK, \
|
||||
RK3368_DIV_ATCLK_SHIFT) | \
|
||||
HIWORD_UPDATE(_pdbg, RK3368_DIV_PCLK_DBG_MASK, \
|
||||
@ -819,6 +819,13 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = {
|
||||
};
|
||||
|
||||
static const char *const rk3368_critical_clocks[] __initconst = {
|
||||
"aclk_bus",
|
||||
"aclk_peri",
|
||||
/*
|
||||
* pwm1 supplies vdd_logic on a lot of boards, is currently unhandled
|
||||
* but needs to stay enabled there (including its parents) at all times.
|
||||
*/
|
||||
"pclk_pwm1",
|
||||
"pclk_pd_pmu",
|
||||
};
|
||||
|
||||
@ -882,6 +889,6 @@ static void __init rk3368_clk_init(struct device_node *np)
|
||||
rockchip_register_softrst(np, 15, reg_base + RK3368_SOFTRST_CON(0),
|
||||
ROCKCHIP_SOFTRST_HIWORD_MASK);
|
||||
|
||||
rockchip_register_restart_notifier(RK3368_GLB_SRST_FST);
|
||||
rockchip_register_restart_notifier(RK3368_GLB_SRST_FST, NULL);
|
||||
}
|
||||
CLK_OF_DECLARE(rk3368_cru, "rockchip,rk3368-cru", rk3368_clk_init);
|
||||
|
@ -341,9 +341,13 @@ void __init rockchip_clk_protect_critical(const char *const clocks[],
|
||||
}
|
||||
|
||||
static unsigned int reg_restart;
|
||||
static void (*cb_restart)(void);
|
||||
static int rockchip_restart_notify(struct notifier_block *this,
|
||||
unsigned long mode, void *cmd)
|
||||
{
|
||||
if (cb_restart)
|
||||
cb_restart();
|
||||
|
||||
writel(0xfdb9, reg_base + reg_restart);
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
@ -353,11 +357,12 @@ static struct notifier_block rockchip_restart_handler = {
|
||||
.priority = 128,
|
||||
};
|
||||
|
||||
void __init rockchip_register_restart_notifier(unsigned int reg)
|
||||
void __init rockchip_register_restart_notifier(unsigned int reg, void (*cb)(void))
|
||||
{
|
||||
int ret;
|
||||
|
||||
reg_restart = reg;
|
||||
cb_restart = cb;
|
||||
ret = register_restart_handler(&rockchip_restart_handler);
|
||||
if (ret)
|
||||
pr_err("%s: cannot register restart handler, %d\n",
|
||||
|
@ -2,6 +2,9 @@
|
||||
* Copyright (c) 2014 MundoReader S.L.
|
||||
* Author: Heiko Stuebner <heiko@sntech.de>
|
||||
*
|
||||
* Copyright (c) 2015 Rockchip Electronics Co. Ltd.
|
||||
* Author: Xing Zheng <zhengxing@rock-chips.com>
|
||||
*
|
||||
* based on
|
||||
*
|
||||
* samsung/clk.h
|
||||
@ -30,7 +33,7 @@ struct clk;
|
||||
#define HIWORD_UPDATE(val, mask, shift) \
|
||||
((val) << (shift) | (mask) << ((shift) + 16))
|
||||
|
||||
/* register positions shared by RK2928, RK3066 and RK3188 */
|
||||
/* register positions shared by RK2928, RK3036, RK3066, RK3188 and RK3228 */
|
||||
#define RK2928_PLL_CON(x) ((x) * 0x4)
|
||||
#define RK2928_MODE_CON 0x40
|
||||
#define RK2928_CLKSEL_CON(x) ((x) * 0x4 + 0x44)
|
||||
@ -40,6 +43,22 @@ struct clk;
|
||||
#define RK2928_SOFTRST_CON(x) ((x) * 0x4 + 0x110)
|
||||
#define RK2928_MISC_CON 0x134
|
||||
|
||||
#define RK3036_SDMMC_CON0 0x144
|
||||
#define RK3036_SDMMC_CON1 0x148
|
||||
#define RK3036_SDIO_CON0 0x14c
|
||||
#define RK3036_SDIO_CON1 0x150
|
||||
#define RK3036_EMMC_CON0 0x154
|
||||
#define RK3036_EMMC_CON1 0x158
|
||||
|
||||
#define RK3228_GLB_SRST_FST 0x1f0
|
||||
#define RK3228_GLB_SRST_SND 0x1f4
|
||||
#define RK3228_SDMMC_CON0 0x1c0
|
||||
#define RK3228_SDMMC_CON1 0x1c4
|
||||
#define RK3228_SDIO_CON0 0x1c8
|
||||
#define RK3228_SDIO_CON1 0x1cc
|
||||
#define RK3228_EMMC_CON0 0x1d8
|
||||
#define RK3228_EMMC_CON1 0x1dc
|
||||
|
||||
#define RK3288_PLL_CON(x) RK2928_PLL_CON(x)
|
||||
#define RK3288_MODE_CON 0x50
|
||||
#define RK3288_CLKSEL_CON(x) ((x) * 0x4 + 0x60)
|
||||
@ -74,9 +93,22 @@ struct clk;
|
||||
#define RK3368_EMMC_CON1 0x41c
|
||||
|
||||
enum rockchip_pll_type {
|
||||
pll_rk3036,
|
||||
pll_rk3066,
|
||||
};
|
||||
|
||||
#define RK3036_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1, \
|
||||
_postdiv2, _dsmpd, _frac) \
|
||||
{ \
|
||||
.rate = _rate##U, \
|
||||
.fbdiv = _fbdiv, \
|
||||
.postdiv1 = _postdiv1, \
|
||||
.refdiv = _refdiv, \
|
||||
.postdiv2 = _postdiv2, \
|
||||
.dsmpd = _dsmpd, \
|
||||
.frac = _frac, \
|
||||
}
|
||||
|
||||
#define RK3066_PLL_RATE(_rate, _nr, _nf, _no) \
|
||||
{ \
|
||||
.rate = _rate##U, \
|
||||
@ -101,6 +133,13 @@ struct rockchip_pll_rate_table {
|
||||
unsigned int nf;
|
||||
unsigned int no;
|
||||
unsigned int nb;
|
||||
/* for RK3036 */
|
||||
unsigned int fbdiv;
|
||||
unsigned int postdiv1;
|
||||
unsigned int refdiv;
|
||||
unsigned int postdiv2;
|
||||
unsigned int dsmpd;
|
||||
unsigned int frac;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -464,7 +503,7 @@ void rockchip_clk_register_armclk(unsigned int lookup_id, const char *name,
|
||||
const struct rockchip_cpuclk_rate_table *rates,
|
||||
int nrates);
|
||||
void rockchip_clk_protect_critical(const char *const clocks[], int nclocks);
|
||||
void rockchip_register_restart_notifier(unsigned int reg);
|
||||
void rockchip_register_restart_notifier(unsigned int reg, void (*cb)(void));
|
||||
|
||||
#define ROCKCHIP_SOFTRST_HIWORD_MASK BIT(0)
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
obj-$(CONFIG_ARCH_EMEV2) += clk-emev2.o
|
||||
obj-$(CONFIG_ARCH_R7S72100) += clk-rz.o
|
||||
obj-$(CONFIG_ARCH_R8A73A4) += clk-r8a73a4.o
|
||||
obj-$(CONFIG_ARCH_R8A7740) += clk-r8a7740.o
|
||||
obj-$(CONFIG_ARCH_R8A7778) += clk-r8a7778.o
|
||||
obj-$(CONFIG_ARCH_R8A7779) += clk-r8a7779.o
|
||||
obj-$(CONFIG_ARCH_R8A7790) += clk-rcar-gen2.o
|
||||
obj-$(CONFIG_ARCH_R8A7791) += clk-rcar-gen2.o
|
||||
obj-$(CONFIG_ARCH_R8A7793) += clk-rcar-gen2.o
|
||||
obj-$(CONFIG_ARCH_R8A7794) += clk-rcar-gen2.o
|
||||
obj-$(CONFIG_ARCH_SH73A0) += clk-sh73a0.o
|
||||
obj-$(CONFIG_ARCH_SHMOBILE_MULTI) += clk-div6.o
|
||||
obj-$(CONFIG_ARCH_SHMOBILE_MULTI) += clk-mstp.o
|
||||
obj-$(CONFIG_ARCH_R7S72100) += clk-rz.o clk-mstp.o
|
||||
obj-$(CONFIG_ARCH_R8A73A4) += clk-r8a73a4.o clk-mstp.o clk-div6.o
|
||||
obj-$(CONFIG_ARCH_R8A7740) += clk-r8a7740.o clk-mstp.o clk-div6.o
|
||||
obj-$(CONFIG_ARCH_R8A7778) += clk-r8a7778.o clk-mstp.o
|
||||
obj-$(CONFIG_ARCH_R8A7779) += clk-r8a7779.o clk-mstp.o
|
||||
obj-$(CONFIG_ARCH_R8A7790) += clk-rcar-gen2.o clk-mstp.o clk-div6.o
|
||||
obj-$(CONFIG_ARCH_R8A7791) += clk-rcar-gen2.o clk-mstp.o clk-div6.o
|
||||
obj-$(CONFIG_ARCH_R8A7793) += clk-rcar-gen2.o clk-mstp.o clk-div6.o
|
||||
obj-$(CONFIG_ARCH_R8A7794) += clk-rcar-gen2.o clk-mstp.o clk-div6.o
|
||||
obj-$(CONFIG_ARCH_R8A7795) += renesas-cpg-mssr.o \
|
||||
r8a7795-cpg-mssr.o clk-div6.o
|
||||
obj-$(CONFIG_ARCH_SH73A0) += clk-sh73a0.o clk-mstp.o clk-div6.o
|
||||
|
@ -18,6 +18,8 @@
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "clk-div6.h"
|
||||
|
||||
#define CPG_DIV6_CKSTP BIT(8)
|
||||
#define CPG_DIV6_DIV(d) ((d) & 0x3f)
|
||||
#define CPG_DIV6_DIV_MASK 0x3f
|
||||
@ -172,67 +174,44 @@ static const struct clk_ops cpg_div6_clock_ops = {
|
||||
.set_rate = cpg_div6_clock_set_rate,
|
||||
};
|
||||
|
||||
static void __init cpg_div6_clock_init(struct device_node *np)
|
||||
|
||||
/**
|
||||
* cpg_div6_register - Register a DIV6 clock
|
||||
* @name: Name of the DIV6 clock
|
||||
* @num_parents: Number of parent clocks of the DIV6 clock (1, 4, or 8)
|
||||
* @parent_names: Array containing the names of the parent clocks
|
||||
* @reg: Mapped register used to control the DIV6 clock
|
||||
*/
|
||||
struct clk * __init cpg_div6_register(const char *name,
|
||||
unsigned int num_parents,
|
||||
const char **parent_names,
|
||||
void __iomem *reg)
|
||||
{
|
||||
unsigned int num_parents, valid_parents;
|
||||
const char **parent_names;
|
||||
unsigned int valid_parents;
|
||||
struct clk_init_data init;
|
||||
struct div6_clock *clock;
|
||||
const char *name;
|
||||
struct clk *clk;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
clock = kzalloc(sizeof(*clock), GFP_KERNEL);
|
||||
if (!clock)
|
||||
return;
|
||||
|
||||
num_parents = of_clk_get_parent_count(np);
|
||||
if (num_parents < 1) {
|
||||
pr_err("%s: no parent found for %s DIV6 clock\n",
|
||||
__func__, np->name);
|
||||
return;
|
||||
}
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
clock->parents = kmalloc_array(num_parents, sizeof(*clock->parents),
|
||||
GFP_KERNEL);
|
||||
parent_names = kmalloc_array(num_parents, sizeof(*parent_names),
|
||||
GFP_KERNEL);
|
||||
if (!parent_names)
|
||||
return;
|
||||
GFP_KERNEL);
|
||||
if (!clock->parents) {
|
||||
clk = ERR_PTR(-ENOMEM);
|
||||
goto free_clock;
|
||||
}
|
||||
|
||||
/* Remap the clock register and read the divisor. Disabling the
|
||||
* clock overwrites the divisor, so we need to cache its value for the
|
||||
* enable operation.
|
||||
clock->reg = reg;
|
||||
|
||||
/*
|
||||
* Read the divisor. Disabling the clock overwrites the divisor, so we
|
||||
* need to cache its value for the enable operation.
|
||||
*/
|
||||
clock->reg = of_iomap(np, 0);
|
||||
if (clock->reg == NULL) {
|
||||
pr_err("%s: failed to map %s DIV6 clock register\n",
|
||||
__func__, np->name);
|
||||
goto error;
|
||||
}
|
||||
|
||||
clock->div = (clk_readl(clock->reg) & CPG_DIV6_DIV_MASK) + 1;
|
||||
|
||||
/* Parse the DT properties. */
|
||||
ret = of_property_read_string(np, "clock-output-names", &name);
|
||||
if (ret < 0) {
|
||||
pr_err("%s: failed to get %s DIV6 clock output name\n",
|
||||
__func__, np->name);
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
||||
for (i = 0, valid_parents = 0; i < num_parents; i++) {
|
||||
const char *name = of_clk_get_parent_name(np, i);
|
||||
|
||||
if (name) {
|
||||
parent_names[valid_parents] = name;
|
||||
clock->parents[valid_parents] = i;
|
||||
valid_parents++;
|
||||
}
|
||||
}
|
||||
|
||||
switch (num_parents) {
|
||||
case 1:
|
||||
/* fixed parent clock */
|
||||
@ -250,8 +229,18 @@ static void __init cpg_div6_clock_init(struct device_node *np)
|
||||
break;
|
||||
default:
|
||||
pr_err("%s: invalid number of parents for DIV6 clock %s\n",
|
||||
__func__, np->name);
|
||||
goto error;
|
||||
__func__, name);
|
||||
clk = ERR_PTR(-EINVAL);
|
||||
goto free_parents;
|
||||
}
|
||||
|
||||
/* Filter out invalid parents */
|
||||
for (i = 0, valid_parents = 0; i < num_parents; i++) {
|
||||
if (parent_names[i]) {
|
||||
parent_names[valid_parents] = parent_names[i];
|
||||
clock->parents[valid_parents] = i;
|
||||
valid_parents++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Register the clock. */
|
||||
@ -264,6 +253,53 @@ static void __init cpg_div6_clock_init(struct device_node *np)
|
||||
clock->hw.init = &init;
|
||||
|
||||
clk = clk_register(NULL, &clock->hw);
|
||||
if (IS_ERR(clk))
|
||||
goto free_parents;
|
||||
|
||||
return clk;
|
||||
|
||||
free_parents:
|
||||
kfree(clock->parents);
|
||||
free_clock:
|
||||
kfree(clock);
|
||||
return clk;
|
||||
}
|
||||
|
||||
static void __init cpg_div6_clock_init(struct device_node *np)
|
||||
{
|
||||
unsigned int num_parents;
|
||||
const char **parent_names;
|
||||
const char *clk_name = np->name;
|
||||
void __iomem *reg;
|
||||
struct clk *clk;
|
||||
unsigned int i;
|
||||
|
||||
num_parents = of_clk_get_parent_count(np);
|
||||
if (num_parents < 1) {
|
||||
pr_err("%s: no parent found for %s DIV6 clock\n",
|
||||
__func__, np->name);
|
||||
return;
|
||||
}
|
||||
|
||||
parent_names = kmalloc_array(num_parents, sizeof(*parent_names),
|
||||
GFP_KERNEL);
|
||||
if (!parent_names)
|
||||
return;
|
||||
|
||||
reg = of_iomap(np, 0);
|
||||
if (reg == NULL) {
|
||||
pr_err("%s: failed to map %s DIV6 clock register\n",
|
||||
__func__, np->name);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Parse the DT properties. */
|
||||
of_property_read_string(np, "clock-output-names", &clk_name);
|
||||
|
||||
for (i = 0; i < num_parents; i++)
|
||||
parent_names[i] = of_clk_get_parent_name(np, i);
|
||||
|
||||
clk = cpg_div6_register(clk_name, num_parents, parent_names, reg);
|
||||
if (IS_ERR(clk)) {
|
||||
pr_err("%s: failed to register %s DIV6 clock (%ld)\n",
|
||||
__func__, np->name, PTR_ERR(clk));
|
||||
@ -276,9 +312,8 @@ static void __init cpg_div6_clock_init(struct device_node *np)
|
||||
return;
|
||||
|
||||
error:
|
||||
if (clock->reg)
|
||||
iounmap(clock->reg);
|
||||
if (reg)
|
||||
iounmap(reg);
|
||||
kfree(parent_names);
|
||||
kfree(clock);
|
||||
}
|
||||
CLK_OF_DECLARE(cpg_div6_clk, "renesas,cpg-div6-clock", cpg_div6_clock_init);
|
||||
|
7
drivers/clk/shmobile/clk-div6.h
Normal file
7
drivers/clk/shmobile/clk-div6.h
Normal file
@ -0,0 +1,7 @@
|
||||
#ifndef __SHMOBILE_CLK_DIV6_H__
|
||||
#define __SHMOBILE_CLK_DIV6_H__
|
||||
|
||||
struct clk *cpg_div6_register(const char *name, unsigned int num_parents,
|
||||
const char **parent_names, void __iomem *reg);
|
||||
|
||||
#endif
|
@ -115,7 +115,7 @@ static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
*
|
||||
* Using experimental measurements, it seems that no more than
|
||||
* ~10 iterations are needed, independently of the CPU rate.
|
||||
* Since this value might be dependant of external xtal rate, pll1
|
||||
* Since this value might be dependent on external xtal rate, pll1
|
||||
* rate or even the other emulation clocks rate, use 1000 as a
|
||||
* "super" safe value.
|
||||
*/
|
||||
@ -262,7 +262,7 @@ static struct clk * __init cpg_adsp_clk_register(struct rcar_gen2_cpg *cpg)
|
||||
* 1 1 0 30 / 2 x172/2 x208/2 x106
|
||||
* 1 1 1 30 / 2 x172/2 x208/2 x88
|
||||
*
|
||||
* *1 : Table 7.6 indicates VCO ouput (PLLx = VCO/2)
|
||||
* *1 : Table 7.6 indicates VCO output (PLLx = VCO/2)
|
||||
*/
|
||||
#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 12) | \
|
||||
(((md) & BIT(13)) >> 12) | \
|
||||
|
382
drivers/clk/shmobile/r8a7795-cpg-mssr.c
Normal file
382
drivers/clk/shmobile/r8a7795-cpg-mssr.c
Normal file
@ -0,0 +1,382 @@
|
||||
/*
|
||||
* r8a7795 Clock Pulse Generator / Module Standby and Software Reset
|
||||
*
|
||||
* Copyright (C) 2015 Glider bvba
|
||||
*
|
||||
* Based on clk-rcar-gen3.c
|
||||
*
|
||||
* Copyright (C) 2015 Renesas Electronics Corp.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*/
|
||||
|
||||
#include <linux/bug.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#include <dt-bindings/clock/r8a7795-cpg-mssr.h>
|
||||
|
||||
#include "renesas-cpg-mssr.h"
|
||||
|
||||
|
||||
enum clk_ids {
|
||||
/* Core Clock Outputs exported to DT */
|
||||
LAST_DT_CORE_CLK = R8A7795_CLK_OSC,
|
||||
|
||||
/* External Input Clocks */
|
||||
CLK_EXTAL,
|
||||
CLK_EXTALR,
|
||||
|
||||
/* Internal Core Clocks */
|
||||
CLK_MAIN,
|
||||
CLK_PLL0,
|
||||
CLK_PLL1,
|
||||
CLK_PLL2,
|
||||
CLK_PLL3,
|
||||
CLK_PLL4,
|
||||
CLK_PLL1_DIV2,
|
||||
CLK_PLL1_DIV4,
|
||||
CLK_S0,
|
||||
CLK_S1,
|
||||
CLK_S2,
|
||||
CLK_S3,
|
||||
CLK_SDSRC,
|
||||
CLK_SSPSRC,
|
||||
|
||||
/* Module Clocks */
|
||||
MOD_CLK_BASE
|
||||
};
|
||||
|
||||
enum r8a7795_clk_types {
|
||||
CLK_TYPE_GEN3_MAIN = CLK_TYPE_CUSTOM,
|
||||
CLK_TYPE_GEN3_PLL0,
|
||||
CLK_TYPE_GEN3_PLL1,
|
||||
CLK_TYPE_GEN3_PLL2,
|
||||
CLK_TYPE_GEN3_PLL3,
|
||||
CLK_TYPE_GEN3_PLL4,
|
||||
};
|
||||
|
||||
static const struct cpg_core_clk r8a7795_core_clks[] __initconst = {
|
||||
/* External Clock Inputs */
|
||||
DEF_INPUT("extal", CLK_EXTAL),
|
||||
DEF_INPUT("extalr", CLK_EXTALR),
|
||||
|
||||
/* Internal Core Clocks */
|
||||
DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN3_MAIN, CLK_EXTAL),
|
||||
DEF_BASE(".pll0", CLK_PLL0, CLK_TYPE_GEN3_PLL0, CLK_MAIN),
|
||||
DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN3_PLL1, CLK_MAIN),
|
||||
DEF_BASE(".pll2", CLK_PLL2, CLK_TYPE_GEN3_PLL2, CLK_MAIN),
|
||||
DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN3_PLL3, CLK_MAIN),
|
||||
DEF_BASE(".pll4", CLK_PLL4, CLK_TYPE_GEN3_PLL4, CLK_MAIN),
|
||||
|
||||
DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1),
|
||||
DEF_FIXED(".pll1_div4", CLK_PLL1_DIV4, CLK_PLL1_DIV2, 2, 1),
|
||||
DEF_FIXED(".s0", CLK_S0, CLK_PLL1_DIV2, 2, 1),
|
||||
DEF_FIXED(".s1", CLK_S1, CLK_PLL1_DIV2, 3, 1),
|
||||
DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1),
|
||||
DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1),
|
||||
|
||||
/* Core Clock Outputs */
|
||||
DEF_FIXED("ztr", R8A7795_CLK_ZTR, CLK_PLL1_DIV2, 6, 1),
|
||||
DEF_FIXED("ztrd2", R8A7795_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1),
|
||||
DEF_FIXED("zt", R8A7795_CLK_ZT, CLK_PLL1_DIV2, 4, 1),
|
||||
DEF_FIXED("zx", R8A7795_CLK_ZX, CLK_PLL1_DIV2, 2, 1),
|
||||
DEF_FIXED("s0d1", R8A7795_CLK_S0D1, CLK_S0, 1, 1),
|
||||
DEF_FIXED("s0d4", R8A7795_CLK_S0D4, CLK_S0, 4, 1),
|
||||
DEF_FIXED("s1d1", R8A7795_CLK_S1D1, CLK_S1, 1, 1),
|
||||
DEF_FIXED("s1d2", R8A7795_CLK_S1D2, CLK_S1, 2, 1),
|
||||
DEF_FIXED("s1d4", R8A7795_CLK_S1D4, CLK_S1, 4, 1),
|
||||
DEF_FIXED("s2d1", R8A7795_CLK_S2D1, CLK_S2, 1, 1),
|
||||
DEF_FIXED("s2d2", R8A7795_CLK_S2D2, CLK_S2, 2, 1),
|
||||
DEF_FIXED("s2d4", R8A7795_CLK_S2D4, CLK_S2, 4, 1),
|
||||
DEF_FIXED("s3d1", R8A7795_CLK_S3D1, CLK_S3, 1, 1),
|
||||
DEF_FIXED("s3d2", R8A7795_CLK_S3D2, CLK_S3, 2, 1),
|
||||
DEF_FIXED("s3d4", R8A7795_CLK_S3D4, CLK_S3, 4, 1),
|
||||
DEF_FIXED("cl", R8A7795_CLK_CL, CLK_PLL1_DIV2, 48, 1),
|
||||
DEF_FIXED("cp", R8A7795_CLK_CP, CLK_EXTAL, 2, 1),
|
||||
|
||||
DEF_DIV6P1("mso", R8A7795_CLK_MSO, CLK_PLL1_DIV4, 0x014),
|
||||
DEF_DIV6P1("hdmi", R8A7795_CLK_HDMI, CLK_PLL1_DIV2, 0x250),
|
||||
};
|
||||
|
||||
static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = {
|
||||
DEF_MOD("scif5", 202, R8A7795_CLK_S3D4),
|
||||
DEF_MOD("scif4", 203, R8A7795_CLK_S3D4),
|
||||
DEF_MOD("scif3", 204, R8A7795_CLK_S3D4),
|
||||
DEF_MOD("scif1", 206, R8A7795_CLK_S3D4),
|
||||
DEF_MOD("scif0", 207, R8A7795_CLK_S3D4),
|
||||
DEF_MOD("msiof3", 208, R8A7795_CLK_MSO),
|
||||
DEF_MOD("msiof2", 209, R8A7795_CLK_MSO),
|
||||
DEF_MOD("msiof1", 210, R8A7795_CLK_MSO),
|
||||
DEF_MOD("msiof0", 211, R8A7795_CLK_MSO),
|
||||
DEF_MOD("sys-dmac2", 217, R8A7795_CLK_S3D1),
|
||||
DEF_MOD("sys-dmac1", 218, R8A7795_CLK_S3D1),
|
||||
DEF_MOD("sys-dmac0", 219, R8A7795_CLK_S3D1),
|
||||
DEF_MOD("scif2", 310, R8A7795_CLK_S3D4),
|
||||
DEF_MOD("pcie1", 318, R8A7795_CLK_S3D1),
|
||||
DEF_MOD("pcie0", 319, R8A7795_CLK_S3D1),
|
||||
DEF_MOD("intc-ap", 408, R8A7795_CLK_S3D1),
|
||||
DEF_MOD("audmac0", 502, R8A7795_CLK_S3D4),
|
||||
DEF_MOD("audmac1", 501, R8A7795_CLK_S3D4),
|
||||
DEF_MOD("hscif4", 516, R8A7795_CLK_S3D1),
|
||||
DEF_MOD("hscif3", 517, R8A7795_CLK_S3D1),
|
||||
DEF_MOD("hscif2", 518, R8A7795_CLK_S3D1),
|
||||
DEF_MOD("hscif1", 519, R8A7795_CLK_S3D1),
|
||||
DEF_MOD("hscif0", 520, R8A7795_CLK_S3D1),
|
||||
DEF_MOD("vspd3", 620, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("vspd2", 621, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("vspd1", 622, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("vspd0", 623, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("vspbc", 624, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("vspbd", 626, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("vspi2", 629, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("vspi1", 630, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("vspi0", 631, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("ehci2", 701, R8A7795_CLK_S3D4),
|
||||
DEF_MOD("ehci1", 702, R8A7795_CLK_S3D4),
|
||||
DEF_MOD("ehci0", 703, R8A7795_CLK_S3D4),
|
||||
DEF_MOD("hsusb", 704, R8A7795_CLK_S3D4),
|
||||
DEF_MOD("du3", 721, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("du2", 722, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("du1", 723, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("du0", 724, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("hdmi1", 728, R8A7795_CLK_HDMI),
|
||||
DEF_MOD("hdmi0", 729, R8A7795_CLK_HDMI),
|
||||
DEF_MOD("etheravb", 812, R8A7795_CLK_S3D2),
|
||||
DEF_MOD("gpio7", 905, R8A7795_CLK_CP),
|
||||
DEF_MOD("gpio6", 906, R8A7795_CLK_CP),
|
||||
DEF_MOD("gpio5", 907, R8A7795_CLK_CP),
|
||||
DEF_MOD("gpio4", 908, R8A7795_CLK_CP),
|
||||
DEF_MOD("gpio3", 909, R8A7795_CLK_CP),
|
||||
DEF_MOD("gpio2", 910, R8A7795_CLK_CP),
|
||||
DEF_MOD("gpio1", 911, R8A7795_CLK_CP),
|
||||
DEF_MOD("gpio0", 912, R8A7795_CLK_CP),
|
||||
DEF_MOD("i2c6", 918, R8A7795_CLK_S3D2),
|
||||
DEF_MOD("i2c5", 919, R8A7795_CLK_S3D2),
|
||||
DEF_MOD("i2c4", 927, R8A7795_CLK_S3D2),
|
||||
DEF_MOD("i2c3", 928, R8A7795_CLK_S3D2),
|
||||
DEF_MOD("i2c2", 929, R8A7795_CLK_S3D2),
|
||||
DEF_MOD("i2c1", 930, R8A7795_CLK_S3D2),
|
||||
DEF_MOD("i2c0", 931, R8A7795_CLK_S3D2),
|
||||
DEF_MOD("ssi-all", 1005, R8A7795_CLK_S3D4),
|
||||
DEF_MOD("ssi9", 1006, MOD_CLK_ID(1005)),
|
||||
DEF_MOD("ssi8", 1007, MOD_CLK_ID(1005)),
|
||||
DEF_MOD("ssi7", 1008, MOD_CLK_ID(1005)),
|
||||
DEF_MOD("ssi6", 1009, MOD_CLK_ID(1005)),
|
||||
DEF_MOD("ssi5", 1010, MOD_CLK_ID(1005)),
|
||||
DEF_MOD("ssi4", 1011, MOD_CLK_ID(1005)),
|
||||
DEF_MOD("ssi3", 1012, MOD_CLK_ID(1005)),
|
||||
DEF_MOD("ssi2", 1013, MOD_CLK_ID(1005)),
|
||||
DEF_MOD("ssi1", 1014, MOD_CLK_ID(1005)),
|
||||
DEF_MOD("ssi0", 1015, MOD_CLK_ID(1005)),
|
||||
DEF_MOD("scu-all", 1017, R8A7795_CLK_S3D4),
|
||||
DEF_MOD("scu-dvc1", 1018, MOD_CLK_ID(1017)),
|
||||
DEF_MOD("scu-dvc0", 1019, MOD_CLK_ID(1017)),
|
||||
DEF_MOD("scu-ctu1-mix1", 1020, MOD_CLK_ID(1017)),
|
||||
DEF_MOD("scu-ctu0-mix0", 1021, MOD_CLK_ID(1017)),
|
||||
DEF_MOD("scu-src9", 1022, MOD_CLK_ID(1017)),
|
||||
DEF_MOD("scu-src8", 1023, MOD_CLK_ID(1017)),
|
||||
DEF_MOD("scu-src7", 1024, MOD_CLK_ID(1017)),
|
||||
DEF_MOD("scu-src6", 1025, MOD_CLK_ID(1017)),
|
||||
DEF_MOD("scu-src5", 1026, MOD_CLK_ID(1017)),
|
||||
DEF_MOD("scu-src4", 1027, MOD_CLK_ID(1017)),
|
||||
DEF_MOD("scu-src3", 1028, MOD_CLK_ID(1017)),
|
||||
DEF_MOD("scu-src2", 1029, MOD_CLK_ID(1017)),
|
||||
DEF_MOD("scu-src1", 1030, MOD_CLK_ID(1017)),
|
||||
DEF_MOD("scu-src0", 1031, MOD_CLK_ID(1017)),
|
||||
};
|
||||
|
||||
static const unsigned int r8a7795_crit_mod_clks[] __initconst = {
|
||||
MOD_CLK_ID(408), /* INTC-AP (GIC) */
|
||||
};
|
||||
|
||||
|
||||
#define CPG_PLL0CR 0x00d8
|
||||
#define CPG_PLL2CR 0x002c
|
||||
#define CPG_PLL4CR 0x01f4
|
||||
|
||||
/*
|
||||
* CPG Clock Data
|
||||
*/
|
||||
|
||||
/*
|
||||
* MD EXTAL PLL0 PLL1 PLL2 PLL3 PLL4
|
||||
* 14 13 19 17 (MHz)
|
||||
*-------------------------------------------------------------------
|
||||
* 0 0 0 0 16.66 x 1 x180 x192 x144 x192 x144
|
||||
* 0 0 0 1 16.66 x 1 x180 x192 x144 x128 x144
|
||||
* 0 0 1 0 Prohibited setting
|
||||
* 0 0 1 1 16.66 x 1 x180 x192 x144 x192 x144
|
||||
* 0 1 0 0 20 x 1 x150 x160 x120 x160 x120
|
||||
* 0 1 0 1 20 x 1 x150 x160 x120 x106 x120
|
||||
* 0 1 1 0 Prohibited setting
|
||||
* 0 1 1 1 20 x 1 x150 x160 x120 x160 x120
|
||||
* 1 0 0 0 25 x 1 x120 x128 x96 x128 x96
|
||||
* 1 0 0 1 25 x 1 x120 x128 x96 x84 x96
|
||||
* 1 0 1 0 Prohibited setting
|
||||
* 1 0 1 1 25 x 1 x120 x128 x96 x128 x96
|
||||
* 1 1 0 0 33.33 / 2 x180 x192 x144 x192 x144
|
||||
* 1 1 0 1 33.33 / 2 x180 x192 x144 x128 x144
|
||||
* 1 1 1 0 Prohibited setting
|
||||
* 1 1 1 1 33.33 / 2 x180 x192 x144 x192 x144
|
||||
*/
|
||||
#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 11) | \
|
||||
(((md) & BIT(13)) >> 11) | \
|
||||
(((md) & BIT(19)) >> 18) | \
|
||||
(((md) & BIT(17)) >> 17))
|
||||
|
||||
struct cpg_pll_config {
|
||||
unsigned int extal_div;
|
||||
unsigned int pll1_mult;
|
||||
unsigned int pll3_mult;
|
||||
};
|
||||
|
||||
static const struct cpg_pll_config cpg_pll_configs[16] __initconst = {
|
||||
/* EXTAL div PLL1 mult PLL3 mult */
|
||||
{ 1, 192, 192, },
|
||||
{ 1, 192, 128, },
|
||||
{ 0, /* Prohibited setting */ },
|
||||
{ 1, 192, 192, },
|
||||
{ 1, 160, 160, },
|
||||
{ 1, 160, 106, },
|
||||
{ 0, /* Prohibited setting */ },
|
||||
{ 1, 160, 160, },
|
||||
{ 1, 128, 128, },
|
||||
{ 1, 128, 84, },
|
||||
{ 0, /* Prohibited setting */ },
|
||||
{ 1, 128, 128, },
|
||||
{ 2, 192, 192, },
|
||||
{ 2, 192, 128, },
|
||||
{ 0, /* Prohibited setting */ },
|
||||
{ 2, 192, 192, },
|
||||
};
|
||||
|
||||
static const struct cpg_pll_config *cpg_pll_config __initdata;
|
||||
|
||||
static
|
||||
struct clk * __init r8a7795_cpg_clk_register(struct device *dev,
|
||||
const struct cpg_core_clk *core,
|
||||
const struct cpg_mssr_info *info,
|
||||
struct clk **clks,
|
||||
void __iomem *base)
|
||||
{
|
||||
const struct clk *parent;
|
||||
unsigned int mult = 1;
|
||||
unsigned int div = 1;
|
||||
u32 value;
|
||||
|
||||
parent = clks[core->parent];
|
||||
if (IS_ERR(parent))
|
||||
return ERR_CAST(parent);
|
||||
|
||||
switch (core->type) {
|
||||
case CLK_TYPE_GEN3_MAIN:
|
||||
div = cpg_pll_config->extal_div;
|
||||
break;
|
||||
|
||||
case CLK_TYPE_GEN3_PLL0:
|
||||
/*
|
||||
* PLL0 is a configurable multiplier clock. Register it as a
|
||||
* fixed factor clock for now as there's no generic multiplier
|
||||
* clock implementation and we currently have no need to change
|
||||
* the multiplier value.
|
||||
*/
|
||||
value = readl(base + CPG_PLL0CR);
|
||||
mult = (((value >> 24) & 0x7f) + 1) * 2;
|
||||
break;
|
||||
|
||||
case CLK_TYPE_GEN3_PLL1:
|
||||
mult = cpg_pll_config->pll1_mult;
|
||||
break;
|
||||
|
||||
case CLK_TYPE_GEN3_PLL2:
|
||||
/*
|
||||
* PLL2 is a configurable multiplier clock. Register it as a
|
||||
* fixed factor clock for now as there's no generic multiplier
|
||||
* clock implementation and we currently have no need to change
|
||||
* the multiplier value.
|
||||
*/
|
||||
value = readl(base + CPG_PLL2CR);
|
||||
mult = (((value >> 24) & 0x7f) + 1) * 2;
|
||||
break;
|
||||
|
||||
case CLK_TYPE_GEN3_PLL3:
|
||||
mult = cpg_pll_config->pll3_mult;
|
||||
break;
|
||||
|
||||
case CLK_TYPE_GEN3_PLL4:
|
||||
/*
|
||||
* PLL4 is a configurable multiplier clock. Register it as a
|
||||
* fixed factor clock for now as there's no generic multiplier
|
||||
* clock implementation and we currently have no need to change
|
||||
* the multiplier value.
|
||||
*/
|
||||
value = readl(base + CPG_PLL4CR);
|
||||
mult = (((value >> 24) & 0x7f) + 1) * 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
return clk_register_fixed_factor(NULL, core->name,
|
||||
__clk_get_name(parent), 0, mult, div);
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset register definitions.
|
||||
*/
|
||||
#define MODEMR 0xe6160060
|
||||
|
||||
static u32 rcar_gen3_read_mode_pins(void)
|
||||
{
|
||||
void __iomem *modemr = ioremap_nocache(MODEMR, 4);
|
||||
u32 mode;
|
||||
|
||||
BUG_ON(!modemr);
|
||||
mode = ioread32(modemr);
|
||||
iounmap(modemr);
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
static int __init r8a7795_cpg_mssr_init(struct device *dev)
|
||||
{
|
||||
u32 cpg_mode = rcar_gen3_read_mode_pins();
|
||||
|
||||
cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)];
|
||||
if (!cpg_pll_config->extal_div) {
|
||||
dev_err(dev, "Prohibited setting (cpg_mode=0x%x)\n", cpg_mode);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct cpg_mssr_info r8a7795_cpg_mssr_info __initconst = {
|
||||
/* Core Clocks */
|
||||
.core_clks = r8a7795_core_clks,
|
||||
.num_core_clks = ARRAY_SIZE(r8a7795_core_clks),
|
||||
.last_dt_core_clk = LAST_DT_CORE_CLK,
|
||||
.num_total_core_clks = MOD_CLK_BASE,
|
||||
|
||||
/* Module Clocks */
|
||||
.mod_clks = r8a7795_mod_clks,
|
||||
.num_mod_clks = ARRAY_SIZE(r8a7795_mod_clks),
|
||||
.num_hw_mod_clks = 12 * 32,
|
||||
|
||||
/* Critical Module Clocks */
|
||||
.crit_mod_clks = r8a7795_crit_mod_clks,
|
||||
.num_crit_mod_clks = ARRAY_SIZE(r8a7795_crit_mod_clks),
|
||||
|
||||
/* Callbacks */
|
||||
.init = r8a7795_cpg_mssr_init,
|
||||
.cpg_clk_register = r8a7795_cpg_clk_register,
|
||||
};
|
596
drivers/clk/shmobile/renesas-cpg-mssr.c
Normal file
596
drivers/clk/shmobile/renesas-cpg-mssr.c
Normal file
@ -0,0 +1,596 @@
|
||||
/*
|
||||
* Renesas Clock Pulse Generator / Module Standby and Software Reset
|
||||
*
|
||||
* Copyright (C) 2015 Glider bvba
|
||||
*
|
||||
* Based on clk-mstp.c, clk-rcar-gen2.c, and clk-rcar-gen3.c
|
||||
*
|
||||
* Copyright (C) 2013 Ideas On Board SPRL
|
||||
* Copyright (C) 2015 Renesas Electronics Corp.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_clock.h>
|
||||
#include <linux/pm_domain.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <dt-bindings/clock/renesas-cpg-mssr.h>
|
||||
|
||||
#include "renesas-cpg-mssr.h"
|
||||
#include "clk-div6.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#define WARN_DEBUG(x) do { } while (0)
|
||||
#else
|
||||
#define WARN_DEBUG(x) WARN_ON(x)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Module Standby and Software Reset register offets.
|
||||
*
|
||||
* If the registers exist, these are valid for SH-Mobile, R-Mobile,
|
||||
* R-Car Gen 2, and R-Car Gen 3.
|
||||
* These are NOT valid for R-Car Gen1 and RZ/A1!
|
||||
*/
|
||||
|
||||
/*
|
||||
* Module Stop Status Register offsets
|
||||
*/
|
||||
|
||||
static const u16 mstpsr[] = {
|
||||
0x030, 0x038, 0x040, 0x048, 0x04C, 0x03C, 0x1C0, 0x1C4,
|
||||
0x9A0, 0x9A4, 0x9A8, 0x9AC,
|
||||
};
|
||||
|
||||
#define MSTPSR(i) mstpsr[i]
|
||||
|
||||
|
||||
/*
|
||||
* System Module Stop Control Register offsets
|
||||
*/
|
||||
|
||||
static const u16 smstpcr[] = {
|
||||
0x130, 0x134, 0x138, 0x13C, 0x140, 0x144, 0x148, 0x14C,
|
||||
0x990, 0x994, 0x998, 0x99C,
|
||||
};
|
||||
|
||||
#define SMSTPCR(i) smstpcr[i]
|
||||
|
||||
|
||||
/*
|
||||
* Software Reset Register offsets
|
||||
*/
|
||||
|
||||
static const u16 srcr[] = {
|
||||
0x0A0, 0x0A8, 0x0B0, 0x0B8, 0x0BC, 0x0C4, 0x1C8, 0x1CC,
|
||||
0x920, 0x924, 0x928, 0x92C,
|
||||
};
|
||||
|
||||
#define SRCR(i) srcr[i]
|
||||
|
||||
|
||||
/* Realtime Module Stop Control Register offsets */
|
||||
#define RMSTPCR(i) (smstpcr[i] - 0x20)
|
||||
|
||||
/* Modem Module Stop Control Register offsets (r8a73a4) */
|
||||
#define MMSTPCR(i) (smstpcr[i] + 0x20)
|
||||
|
||||
/* Software Reset Clearing Register offsets */
|
||||
#define SRSTCLR(i) (0x940 + (i) * 4)
|
||||
|
||||
|
||||
/**
|
||||
* Clock Pulse Generator / Module Standby and Software Reset Private Data
|
||||
*
|
||||
* @dev: CPG/MSSR device
|
||||
* @base: CPG/MSSR register block base address
|
||||
* @mstp_lock: protects writes to SMSTPCR
|
||||
* @clks: Array containing all Core and Module Clocks
|
||||
* @num_core_clks: Number of Core Clocks in clks[]
|
||||
* @num_mod_clks: Number of Module Clocks in clks[]
|
||||
* @last_dt_core_clk: ID of the last Core Clock exported to DT
|
||||
*/
|
||||
struct cpg_mssr_priv {
|
||||
struct device *dev;
|
||||
void __iomem *base;
|
||||
spinlock_t mstp_lock;
|
||||
|
||||
struct clk **clks;
|
||||
unsigned int num_core_clks;
|
||||
unsigned int num_mod_clks;
|
||||
unsigned int last_dt_core_clk;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* struct mstp_clock - MSTP gating clock
|
||||
* @hw: handle between common and hardware-specific interfaces
|
||||
* @index: MSTP clock number
|
||||
* @priv: CPG/MSSR private data
|
||||
*/
|
||||
struct mstp_clock {
|
||||
struct clk_hw hw;
|
||||
u32 index;
|
||||
struct cpg_mssr_priv *priv;
|
||||
};
|
||||
|
||||
#define to_mstp_clock(_hw) container_of(_hw, struct mstp_clock, hw)
|
||||
|
||||
static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
|
||||
{
|
||||
struct mstp_clock *clock = to_mstp_clock(hw);
|
||||
struct cpg_mssr_priv *priv = clock->priv;
|
||||
unsigned int reg = clock->index / 32;
|
||||
unsigned int bit = clock->index % 32;
|
||||
struct device *dev = priv->dev;
|
||||
u32 bitmask = BIT(bit);
|
||||
unsigned long flags;
|
||||
unsigned int i;
|
||||
u32 value;
|
||||
|
||||
dev_dbg(dev, "MSTP %u%02u/%pC %s\n", reg, bit, hw->clk,
|
||||
enable ? "ON" : "OFF");
|
||||
spin_lock_irqsave(&priv->mstp_lock, flags);
|
||||
|
||||
value = clk_readl(priv->base + SMSTPCR(reg));
|
||||
if (enable)
|
||||
value &= ~bitmask;
|
||||
else
|
||||
value |= bitmask;
|
||||
clk_writel(value, priv->base + SMSTPCR(reg));
|
||||
|
||||
spin_unlock_irqrestore(&priv->mstp_lock, flags);
|
||||
|
||||
if (!enable)
|
||||
return 0;
|
||||
|
||||
for (i = 1000; i > 0; --i) {
|
||||
if (!(clk_readl(priv->base + MSTPSR(reg)) &
|
||||
bitmask))
|
||||
break;
|
||||
cpu_relax();
|
||||
}
|
||||
|
||||
if (!i) {
|
||||
dev_err(dev, "Failed to enable SMSTP %p[%d]\n",
|
||||
priv->base + SMSTPCR(reg), bit);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cpg_mstp_clock_enable(struct clk_hw *hw)
|
||||
{
|
||||
return cpg_mstp_clock_endisable(hw, true);
|
||||
}
|
||||
|
||||
static void cpg_mstp_clock_disable(struct clk_hw *hw)
|
||||
{
|
||||
cpg_mstp_clock_endisable(hw, false);
|
||||
}
|
||||
|
||||
static int cpg_mstp_clock_is_enabled(struct clk_hw *hw)
|
||||
{
|
||||
struct mstp_clock *clock = to_mstp_clock(hw);
|
||||
struct cpg_mssr_priv *priv = clock->priv;
|
||||
u32 value;
|
||||
|
||||
value = clk_readl(priv->base + MSTPSR(clock->index / 32));
|
||||
|
||||
return !(value & BIT(clock->index % 32));
|
||||
}
|
||||
|
||||
static const struct clk_ops cpg_mstp_clock_ops = {
|
||||
.enable = cpg_mstp_clock_enable,
|
||||
.disable = cpg_mstp_clock_disable,
|
||||
.is_enabled = cpg_mstp_clock_is_enabled,
|
||||
};
|
||||
|
||||
static
|
||||
struct clk *cpg_mssr_clk_src_twocell_get(struct of_phandle_args *clkspec,
|
||||
void *data)
|
||||
{
|
||||
unsigned int clkidx = clkspec->args[1];
|
||||
struct cpg_mssr_priv *priv = data;
|
||||
struct device *dev = priv->dev;
|
||||
unsigned int idx;
|
||||
const char *type;
|
||||
struct clk *clk;
|
||||
|
||||
switch (clkspec->args[0]) {
|
||||
case CPG_CORE:
|
||||
type = "core";
|
||||
if (clkidx > priv->last_dt_core_clk) {
|
||||
dev_err(dev, "Invalid %s clock index %u\n", type,
|
||||
clkidx);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
clk = priv->clks[clkidx];
|
||||
break;
|
||||
|
||||
case CPG_MOD:
|
||||
type = "module";
|
||||
idx = MOD_CLK_PACK(clkidx);
|
||||
if (clkidx % 100 > 31 || idx >= priv->num_mod_clks) {
|
||||
dev_err(dev, "Invalid %s clock index %u\n", type,
|
||||
clkidx);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
clk = priv->clks[priv->num_core_clks + idx];
|
||||
break;
|
||||
|
||||
default:
|
||||
dev_err(dev, "Invalid CPG clock type %u\n", clkspec->args[0]);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
if (IS_ERR(clk))
|
||||
dev_err(dev, "Cannot get %s clock %u: %ld", type, clkidx,
|
||||
PTR_ERR(clk));
|
||||
else
|
||||
dev_dbg(dev, "clock (%u, %u) is %pC at %pCr Hz\n",
|
||||
clkspec->args[0], clkspec->args[1], clk, clk);
|
||||
return clk;
|
||||
}
|
||||
|
||||
static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core,
|
||||
const struct cpg_mssr_info *info,
|
||||
struct cpg_mssr_priv *priv)
|
||||
{
|
||||
struct clk *clk = NULL, *parent;
|
||||
struct device *dev = priv->dev;
|
||||
unsigned int id = core->id;
|
||||
const char *parent_name;
|
||||
|
||||
WARN_DEBUG(id >= priv->num_core_clks);
|
||||
WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT);
|
||||
|
||||
switch (core->type) {
|
||||
case CLK_TYPE_IN:
|
||||
clk = of_clk_get_by_name(priv->dev->of_node, core->name);
|
||||
break;
|
||||
|
||||
case CLK_TYPE_FF:
|
||||
case CLK_TYPE_DIV6P1:
|
||||
WARN_DEBUG(core->parent >= priv->num_core_clks);
|
||||
parent = priv->clks[core->parent];
|
||||
if (IS_ERR(parent)) {
|
||||
clk = parent;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
parent_name = __clk_get_name(parent);
|
||||
if (core->type == CLK_TYPE_FF) {
|
||||
clk = clk_register_fixed_factor(NULL, core->name,
|
||||
parent_name, 0,
|
||||
core->mult, core->div);
|
||||
} else {
|
||||
clk = cpg_div6_register(core->name, 1, &parent_name,
|
||||
priv->base + core->offset);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (info->cpg_clk_register)
|
||||
clk = info->cpg_clk_register(dev, core, info,
|
||||
priv->clks, priv->base);
|
||||
else
|
||||
dev_err(dev, "%s has unsupported core clock type %u\n",
|
||||
core->name, core->type);
|
||||
break;
|
||||
}
|
||||
|
||||
if (IS_ERR_OR_NULL(clk))
|
||||
goto fail;
|
||||
|
||||
dev_dbg(dev, "Core clock %pC at %pCr Hz\n", clk, clk);
|
||||
priv->clks[id] = clk;
|
||||
return;
|
||||
|
||||
fail:
|
||||
dev_err(dev, "Failed to register %s clock %s: %ld\n", "core,",
|
||||
core->name, PTR_ERR(clk));
|
||||
}
|
||||
|
||||
static void __init cpg_mssr_register_mod_clk(const struct mssr_mod_clk *mod,
|
||||
const struct cpg_mssr_info *info,
|
||||
struct cpg_mssr_priv *priv)
|
||||
{
|
||||
struct mstp_clock *clock = NULL;
|
||||
struct device *dev = priv->dev;
|
||||
unsigned int id = mod->id;
|
||||
struct clk_init_data init;
|
||||
struct clk *parent, *clk;
|
||||
const char *parent_name;
|
||||
unsigned int i;
|
||||
|
||||
WARN_DEBUG(id < priv->num_core_clks);
|
||||
WARN_DEBUG(id >= priv->num_core_clks + priv->num_mod_clks);
|
||||
WARN_DEBUG(mod->parent >= priv->num_core_clks + priv->num_mod_clks);
|
||||
WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT);
|
||||
|
||||
parent = priv->clks[mod->parent];
|
||||
if (IS_ERR(parent)) {
|
||||
clk = parent;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
clock = kzalloc(sizeof(*clock), GFP_KERNEL);
|
||||
if (!clock) {
|
||||
clk = ERR_PTR(-ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
init.name = mod->name;
|
||||
init.ops = &cpg_mstp_clock_ops;
|
||||
init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT;
|
||||
for (i = 0; i < info->num_crit_mod_clks; i++)
|
||||
if (id == info->crit_mod_clks[i]) {
|
||||
#ifdef CLK_ENABLE_HAND_OFF
|
||||
dev_dbg(dev, "MSTP %s setting CLK_ENABLE_HAND_OFF\n",
|
||||
mod->name);
|
||||
init.flags |= CLK_ENABLE_HAND_OFF;
|
||||
break;
|
||||
#else
|
||||
dev_dbg(dev, "Ignoring MSTP %s to prevent disabling\n",
|
||||
mod->name);
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
parent_name = __clk_get_name(parent);
|
||||
init.parent_names = &parent_name;
|
||||
init.num_parents = 1;
|
||||
|
||||
clock->index = id - priv->num_core_clks;
|
||||
clock->priv = priv;
|
||||
clock->hw.init = &init;
|
||||
|
||||
clk = clk_register(NULL, &clock->hw);
|
||||
if (IS_ERR(clk))
|
||||
goto fail;
|
||||
|
||||
dev_dbg(dev, "Module clock %pC at %pCr Hz\n", clk, clk);
|
||||
priv->clks[id] = clk;
|
||||
return;
|
||||
|
||||
fail:
|
||||
dev_err(dev, "Failed to register %s clock %s: %ld\n", "module,",
|
||||
mod->name, PTR_ERR(clk));
|
||||
kfree(clock);
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_PM_GENERIC_DOMAINS_OF
|
||||
struct cpg_mssr_clk_domain {
|
||||
struct generic_pm_domain genpd;
|
||||
struct device_node *np;
|
||||
unsigned int num_core_pm_clks;
|
||||
unsigned int core_pm_clks[0];
|
||||
};
|
||||
|
||||
static bool cpg_mssr_is_pm_clk(const struct of_phandle_args *clkspec,
|
||||
struct cpg_mssr_clk_domain *pd)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (clkspec->np != pd->np || clkspec->args_count != 2)
|
||||
return false;
|
||||
|
||||
switch (clkspec->args[0]) {
|
||||
case CPG_CORE:
|
||||
for (i = 0; i < pd->num_core_pm_clks; i++)
|
||||
if (clkspec->args[1] == pd->core_pm_clks[i])
|
||||
return true;
|
||||
return false;
|
||||
|
||||
case CPG_MOD:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static int cpg_mssr_attach_dev(struct generic_pm_domain *genpd,
|
||||
struct device *dev)
|
||||
{
|
||||
struct cpg_mssr_clk_domain *pd =
|
||||
container_of(genpd, struct cpg_mssr_clk_domain, genpd);
|
||||
struct device_node *np = dev->of_node;
|
||||
struct of_phandle_args clkspec;
|
||||
struct clk *clk;
|
||||
int i = 0;
|
||||
int error;
|
||||
|
||||
while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i,
|
||||
&clkspec)) {
|
||||
if (cpg_mssr_is_pm_clk(&clkspec, pd))
|
||||
goto found;
|
||||
|
||||
of_node_put(clkspec.np);
|
||||
i++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
found:
|
||||
clk = of_clk_get_from_provider(&clkspec);
|
||||
of_node_put(clkspec.np);
|
||||
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
|
||||
error = pm_clk_create(dev);
|
||||
if (error) {
|
||||
dev_err(dev, "pm_clk_create failed %d\n", error);
|
||||
goto fail_put;
|
||||
}
|
||||
|
||||
error = pm_clk_add_clk(dev, clk);
|
||||
if (error) {
|
||||
dev_err(dev, "pm_clk_add_clk %pC failed %d\n", clk, error);
|
||||
goto fail_destroy;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail_destroy:
|
||||
pm_clk_destroy(dev);
|
||||
fail_put:
|
||||
clk_put(clk);
|
||||
return error;
|
||||
}
|
||||
|
||||
static void cpg_mssr_detach_dev(struct generic_pm_domain *genpd,
|
||||
struct device *dev)
|
||||
{
|
||||
if (!list_empty(&dev->power.subsys_data->clock_list))
|
||||
pm_clk_destroy(dev);
|
||||
}
|
||||
|
||||
static int __init cpg_mssr_add_clk_domain(struct device *dev,
|
||||
const unsigned int *core_pm_clks,
|
||||
unsigned int num_core_pm_clks)
|
||||
{
|
||||
struct device_node *np = dev->of_node;
|
||||
struct generic_pm_domain *genpd;
|
||||
struct cpg_mssr_clk_domain *pd;
|
||||
size_t pm_size = num_core_pm_clks * sizeof(core_pm_clks[0]);
|
||||
|
||||
pd = devm_kzalloc(dev, sizeof(*pd) + pm_size, GFP_KERNEL);
|
||||
if (!pd)
|
||||
return -ENOMEM;
|
||||
|
||||
pd->np = np;
|
||||
pd->num_core_pm_clks = num_core_pm_clks;
|
||||
memcpy(pd->core_pm_clks, core_pm_clks, pm_size);
|
||||
|
||||
genpd = &pd->genpd;
|
||||
genpd->name = np->name;
|
||||
genpd->flags = GENPD_FLAG_PM_CLK;
|
||||
pm_genpd_init(genpd, &simple_qos_governor, false);
|
||||
genpd->attach_dev = cpg_mssr_attach_dev;
|
||||
genpd->detach_dev = cpg_mssr_detach_dev;
|
||||
|
||||
of_genpd_add_provider_simple(np, genpd);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static inline int cpg_mssr_add_clk_domain(struct device *dev,
|
||||
const unsigned int *core_pm_clks,
|
||||
unsigned int num_core_pm_clks)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* !CONFIG_PM_GENERIC_DOMAINS_OF */
|
||||
|
||||
|
||||
static const struct of_device_id cpg_mssr_match[] = {
|
||||
#ifdef CONFIG_ARCH_R8A7795
|
||||
{
|
||||
.compatible = "renesas,r8a7795-cpg-mssr",
|
||||
.data = &r8a7795_cpg_mssr_info,
|
||||
},
|
||||
#endif
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static void cpg_mssr_del_clk_provider(void *data)
|
||||
{
|
||||
of_clk_del_provider(data);
|
||||
}
|
||||
|
||||
static int __init cpg_mssr_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
const struct cpg_mssr_info *info;
|
||||
struct cpg_mssr_priv *priv;
|
||||
unsigned int nclks, i;
|
||||
struct resource *res;
|
||||
struct clk **clks;
|
||||
int error;
|
||||
|
||||
info = of_match_node(cpg_mssr_match, np)->data;
|
||||
if (info->init) {
|
||||
error = info->init(dev);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->dev = dev;
|
||||
spin_lock_init(&priv->mstp_lock);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
priv->base = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(priv->base))
|
||||
return PTR_ERR(priv->base);
|
||||
|
||||
nclks = info->num_total_core_clks + info->num_hw_mod_clks;
|
||||
clks = devm_kmalloc_array(dev, nclks, sizeof(*clks), GFP_KERNEL);
|
||||
if (!clks)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->clks = clks;
|
||||
priv->num_core_clks = info->num_total_core_clks;
|
||||
priv->num_mod_clks = info->num_hw_mod_clks;
|
||||
priv->last_dt_core_clk = info->last_dt_core_clk;
|
||||
|
||||
for (i = 0; i < nclks; i++)
|
||||
clks[i] = ERR_PTR(-ENOENT);
|
||||
|
||||
for (i = 0; i < info->num_core_clks; i++)
|
||||
cpg_mssr_register_core_clk(&info->core_clks[i], info, priv);
|
||||
|
||||
for (i = 0; i < info->num_mod_clks; i++)
|
||||
cpg_mssr_register_mod_clk(&info->mod_clks[i], info, priv);
|
||||
|
||||
error = of_clk_add_provider(np, cpg_mssr_clk_src_twocell_get, priv);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
devm_add_action(dev, cpg_mssr_del_clk_provider, np);
|
||||
|
||||
error = cpg_mssr_add_clk_domain(dev, info->core_pm_clks,
|
||||
info->num_core_pm_clks);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver cpg_mssr_driver = {
|
||||
.driver = {
|
||||
.name = "renesas-cpg-mssr",
|
||||
.of_match_table = cpg_mssr_match,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init cpg_mssr_init(void)
|
||||
{
|
||||
return platform_driver_probe(&cpg_mssr_driver, cpg_mssr_probe);
|
||||
}
|
||||
|
||||
subsys_initcall(cpg_mssr_init);
|
||||
|
||||
MODULE_DESCRIPTION("Renesas CPG/MSSR Driver");
|
||||
MODULE_LICENSE("GPL v2");
|
132
drivers/clk/shmobile/renesas-cpg-mssr.h
Normal file
132
drivers/clk/shmobile/renesas-cpg-mssr.h
Normal file
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Renesas Clock Pulse Generator / Module Standby and Software Reset
|
||||
*
|
||||
* Copyright (C) 2015 Glider bvba
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*/
|
||||
|
||||
#ifndef __CLK_RENESAS_CPG_MSSR_H__
|
||||
#define __CLK_RENESAS_CPG_MSSR_H__
|
||||
|
||||
/*
|
||||
* Definitions of CPG Core Clocks
|
||||
*
|
||||
* These include:
|
||||
* - Clock outputs exported to DT
|
||||
* - External input clocks
|
||||
* - Internal CPG clocks
|
||||
*/
|
||||
|
||||
struct cpg_core_clk {
|
||||
/* Common */
|
||||
const char *name;
|
||||
unsigned int id;
|
||||
unsigned int type;
|
||||
/* Depending on type */
|
||||
unsigned int parent; /* Core Clocks only */
|
||||
unsigned int div;
|
||||
unsigned int mult;
|
||||
unsigned int offset;
|
||||
};
|
||||
|
||||
enum clk_types {
|
||||
/* Generic */
|
||||
CLK_TYPE_IN, /* External Clock Input */
|
||||
CLK_TYPE_FF, /* Fixed Factor Clock */
|
||||
CLK_TYPE_DIV6P1, /* DIV6 Clock with 1 parent clock */
|
||||
|
||||
/* Custom definitions start here */
|
||||
CLK_TYPE_CUSTOM,
|
||||
};
|
||||
|
||||
#define DEF_TYPE(_name, _id, _type...) \
|
||||
{ .name = _name, .id = _id, .type = _type }
|
||||
#define DEF_BASE(_name, _id, _type, _parent...) \
|
||||
DEF_TYPE(_name, _id, _type, .parent = _parent)
|
||||
|
||||
#define DEF_INPUT(_name, _id) \
|
||||
DEF_TYPE(_name, _id, CLK_TYPE_IN)
|
||||
#define DEF_FIXED(_name, _id, _parent, _div, _mult) \
|
||||
DEF_BASE(_name, _id, CLK_TYPE_FF, _parent, .div = _div, .mult = _mult)
|
||||
#define DEF_DIV6P1(_name, _id, _parent, _offset) \
|
||||
DEF_BASE(_name, _id, CLK_TYPE_DIV6P1, _parent, .offset = _offset)
|
||||
|
||||
|
||||
/*
|
||||
* Definitions of Module Clocks
|
||||
*/
|
||||
|
||||
struct mssr_mod_clk {
|
||||
const char *name;
|
||||
unsigned int id;
|
||||
unsigned int parent; /* Add MOD_CLK_BASE for Module Clocks */
|
||||
};
|
||||
|
||||
/* Convert from sparse base-100 to packed index space */
|
||||
#define MOD_CLK_PACK(x) ((x) - ((x) / 100) * (100 - 32))
|
||||
|
||||
#define MOD_CLK_ID(x) (MOD_CLK_BASE + MOD_CLK_PACK(x))
|
||||
|
||||
#define DEF_MOD(_name, _mod, _parent...) \
|
||||
{ .name = _name, .id = MOD_CLK_ID(_mod), .parent = _parent }
|
||||
|
||||
|
||||
struct device_node;
|
||||
|
||||
/**
|
||||
* SoC-specific CPG/MSSR Description
|
||||
*
|
||||
* @core_clks: Array of Core Clock definitions
|
||||
* @num_core_clks: Number of entries in core_clks[]
|
||||
* @last_dt_core_clk: ID of the last Core Clock exported to DT
|
||||
* @num_total_core_clks: Total number of Core Clocks (exported + internal)
|
||||
*
|
||||
* @mod_clks: Array of Module Clock definitions
|
||||
* @num_mod_clks: Number of entries in mod_clks[]
|
||||
* @num_hw_mod_clks: Number of Module Clocks supported by the hardware
|
||||
*
|
||||
* @crit_mod_clks: Array with Module Clock IDs of critical clocks that
|
||||
* should not be disabled without a knowledgeable driver
|
||||
* @num_crit_mod_clks: Number of entries in crit_mod_clks[]
|
||||
*
|
||||
* @core_pm_clks: Array with IDs of Core Clocks that are suitable for Power
|
||||
* Management, in addition to Module Clocks
|
||||
* @num_core_pm_clks: Number of entries in core_pm_clks[]
|
||||
*
|
||||
* @init: Optional callback to perform SoC-specific initialization
|
||||
* @cpg_clk_register: Optional callback to handle special Core Clock types
|
||||
*/
|
||||
|
||||
struct cpg_mssr_info {
|
||||
/* Core Clocks */
|
||||
const struct cpg_core_clk *core_clks;
|
||||
unsigned int num_core_clks;
|
||||
unsigned int last_dt_core_clk;
|
||||
unsigned int num_total_core_clks;
|
||||
|
||||
/* Module Clocks */
|
||||
const struct mssr_mod_clk *mod_clks;
|
||||
unsigned int num_mod_clks;
|
||||
unsigned int num_hw_mod_clks;
|
||||
|
||||
/* Critical Module Clocks that should not be disabled */
|
||||
const unsigned int *crit_mod_clks;
|
||||
unsigned int num_crit_mod_clks;
|
||||
|
||||
/* Core Clocks suitable for PM, in addition to the Module Clocks */
|
||||
const unsigned int *core_pm_clks;
|
||||
unsigned int num_core_pm_clks;
|
||||
|
||||
/* Callbacks */
|
||||
int (*init)(struct device *dev);
|
||||
struct clk *(*cpg_clk_register)(struct device *dev,
|
||||
const struct cpg_core_clk *core,
|
||||
const struct cpg_mssr_info *info,
|
||||
struct clk **clks, void __iomem *base);
|
||||
};
|
||||
|
||||
extern const struct cpg_mssr_info r8a7795_cpg_mssr_info;
|
||||
#endif
|
@ -549,19 +549,20 @@ static int clk_fs660c32_vco_get_params(unsigned long input,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long quadfs_pll_fs660c32_round_rate(struct clk_hw *hw, unsigned long rate
|
||||
, unsigned long *prate)
|
||||
static long quadfs_pll_fs660c32_round_rate(struct clk_hw *hw,
|
||||
unsigned long rate,
|
||||
unsigned long *prate)
|
||||
{
|
||||
struct stm_fs params;
|
||||
|
||||
if (!clk_fs660c32_vco_get_params(*prate, rate, ¶ms))
|
||||
clk_fs660c32_vco_get_rate(*prate, ¶ms, &rate);
|
||||
if (clk_fs660c32_vco_get_params(*prate, rate, ¶ms))
|
||||
return rate;
|
||||
|
||||
pr_debug("%s: %s new rate %ld [sdiv=0x%x,md=0x%x,pe=0x%x,nsdiv3=%u]\n",
|
||||
clk_fs660c32_vco_get_rate(*prate, ¶ms, &rate);
|
||||
|
||||
pr_debug("%s: %s new rate %ld [ndiv=%u]\n",
|
||||
__func__, clk_hw_get_name(hw),
|
||||
rate, (unsigned int)params.sdiv,
|
||||
(unsigned int)params.mdiv,
|
||||
(unsigned int)params.pe, (unsigned int)params.nsdiv);
|
||||
rate, (unsigned int)params.ndiv);
|
||||
|
||||
return rate;
|
||||
}
|
||||
|
@ -323,7 +323,7 @@ static void omap2_apll_deny_idle(struct clk_hw_omap *clk)
|
||||
omap2_apll_set_autoidle(clk, OMAP2_APLL_AUTOIDLE_DISABLE);
|
||||
}
|
||||
|
||||
static struct clk_hw_omap_ops omap2_apll_hwops = {
|
||||
static const struct clk_hw_omap_ops omap2_apll_hwops = {
|
||||
.allow_idle = &omap2_apll_allow_idle,
|
||||
.deny_idle = &omap2_apll_deny_idle,
|
||||
};
|
||||
|
@ -305,8 +305,9 @@ static void _lookup_sddiv(struct clk_hw_omap *clk, u8 *sd_div, u16 m, u8 n)
|
||||
static int omap3_noncore_dpll_program(struct clk_hw_omap *clk, u16 freqsel)
|
||||
{
|
||||
struct dpll_data *dd = clk->dpll_data;
|
||||
u8 dco, sd_div;
|
||||
u8 dco, sd_div, ai = 0;
|
||||
u32 v;
|
||||
bool errata_i810;
|
||||
|
||||
/* 3430 ES2 TRM: 4.7.6.9 DPLL Programming Sequence */
|
||||
_omap3_noncore_dpll_bypass(clk);
|
||||
@ -350,6 +351,25 @@ static int omap3_noncore_dpll_program(struct clk_hw_omap *clk, u16 freqsel)
|
||||
v |= sd_div << __ffs(dd->sddiv_mask);
|
||||
}
|
||||
|
||||
/*
|
||||
* Errata i810 - DPLL controller can get stuck while transitioning
|
||||
* to a power saving state. Software must ensure the DPLL can not
|
||||
* transition to a low power state while changing M/N values.
|
||||
* Easiest way to accomplish this is to prevent DPLL autoidle
|
||||
* before doing the M/N re-program.
|
||||
*/
|
||||
errata_i810 = ti_clk_get_features()->flags & TI_CLK_ERRATA_I810;
|
||||
|
||||
if (errata_i810) {
|
||||
ai = omap3_dpll_autoidle_read(clk);
|
||||
if (ai) {
|
||||
omap3_dpll_deny_idle(clk);
|
||||
|
||||
/* OCP barrier */
|
||||
omap3_dpll_autoidle_read(clk);
|
||||
}
|
||||
}
|
||||
|
||||
ti_clk_ll_ops->clk_writel(v, dd->mult_div1_reg);
|
||||
|
||||
/* Set 4X multiplier and low-power mode */
|
||||
@ -379,6 +399,9 @@ static int omap3_noncore_dpll_program(struct clk_hw_omap *clk, u16 freqsel)
|
||||
|
||||
_omap3_noncore_dpll_lock(clk);
|
||||
|
||||
if (errata_i810 && ai)
|
||||
omap3_dpll_allow_idle(clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -95,13 +95,12 @@ static void __init clk_sp810_of_setup(struct device_node *node)
|
||||
int i;
|
||||
bool deprecated;
|
||||
|
||||
if (!sp810) {
|
||||
pr_err("Failed to allocate memory for SP810!\n");
|
||||
if (!sp810)
|
||||
return;
|
||||
}
|
||||
|
||||
if (of_clk_parent_fill(node, parent_names, num) != num) {
|
||||
pr_warn("Failed to obtain parent clocks for SP810!\n");
|
||||
kfree(sp810);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -447,5 +447,6 @@
|
||||
#define IMX7D_SEMA4_HS_ROOT_CLK 434
|
||||
#define IMX7D_PLL_DRAM_TEST_DIV 435
|
||||
#define IMX7D_ADC_ROOT_CLK 436
|
||||
#define IMX7D_CLK_END 437
|
||||
#define IMX7D_CLK_ARM 437
|
||||
#define IMX7D_CLK_END 438
|
||||
#endif /* __DT_BINDINGS_CLOCK_IMX7D_H */
|
||||
|
339
include/dt-bindings/clock/qcom,gcc-msm8996.h
Normal file
339
include/dt-bindings/clock/qcom,gcc-msm8996.h
Normal file
@ -0,0 +1,339 @@
|
||||
/*
|
||||
* Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_CLK_MSM_GCC_8996_H
|
||||
#define _DT_BINDINGS_CLK_MSM_GCC_8996_H
|
||||
|
||||
#define GPLL0_EARLY 0
|
||||
#define GPLL0 1
|
||||
#define GPLL1_EARLY 2
|
||||
#define GPLL1 3
|
||||
#define GPLL2_EARLY 4
|
||||
#define GPLL2 5
|
||||
#define GPLL3_EARLY 6
|
||||
#define GPLL3 7
|
||||
#define GPLL4_EARLY 8
|
||||
#define GPLL4 9
|
||||
#define SYSTEM_NOC_CLK_SRC 10
|
||||
#define CONFIG_NOC_CLK_SRC 11
|
||||
#define PERIPH_NOC_CLK_SRC 12
|
||||
#define MMSS_BIMC_GFX_CLK_SRC 13
|
||||
#define USB30_MASTER_CLK_SRC 14
|
||||
#define USB30_MOCK_UTMI_CLK_SRC 15
|
||||
#define USB3_PHY_AUX_CLK_SRC 16
|
||||
#define USB20_MASTER_CLK_SRC 17
|
||||
#define USB20_MOCK_UTMI_CLK_SRC 18
|
||||
#define SDCC1_APPS_CLK_SRC 19
|
||||
#define SDCC1_ICE_CORE_CLK_SRC 20
|
||||
#define SDCC2_APPS_CLK_SRC 21
|
||||
#define SDCC3_APPS_CLK_SRC 22
|
||||
#define SDCC4_APPS_CLK_SRC 23
|
||||
#define BLSP1_QUP1_SPI_APPS_CLK_SRC 24
|
||||
#define BLSP1_QUP1_I2C_APPS_CLK_SRC 25
|
||||
#define BLSP1_UART1_APPS_CLK_SRC 26
|
||||
#define BLSP1_QUP2_SPI_APPS_CLK_SRC 27
|
||||
#define BLSP1_QUP2_I2C_APPS_CLK_SRC 28
|
||||
#define BLSP1_UART2_APPS_CLK_SRC 29
|
||||
#define BLSP1_QUP3_SPI_APPS_CLK_SRC 30
|
||||
#define BLSP1_QUP3_I2C_APPS_CLK_SRC 31
|
||||
#define BLSP1_UART3_APPS_CLK_SRC 32
|
||||
#define BLSP1_QUP4_SPI_APPS_CLK_SRC 33
|
||||
#define BLSP1_QUP4_I2C_APPS_CLK_SRC 34
|
||||
#define BLSP1_UART4_APPS_CLK_SRC 35
|
||||
#define BLSP1_QUP5_SPI_APPS_CLK_SRC 36
|
||||
#define BLSP1_QUP5_I2C_APPS_CLK_SRC 37
|
||||
#define BLSP1_UART5_APPS_CLK_SRC 38
|
||||
#define BLSP1_QUP6_SPI_APPS_CLK_SRC 39
|
||||
#define BLSP1_QUP6_I2C_APPS_CLK_SRC 40
|
||||
#define BLSP1_UART6_APPS_CLK_SRC 41
|
||||
#define BLSP2_QUP1_SPI_APPS_CLK_SRC 42
|
||||
#define BLSP2_QUP1_I2C_APPS_CLK_SRC 43
|
||||
#define BLSP2_UART1_APPS_CLK_SRC 44
|
||||
#define BLSP2_QUP2_SPI_APPS_CLK_SRC 45
|
||||
#define BLSP2_QUP2_I2C_APPS_CLK_SRC 46
|
||||
#define BLSP2_UART2_APPS_CLK_SRC 47
|
||||
#define BLSP2_QUP3_SPI_APPS_CLK_SRC 48
|
||||
#define BLSP2_QUP3_I2C_APPS_CLK_SRC 49
|
||||
#define BLSP2_UART3_APPS_CLK_SRC 50
|
||||
#define BLSP2_QUP4_SPI_APPS_CLK_SRC 51
|
||||
#define BLSP2_QUP4_I2C_APPS_CLK_SRC 52
|
||||
#define BLSP2_UART4_APPS_CLK_SRC 53
|
||||
#define BLSP2_QUP5_SPI_APPS_CLK_SRC 54
|
||||
#define BLSP2_QUP5_I2C_APPS_CLK_SRC 55
|
||||
#define BLSP2_UART5_APPS_CLK_SRC 56
|
||||
#define BLSP2_QUP6_SPI_APPS_CLK_SRC 57
|
||||
#define BLSP2_QUP6_I2C_APPS_CLK_SRC 58
|
||||
#define BLSP2_UART6_APPS_CLK_SRC 59
|
||||
#define PDM2_CLK_SRC 60
|
||||
#define TSIF_REF_CLK_SRC 61
|
||||
#define CE1_CLK_SRC 62
|
||||
#define GCC_SLEEP_CLK_SRC 63
|
||||
#define BIMC_CLK_SRC 64
|
||||
#define HMSS_AHB_CLK_SRC 65
|
||||
#define BIMC_HMSS_AXI_CLK_SRC 66
|
||||
#define HMSS_RBCPR_CLK_SRC 67
|
||||
#define HMSS_GPLL0_CLK_SRC 68
|
||||
#define GP1_CLK_SRC 69
|
||||
#define GP2_CLK_SRC 70
|
||||
#define GP3_CLK_SRC 71
|
||||
#define PCIE_AUX_CLK_SRC 72
|
||||
#define UFS_AXI_CLK_SRC 73
|
||||
#define UFS_ICE_CORE_CLK_SRC 74
|
||||
#define QSPI_SER_CLK_SRC 75
|
||||
#define GCC_SYS_NOC_AXI_CLK 76
|
||||
#define GCC_SYS_NOC_HMSS_AHB_CLK 77
|
||||
#define GCC_SNOC_CNOC_AHB_CLK 78
|
||||
#define GCC_SNOC_PNOC_AHB_CLK 79
|
||||
#define GCC_SYS_NOC_AT_CLK 80
|
||||
#define GCC_SYS_NOC_USB3_AXI_CLK 81
|
||||
#define GCC_SYS_NOC_UFS_AXI_CLK 82
|
||||
#define GCC_CFG_NOC_AHB_CLK 83
|
||||
#define GCC_PERIPH_NOC_AHB_CLK 84
|
||||
#define GCC_PERIPH_NOC_USB20_AHB_CLK 85
|
||||
#define GCC_TIC_CLK 86
|
||||
#define GCC_IMEM_AXI_CLK 87
|
||||
#define GCC_MMSS_SYS_NOC_AXI_CLK 88
|
||||
#define GCC_MMSS_NOC_CFG_AHB_CLK 89
|
||||
#define GCC_MMSS_BIMC_GFX_CLK 90
|
||||
#define GCC_USB30_MASTER_CLK 91
|
||||
#define GCC_USB30_SLEEP_CLK 92
|
||||
#define GCC_USB30_MOCK_UTMI_CLK 93
|
||||
#define GCC_USB3_PHY_AUX_CLK 94
|
||||
#define GCC_USB3_PHY_PIPE_CLK 95
|
||||
#define GCC_USB20_MASTER_CLK 96
|
||||
#define GCC_USB20_SLEEP_CLK 97
|
||||
#define GCC_USB20_MOCK_UTMI_CLK 98
|
||||
#define GCC_USB_PHY_CFG_AHB2PHY_CLK 99
|
||||
#define GCC_SDCC1_APPS_CLK 100
|
||||
#define GCC_SDCC1_AHB_CLK 101
|
||||
#define GCC_SDCC1_ICE_CORE_CLK 102
|
||||
#define GCC_SDCC2_APPS_CLK 103
|
||||
#define GCC_SDCC2_AHB_CLK 104
|
||||
#define GCC_SDCC3_APPS_CLK 105
|
||||
#define GCC_SDCC3_AHB_CLK 106
|
||||
#define GCC_SDCC4_APPS_CLK 107
|
||||
#define GCC_SDCC4_AHB_CLK 108
|
||||
#define GCC_BLSP1_AHB_CLK 109
|
||||
#define GCC_BLSP1_SLEEP_CLK 110
|
||||
#define GCC_BLSP1_QUP1_SPI_APPS_CLK 111
|
||||
#define GCC_BLSP1_QUP1_I2C_APPS_CLK 112
|
||||
#define GCC_BLSP1_UART1_APPS_CLK 113
|
||||
#define GCC_BLSP1_QUP2_SPI_APPS_CLK 114
|
||||
#define GCC_BLSP1_QUP2_I2C_APPS_CLK 115
|
||||
#define GCC_BLSP1_UART2_APPS_CLK 116
|
||||
#define GCC_BLSP1_QUP3_SPI_APPS_CLK 117
|
||||
#define GCC_BLSP1_QUP3_I2C_APPS_CLK 118
|
||||
#define GCC_BLSP1_UART3_APPS_CLK 119
|
||||
#define GCC_BLSP1_QUP4_SPI_APPS_CLK 120
|
||||
#define GCC_BLSP1_QUP4_I2C_APPS_CLK 121
|
||||
#define GCC_BLSP1_UART4_APPS_CLK 122
|
||||
#define GCC_BLSP1_QUP5_SPI_APPS_CLK 123
|
||||
#define GCC_BLSP1_QUP5_I2C_APPS_CLK 124
|
||||
#define GCC_BLSP1_UART5_APPS_CLK 125
|
||||
#define GCC_BLSP1_QUP6_SPI_APPS_CLK 126
|
||||
#define GCC_BLSP1_QUP6_I2C_APPS_CLK 127
|
||||
#define GCC_BLSP1_UART6_APPS_CLK 128
|
||||
#define GCC_BLSP2_AHB_CLK 129
|
||||
#define GCC_BLSP2_SLEEP_CLK 130
|
||||
#define GCC_BLSP2_QUP1_SPI_APPS_CLK 131
|
||||
#define GCC_BLSP2_QUP1_I2C_APPS_CLK 132
|
||||
#define GCC_BLSP2_UART1_APPS_CLK 133
|
||||
#define GCC_BLSP2_QUP2_SPI_APPS_CLK 134
|
||||
#define GCC_BLSP2_QUP2_I2C_APPS_CLK 135
|
||||
#define GCC_BLSP2_UART2_APPS_CLK 136
|
||||
#define GCC_BLSP2_QUP3_SPI_APPS_CLK 137
|
||||
#define GCC_BLSP2_QUP3_I2C_APPS_CLK 138
|
||||
#define GCC_BLSP2_UART3_APPS_CLK 139
|
||||
#define GCC_BLSP2_QUP4_SPI_APPS_CLK 140
|
||||
#define GCC_BLSP2_QUP4_I2C_APPS_CLK 141
|
||||
#define GCC_BLSP2_UART4_APPS_CLK 142
|
||||
#define GCC_BLSP2_QUP5_SPI_APPS_CLK 143
|
||||
#define GCC_BLSP2_QUP5_I2C_APPS_CLK 144
|
||||
#define GCC_BLSP2_UART5_APPS_CLK 145
|
||||
#define GCC_BLSP2_QUP6_SPI_APPS_CLK 146
|
||||
#define GCC_BLSP2_QUP6_I2C_APPS_CLK 147
|
||||
#define GCC_BLSP2_UART6_APPS_CLK 148
|
||||
#define GCC_PDM_AHB_CLK 149
|
||||
#define GCC_PDM_XO4_CLK 150
|
||||
#define GCC_PDM2_CLK 151
|
||||
#define GCC_PRNG_AHB_CLK 152
|
||||
#define GCC_TSIF_AHB_CLK 153
|
||||
#define GCC_TSIF_REF_CLK 154
|
||||
#define GCC_TSIF_INACTIVITY_TIMERS_CLK 155
|
||||
#define GCC_TCSR_AHB_CLK 156
|
||||
#define GCC_BOOT_ROM_AHB_CLK 157
|
||||
#define GCC_MSG_RAM_AHB_CLK 158
|
||||
#define GCC_TLMM_AHB_CLK 159
|
||||
#define GCC_TLMM_CLK 160
|
||||
#define GCC_MPM_AHB_CLK 161
|
||||
#define GCC_SPMI_SER_CLK 162
|
||||
#define GCC_SPMI_CNOC_AHB_CLK 163
|
||||
#define GCC_CE1_CLK 164
|
||||
#define GCC_CE1_AXI_CLK 165
|
||||
#define GCC_CE1_AHB_CLK 166
|
||||
#define GCC_BIMC_HMSS_AXI_CLK 167
|
||||
#define GCC_BIMC_GFX_CLK 168
|
||||
#define GCC_HMSS_AHB_CLK 169
|
||||
#define GCC_HMSS_SLV_AXI_CLK 170
|
||||
#define GCC_HMSS_MSTR_AXI_CLK 171
|
||||
#define GCC_HMSS_RBCPR_CLK 172
|
||||
#define GCC_GP1_CLK 173
|
||||
#define GCC_GP2_CLK 174
|
||||
#define GCC_GP3_CLK 175
|
||||
#define GCC_PCIE_0_SLV_AXI_CLK 176
|
||||
#define GCC_PCIE_0_MSTR_AXI_CLK 177
|
||||
#define GCC_PCIE_0_CFG_AHB_CLK 178
|
||||
#define GCC_PCIE_0_AUX_CLK 179
|
||||
#define GCC_PCIE_0_PIPE_CLK 180
|
||||
#define GCC_PCIE_1_SLV_AXI_CLK 181
|
||||
#define GCC_PCIE_1_MSTR_AXI_CLK 182
|
||||
#define GCC_PCIE_1_CFG_AHB_CLK 183
|
||||
#define GCC_PCIE_1_AUX_CLK 184
|
||||
#define GCC_PCIE_1_PIPE_CLK 185
|
||||
#define GCC_PCIE_2_SLV_AXI_CLK 186
|
||||
#define GCC_PCIE_2_MSTR_AXI_CLK 187
|
||||
#define GCC_PCIE_2_CFG_AHB_CLK 188
|
||||
#define GCC_PCIE_2_AUX_CLK 189
|
||||
#define GCC_PCIE_2_PIPE_CLK 190
|
||||
#define GCC_PCIE_PHY_CFG_AHB_CLK 191
|
||||
#define GCC_PCIE_PHY_AUX_CLK 192
|
||||
#define GCC_UFS_AXI_CLK 193
|
||||
#define GCC_UFS_AHB_CLK 194
|
||||
#define GCC_UFS_TX_CFG_CLK 195
|
||||
#define GCC_UFS_RX_CFG_CLK 196
|
||||
#define GCC_UFS_TX_SYMBOL_0_CLK 197
|
||||
#define GCC_UFS_RX_SYMBOL_0_CLK 198
|
||||
#define GCC_UFS_RX_SYMBOL_1_CLK 199
|
||||
#define GCC_UFS_UNIPRO_CORE_CLK 200
|
||||
#define GCC_UFS_ICE_CORE_CLK 201
|
||||
#define GCC_UFS_SYS_CLK_CORE_CLK 202
|
||||
#define GCC_UFS_TX_SYMBOL_CLK_CORE_CLK 203
|
||||
#define GCC_AGGRE0_SNOC_AXI_CLK 204
|
||||
#define GCC_AGGRE0_CNOC_AHB_CLK 205
|
||||
#define GCC_SMMU_AGGRE0_AXI_CLK 206
|
||||
#define GCC_SMMU_AGGRE0_AHB_CLK 207
|
||||
#define GCC_AGGRE1_PNOC_AHB_CLK 208
|
||||
#define GCC_AGGRE2_UFS_AXI_CLK 209
|
||||
#define GCC_AGGRE2_USB3_AXI_CLK 210
|
||||
#define GCC_QSPI_AHB_CLK 211
|
||||
#define GCC_QSPI_SER_CLK 212
|
||||
#define GCC_USB3_CLKREF_CLK 213
|
||||
#define GCC_HDMI_CLKREF_CLK 214
|
||||
#define GCC_UFS_CLKREF_CLK 215
|
||||
#define GCC_PCIE_CLKREF_CLK 216
|
||||
#define GCC_RX2_USB2_CLKREF_CLK 217
|
||||
#define GCC_RX1_USB2_CLKREF_CLK 218
|
||||
|
||||
#define GCC_SYSTEM_NOC_BCR 0
|
||||
#define GCC_CONFIG_NOC_BCR 1
|
||||
#define GCC_PERIPH_NOC_BCR 2
|
||||
#define GCC_IMEM_BCR 3
|
||||
#define GCC_MMSS_BCR 4
|
||||
#define GCC_PIMEM_BCR 5
|
||||
#define GCC_QDSS_BCR 6
|
||||
#define GCC_USB_30_BCR 7
|
||||
#define GCC_USB_20_BCR 8
|
||||
#define GCC_QUSB2PHY_PRIM_BCR 9
|
||||
#define GCC_QUSB2PHY_SEC_BCR 10
|
||||
#define GCC_USB_PHY_CFG_AHB2PHY_BCR 11
|
||||
#define GCC_SDCC1_BCR 12
|
||||
#define GCC_SDCC2_BCR 13
|
||||
#define GCC_SDCC3_BCR 14
|
||||
#define GCC_SDCC4_BCR 15
|
||||
#define GCC_BLSP1_BCR 16
|
||||
#define GCC_BLSP1_QUP1_BCR 17
|
||||
#define GCC_BLSP1_UART1_BCR 18
|
||||
#define GCC_BLSP1_QUP2_BCR 19
|
||||
#define GCC_BLSP1_UART2_BCR 20
|
||||
#define GCC_BLSP1_QUP3_BCR 21
|
||||
#define GCC_BLSP1_UART3_BCR 22
|
||||
#define GCC_BLSP1_QUP4_BCR 23
|
||||
#define GCC_BLSP1_UART4_BCR 24
|
||||
#define GCC_BLSP1_QUP5_BCR 25
|
||||
#define GCC_BLSP1_UART5_BCR 26
|
||||
#define GCC_BLSP1_QUP6_BCR 27
|
||||
#define GCC_BLSP1_UART6_BCR 28
|
||||
#define GCC_BLSP2_BCR 29
|
||||
#define GCC_BLSP2_QUP1_BCR 30
|
||||
#define GCC_BLSP2_UART1_BCR 31
|
||||
#define GCC_BLSP2_QUP2_BCR 32
|
||||
#define GCC_BLSP2_UART2_BCR 33
|
||||
#define GCC_BLSP2_QUP3_BCR 34
|
||||
#define GCC_BLSP2_UART3_BCR 35
|
||||
#define GCC_BLSP2_QUP4_BCR 36
|
||||
#define GCC_BLSP2_UART4_BCR 37
|
||||
#define GCC_BLSP2_QUP5_BCR 38
|
||||
#define GCC_BLSP2_UART5_BCR 39
|
||||
#define GCC_BLSP2_QUP6_BCR 40
|
||||
#define GCC_BLSP2_UART6_BCR 41
|
||||
#define GCC_PDM_BCR 42
|
||||
#define GCC_PRNG_BCR 43
|
||||
#define GCC_TSIF_BCR 44
|
||||
#define GCC_TCSR_BCR 45
|
||||
#define GCC_BOOT_ROM_BCR 46
|
||||
#define GCC_MSG_RAM_BCR 47
|
||||
#define GCC_TLMM_BCR 48
|
||||
#define GCC_MPM_BCR 49
|
||||
#define GCC_SEC_CTRL_BCR 50
|
||||
#define GCC_SPMI_BCR 51
|
||||
#define GCC_SPDM_BCR 52
|
||||
#define GCC_CE1_BCR 53
|
||||
#define GCC_BIMC_BCR 54
|
||||
#define GCC_SNOC_BUS_TIMEOUT0_BCR 55
|
||||
#define GCC_SNOC_BUS_TIMEOUT2_BCR 56
|
||||
#define GCC_SNOC_BUS_TIMEOUT1_BCR 57
|
||||
#define GCC_SNOC_BUS_TIMEOUT3_BCR 58
|
||||
#define GCC_SNOC_BUS_TIMEOUT_EXTREF_BCR 59
|
||||
#define GCC_PNOC_BUS_TIMEOUT0_BCR 60
|
||||
#define GCC_PNOC_BUS_TIMEOUT1_BCR 61
|
||||
#define GCC_PNOC_BUS_TIMEOUT2_BCR 62
|
||||
#define GCC_PNOC_BUS_TIMEOUT3_BCR 63
|
||||
#define GCC_PNOC_BUS_TIMEOUT4_BCR 64
|
||||
#define GCC_CNOC_BUS_TIMEOUT0_BCR 65
|
||||
#define GCC_CNOC_BUS_TIMEOUT1_BCR 66
|
||||
#define GCC_CNOC_BUS_TIMEOUT2_BCR 67
|
||||
#define GCC_CNOC_BUS_TIMEOUT3_BCR 68
|
||||
#define GCC_CNOC_BUS_TIMEOUT4_BCR 69
|
||||
#define GCC_CNOC_BUS_TIMEOUT5_BCR 70
|
||||
#define GCC_CNOC_BUS_TIMEOUT6_BCR 71
|
||||
#define GCC_CNOC_BUS_TIMEOUT7_BCR 72
|
||||
#define GCC_CNOC_BUS_TIMEOUT8_BCR 73
|
||||
#define GCC_CNOC_BUS_TIMEOUT9_BCR 74
|
||||
#define GCC_CNOC_BUS_TIMEOUT_EXTREF_BCR 75
|
||||
#define GCC_APB2JTAG_BCR 76
|
||||
#define GCC_RBCPR_CX_BCR 77
|
||||
#define GCC_RBCPR_MX_BCR 78
|
||||
#define GCC_PCIE_0_BCR 79
|
||||
#define GCC_PCIE_0_PHY_BCR 80
|
||||
#define GCC_PCIE_1_BCR 81
|
||||
#define GCC_PCIE_1_PHY_BCR 82
|
||||
#define GCC_PCIE_2_BCR 83
|
||||
#define GCC_PCIE_2_PHY_BCR 84
|
||||
#define GCC_PCIE_PHY_BCR 85
|
||||
#define GCC_DCD_BCR 86
|
||||
#define GCC_OBT_ODT_BCR 87
|
||||
#define GCC_UFS_BCR 88
|
||||
#define GCC_SSC_BCR 89
|
||||
#define GCC_VS_BCR 90
|
||||
#define GCC_AGGRE0_NOC_BCR 91
|
||||
#define GCC_AGGRE1_NOC_BCR 92
|
||||
#define GCC_AGGRE2_NOC_BCR 93
|
||||
#define GCC_DCC_BCR 94
|
||||
#define GCC_IPA_BCR 95
|
||||
#define GCC_QSPI_BCR 96
|
||||
#define GCC_SKL_BCR 97
|
||||
#define GCC_MSMPU_BCR 98
|
||||
#define GCC_MSS_Q6_BCR 99
|
||||
#define GCC_QREFS_VBG_CAL_BCR 100
|
||||
|
||||
#endif
|
285
include/dt-bindings/clock/qcom,mmcc-msm8996.h
Normal file
285
include/dt-bindings/clock/qcom,mmcc-msm8996.h
Normal file
@ -0,0 +1,285 @@
|
||||
/*
|
||||
* Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_CLK_MSM_MMCC_8996_H
|
||||
#define _DT_BINDINGS_CLK_MSM_MMCC_8996_H
|
||||
|
||||
#define MMPLL0_EARLY 0
|
||||
#define MMPLL0_PLL 1
|
||||
#define MMPLL1_EARLY 2
|
||||
#define MMPLL1_PLL 3
|
||||
#define MMPLL2_EARLY 4
|
||||
#define MMPLL2_PLL 5
|
||||
#define MMPLL3_EARLY 6
|
||||
#define MMPLL3_PLL 7
|
||||
#define MMPLL4_EARLY 8
|
||||
#define MMPLL4_PLL 9
|
||||
#define MMPLL5_EARLY 10
|
||||
#define MMPLL5_PLL 11
|
||||
#define MMPLL8_EARLY 12
|
||||
#define MMPLL8_PLL 13
|
||||
#define MMPLL9_EARLY 14
|
||||
#define MMPLL9_PLL 15
|
||||
#define AHB_CLK_SRC 16
|
||||
#define AXI_CLK_SRC 17
|
||||
#define MAXI_CLK_SRC 18
|
||||
#define DSA_CORE_CLK_SRC 19
|
||||
#define GFX3D_CLK_SRC 20
|
||||
#define RBBMTIMER_CLK_SRC 21
|
||||
#define ISENSE_CLK_SRC 22
|
||||
#define RBCPR_CLK_SRC 23
|
||||
#define VIDEO_CORE_CLK_SRC 24
|
||||
#define VIDEO_SUBCORE0_CLK_SRC 25
|
||||
#define VIDEO_SUBCORE1_CLK_SRC 26
|
||||
#define PCLK0_CLK_SRC 27
|
||||
#define PCLK1_CLK_SRC 28
|
||||
#define MDP_CLK_SRC 29
|
||||
#define EXTPCLK_CLK_SRC 30
|
||||
#define VSYNC_CLK_SRC 31
|
||||
#define HDMI_CLK_SRC 32
|
||||
#define BYTE0_CLK_SRC 33
|
||||
#define BYTE1_CLK_SRC 34
|
||||
#define ESC0_CLK_SRC 35
|
||||
#define ESC1_CLK_SRC 36
|
||||
#define CAMSS_GP0_CLK_SRC 37
|
||||
#define CAMSS_GP1_CLK_SRC 38
|
||||
#define MCLK0_CLK_SRC 39
|
||||
#define MCLK1_CLK_SRC 40
|
||||
#define MCLK2_CLK_SRC 41
|
||||
#define MCLK3_CLK_SRC 42
|
||||
#define CCI_CLK_SRC 43
|
||||
#define CSI0PHYTIMER_CLK_SRC 44
|
||||
#define CSI1PHYTIMER_CLK_SRC 45
|
||||
#define CSI2PHYTIMER_CLK_SRC 46
|
||||
#define CSIPHY0_3P_CLK_SRC 47
|
||||
#define CSIPHY1_3P_CLK_SRC 48
|
||||
#define CSIPHY2_3P_CLK_SRC 49
|
||||
#define JPEG0_CLK_SRC 50
|
||||
#define JPEG2_CLK_SRC 51
|
||||
#define JPEG_DMA_CLK_SRC 52
|
||||
#define VFE0_CLK_SRC 53
|
||||
#define VFE1_CLK_SRC 54
|
||||
#define CPP_CLK_SRC 55
|
||||
#define CSI0_CLK_SRC 56
|
||||
#define CSI1_CLK_SRC 57
|
||||
#define CSI2_CLK_SRC 58
|
||||
#define CSI3_CLK_SRC 59
|
||||
#define FD_CORE_CLK_SRC 60
|
||||
#define MMSS_CXO_CLK 61
|
||||
#define MMSS_SLEEPCLK_CLK 62
|
||||
#define MMSS_MMAGIC_AHB_CLK 63
|
||||
#define MMSS_MMAGIC_CFG_AHB_CLK 64
|
||||
#define MMSS_MISC_AHB_CLK 65
|
||||
#define MMSS_MISC_CXO_CLK 66
|
||||
#define MMSS_BTO_AHB_CLK 67
|
||||
#define MMSS_MMAGIC_AXI_CLK 68
|
||||
#define MMSS_S0_AXI_CLK 69
|
||||
#define MMSS_MMAGIC_MAXI_CLK 70
|
||||
#define DSA_CORE_CLK 71
|
||||
#define DSA_NOC_CFG_AHB_CLK 72
|
||||
#define MMAGIC_CAMSS_AXI_CLK 73
|
||||
#define MMAGIC_CAMSS_NOC_CFG_AHB_CLK 74
|
||||
#define THROTTLE_CAMSS_CXO_CLK 75
|
||||
#define THROTTLE_CAMSS_AHB_CLK 76
|
||||
#define THROTTLE_CAMSS_AXI_CLK 77
|
||||
#define SMMU_VFE_AHB_CLK 78
|
||||
#define SMMU_VFE_AXI_CLK 79
|
||||
#define SMMU_CPP_AHB_CLK 80
|
||||
#define SMMU_CPP_AXI_CLK 81
|
||||
#define SMMU_JPEG_AHB_CLK 82
|
||||
#define SMMU_JPEG_AXI_CLK 83
|
||||
#define MMAGIC_MDSS_AXI_CLK 84
|
||||
#define MMAGIC_MDSS_NOC_CFG_AHB_CLK 85
|
||||
#define THROTTLE_MDSS_CXO_CLK 86
|
||||
#define THROTTLE_MDSS_AHB_CLK 87
|
||||
#define THROTTLE_MDSS_AXI_CLK 88
|
||||
#define SMMU_ROT_AHB_CLK 89
|
||||
#define SMMU_ROT_AXI_CLK 90
|
||||
#define SMMU_MDP_AHB_CLK 91
|
||||
#define SMMU_MDP_AXI_CLK 92
|
||||
#define MMAGIC_VIDEO_AXI_CLK 93
|
||||
#define MMAGIC_VIDEO_NOC_CFG_AHB_CLK 94
|
||||
#define THROTTLE_VIDEO_CXO_CLK 95
|
||||
#define THROTTLE_VIDEO_AHB_CLK 96
|
||||
#define THROTTLE_VIDEO_AXI_CLK 97
|
||||
#define SMMU_VIDEO_AHB_CLK 98
|
||||
#define SMMU_VIDEO_AXI_CLK 99
|
||||
#define MMAGIC_BIMC_AXI_CLK 100
|
||||
#define MMAGIC_BIMC_NOC_CFG_AHB_CLK 101
|
||||
#define GPU_GX_GFX3D_CLK 102
|
||||
#define GPU_GX_RBBMTIMER_CLK 103
|
||||
#define GPU_AHB_CLK 104
|
||||
#define GPU_AON_ISENSE_CLK 105
|
||||
#define VMEM_MAXI_CLK 106
|
||||
#define VMEM_AHB_CLK 107
|
||||
#define MMSS_RBCPR_CLK 108
|
||||
#define MMSS_RBCPR_AHB_CLK 109
|
||||
#define VIDEO_CORE_CLK 110
|
||||
#define VIDEO_AXI_CLK 111
|
||||
#define VIDEO_MAXI_CLK 112
|
||||
#define VIDEO_AHB_CLK 113
|
||||
#define VIDEO_SUBCORE0_CLK 114
|
||||
#define VIDEO_SUBCORE1_CLK 115
|
||||
#define MDSS_AHB_CLK 116
|
||||
#define MDSS_HDMI_AHB_CLK 117
|
||||
#define MDSS_AXI_CLK 118
|
||||
#define MDSS_PCLK0_CLK 119
|
||||
#define MDSS_PCLK1_CLK 120
|
||||
#define MDSS_MDP_CLK 121
|
||||
#define MDSS_EXTPCLK_CLK 122
|
||||
#define MDSS_VSYNC_CLK 123
|
||||
#define MDSS_HDMI_CLK 124
|
||||
#define MDSS_BYTE0_CLK 125
|
||||
#define MDSS_BYTE1_CLK 126
|
||||
#define MDSS_ESC0_CLK 127
|
||||
#define MDSS_ESC1_CLK 128
|
||||
#define CAMSS_TOP_AHB_CLK 129
|
||||
#define CAMSS_AHB_CLK 130
|
||||
#define CAMSS_MICRO_AHB_CLK 131
|
||||
#define CAMSS_GP0_CLK 132
|
||||
#define CAMSS_GP1_CLK 133
|
||||
#define CAMSS_MCLK0_CLK 134
|
||||
#define CAMSS_MCLK1_CLK 135
|
||||
#define CAMSS_MCLK2_CLK 136
|
||||
#define CAMSS_MCLK3_CLK 137
|
||||
#define CAMSS_CCI_CLK 138
|
||||
#define CAMSS_CCI_AHB_CLK 139
|
||||
#define CAMSS_CSI0PHYTIMER_CLK 140
|
||||
#define CAMSS_CSI1PHYTIMER_CLK 141
|
||||
#define CAMSS_CSI2PHYTIMER_CLK 142
|
||||
#define CAMSS_CSIPHY0_3P_CLK 143
|
||||
#define CAMSS_CSIPHY1_3P_CLK 144
|
||||
#define CAMSS_CSIPHY2_3P_CLK 145
|
||||
#define CAMSS_JPEG0_CLK 146
|
||||
#define CAMSS_JPEG2_CLK 147
|
||||
#define CAMSS_JPEG_DMA_CLK 148
|
||||
#define CAMSS_JPEG_AHB_CLK 149
|
||||
#define CAMSS_JPEG_AXI_CLK 150
|
||||
#define CAMSS_VFE_AHB_CLK 151
|
||||
#define CAMSS_VFE_AXI_CLK 152
|
||||
#define CAMSS_VFE0_CLK 153
|
||||
#define CAMSS_VFE0_STREAM_CLK 154
|
||||
#define CAMSS_VFE0_AHB_CLK 155
|
||||
#define CAMSS_VFE1_CLK 156
|
||||
#define CAMSS_VFE1_STREAM_CLK 157
|
||||
#define CAMSS_VFE1_AHB_CLK 158
|
||||
#define CAMSS_CSI_VFE0_CLK 159
|
||||
#define CAMSS_CSI_VFE1_CLK 160
|
||||
#define CAMSS_CPP_VBIF_AHB_CLK 161
|
||||
#define CAMSS_CPP_AXI_CLK 162
|
||||
#define CAMSS_CPP_CLK 163
|
||||
#define CAMSS_CPP_AHB_CLK 164
|
||||
#define CAMSS_CSI0_CLK 165
|
||||
#define CAMSS_CSI0_AHB_CLK 166
|
||||
#define CAMSS_CSI0PHY_CLK 167
|
||||
#define CAMSS_CSI0RDI_CLK 168
|
||||
#define CAMSS_CSI0PIX_CLK 169
|
||||
#define CAMSS_CSI1_CLK 170
|
||||
#define CAMSS_CSI1_AHB_CLK 171
|
||||
#define CAMSS_CSI1PHY_CLK 172
|
||||
#define CAMSS_CSI1RDI_CLK 173
|
||||
#define CAMSS_CSI1PIX_CLK 174
|
||||
#define CAMSS_CSI2_CLK 175
|
||||
#define CAMSS_CSI2_AHB_CLK 176
|
||||
#define CAMSS_CSI2PHY_CLK 177
|
||||
#define CAMSS_CSI2RDI_CLK 178
|
||||
#define CAMSS_CSI2PIX_CLK 179
|
||||
#define CAMSS_CSI3_CLK 180
|
||||
#define CAMSS_CSI3_AHB_CLK 181
|
||||
#define CAMSS_CSI3PHY_CLK 182
|
||||
#define CAMSS_CSI3RDI_CLK 183
|
||||
#define CAMSS_CSI3PIX_CLK 184
|
||||
#define CAMSS_ISPIF_AHB_CLK 185
|
||||
#define FD_CORE_CLK 186
|
||||
#define FD_CORE_UAR_CLK 187
|
||||
#define FD_AHB_CLK 188
|
||||
#define MMSS_SPDM_CSI0_CLK 189
|
||||
#define MMSS_SPDM_JPEG_DMA_CLK 190
|
||||
#define MMSS_SPDM_CPP_CLK 191
|
||||
#define MMSS_SPDM_PCLK0_CLK 192
|
||||
#define MMSS_SPDM_AHB_CLK 193
|
||||
#define MMSS_SPDM_GFX3D_CLK 194
|
||||
#define MMSS_SPDM_PCLK1_CLK 195
|
||||
#define MMSS_SPDM_JPEG2_CLK 196
|
||||
#define MMSS_SPDM_DEBUG_CLK 197
|
||||
#define MMSS_SPDM_VFE1_CLK 198
|
||||
#define MMSS_SPDM_VFE0_CLK 199
|
||||
#define MMSS_SPDM_VIDEO_CORE_CLK 200
|
||||
#define MMSS_SPDM_AXI_CLK 201
|
||||
#define MMSS_SPDM_MDP_CLK 202
|
||||
#define MMSS_SPDM_JPEG0_CLK 203
|
||||
#define MMSS_SPDM_RM_AXI_CLK 204
|
||||
#define MMSS_SPDM_RM_MAXI_CLK 205
|
||||
|
||||
#define MMAGICAHB_BCR 0
|
||||
#define MMAGIC_CFG_BCR 1
|
||||
#define MISC_BCR 2
|
||||
#define BTO_BCR 3
|
||||
#define MMAGICAXI_BCR 4
|
||||
#define MMAGICMAXI_BCR 5
|
||||
#define DSA_BCR 6
|
||||
#define MMAGIC_CAMSS_BCR 7
|
||||
#define THROTTLE_CAMSS_BCR 8
|
||||
#define SMMU_VFE_BCR 9
|
||||
#define SMMU_CPP_BCR 10
|
||||
#define SMMU_JPEG_BCR 11
|
||||
#define MMAGIC_MDSS_BCR 12
|
||||
#define THROTTLE_MDSS_BCR 13
|
||||
#define SMMU_ROT_BCR 14
|
||||
#define SMMU_MDP_BCR 15
|
||||
#define MMAGIC_VIDEO_BCR 16
|
||||
#define THROTTLE_VIDEO_BCR 17
|
||||
#define SMMU_VIDEO_BCR 18
|
||||
#define MMAGIC_BIMC_BCR 19
|
||||
#define GPU_GX_BCR 20
|
||||
#define GPU_BCR 21
|
||||
#define GPU_AON_BCR 22
|
||||
#define VMEM_BCR 23
|
||||
#define MMSS_RBCPR_BCR 24
|
||||
#define VIDEO_BCR 25
|
||||
#define MDSS_BCR 26
|
||||
#define CAMSS_TOP_BCR 27
|
||||
#define CAMSS_AHB_BCR 28
|
||||
#define CAMSS_MICRO_BCR 29
|
||||
#define CAMSS_CCI_BCR 30
|
||||
#define CAMSS_PHY0_BCR 31
|
||||
#define CAMSS_PHY1_BCR 32
|
||||
#define CAMSS_PHY2_BCR 33
|
||||
#define CAMSS_CSIPHY0_3P_BCR 34
|
||||
#define CAMSS_CSIPHY1_3P_BCR 35
|
||||
#define CAMSS_CSIPHY2_3P_BCR 36
|
||||
#define CAMSS_JPEG_BCR 37
|
||||
#define CAMSS_VFE_BCR 38
|
||||
#define CAMSS_VFE0_BCR 39
|
||||
#define CAMSS_VFE1_BCR 40
|
||||
#define CAMSS_CSI_VFE0_BCR 41
|
||||
#define CAMSS_CSI_VFE1_BCR 42
|
||||
#define CAMSS_CPP_TOP_BCR 43
|
||||
#define CAMSS_CPP_BCR 44
|
||||
#define CAMSS_CSI0_BCR 45
|
||||
#define CAMSS_CSI0RDI_BCR 46
|
||||
#define CAMSS_CSI0PIX_BCR 47
|
||||
#define CAMSS_CSI1_BCR 48
|
||||
#define CAMSS_CSI1RDI_BCR 49
|
||||
#define CAMSS_CSI1PIX_BCR 50
|
||||
#define CAMSS_CSI2_BCR 51
|
||||
#define CAMSS_CSI2RDI_BCR 52
|
||||
#define CAMSS_CSI2PIX_BCR 53
|
||||
#define CAMSS_CSI3_BCR 54
|
||||
#define CAMSS_CSI3RDI_BCR 55
|
||||
#define CAMSS_CSI3PIX_BCR 56
|
||||
#define CAMSS_ISPIF_BCR 57
|
||||
#define FD_BCR 58
|
||||
#define MMSS_SPDM_RM_BCR 59
|
||||
|
||||
#endif
|
193
include/dt-bindings/clock/rk3036-cru.h
Normal file
193
include/dt-bindings/clock/rk3036-cru.h
Normal file
@ -0,0 +1,193 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Rockchip Electronics Co. Ltd.
|
||||
* Author: Xing Zheng <zhengxing@rock-chips.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3036_H
|
||||
#define _DT_BINDINGS_CLK_ROCKCHIP_RK3036_H
|
||||
|
||||
/* core clocks */
|
||||
#define PLL_APLL 1
|
||||
#define PLL_DPLL 2
|
||||
#define PLL_GPLL 3
|
||||
#define ARMCLK 4
|
||||
|
||||
/* sclk gates (special clocks) */
|
||||
#define SCLK_GPU 64
|
||||
#define SCLK_SPI 65
|
||||
#define SCLK_SDMMC 68
|
||||
#define SCLK_SDIO 69
|
||||
#define SCLK_EMMC 71
|
||||
#define SCLK_NANDC 76
|
||||
#define SCLK_UART0 77
|
||||
#define SCLK_UART1 78
|
||||
#define SCLK_UART2 79
|
||||
#define SCLK_I2S 82
|
||||
#define SCLK_SPDIF 83
|
||||
#define SCLK_TIMER0 85
|
||||
#define SCLK_TIMER1 86
|
||||
#define SCLK_TIMER2 87
|
||||
#define SCLK_TIMER3 88
|
||||
#define SCLK_OTGPHY0 93
|
||||
#define SCLK_LCDC 100
|
||||
#define SCLK_HDMI 109
|
||||
#define SCLK_HEVC 111
|
||||
#define SCLK_I2S_OUT 113
|
||||
#define SCLK_SDMMC_DRV 114
|
||||
#define SCLK_SDIO_DRV 115
|
||||
#define SCLK_EMMC_DRV 117
|
||||
#define SCLK_SDMMC_SAMPLE 118
|
||||
#define SCLK_SDIO_SAMPLE 119
|
||||
#define SCLK_EMMC_SAMPLE 121
|
||||
#define SCLK_PVTM_CORE 123
|
||||
#define SCLK_PVTM_GPU 124
|
||||
#define SCLK_PVTM_VIDEO 125
|
||||
#define SCLK_MAC 151
|
||||
#define SCLK_MACREF 152
|
||||
#define SCLK_SFC 160
|
||||
|
||||
/* aclk gates */
|
||||
#define ACLK_DMAC2 194
|
||||
#define ACLK_LCDC 197
|
||||
#define ACLK_VIO 203
|
||||
#define ACLK_VCODEC 208
|
||||
#define ACLK_CPU 209
|
||||
#define ACLK_PERI 210
|
||||
|
||||
/* pclk gates */
|
||||
#define PCLK_GPIO0 320
|
||||
#define PCLK_GPIO1 321
|
||||
#define PCLK_GPIO2 322
|
||||
#define PCLK_GRF 329
|
||||
#define PCLK_I2C0 332
|
||||
#define PCLK_I2C1 333
|
||||
#define PCLK_I2C2 334
|
||||
#define PCLK_SPI 338
|
||||
#define PCLK_UART0 341
|
||||
#define PCLK_UART1 342
|
||||
#define PCLK_UART2 343
|
||||
#define PCLK_PWM 350
|
||||
#define PCLK_TIMER 353
|
||||
#define PCLK_HDMI 360
|
||||
#define PCLK_CPU 362
|
||||
#define PCLK_PERI 363
|
||||
#define PCLK_DDRUPCTL 364
|
||||
#define PCLK_WDT 368
|
||||
#define PCLK_ACODEC 369
|
||||
|
||||
/* hclk gates */
|
||||
#define HCLK_OTG0 449
|
||||
#define HCLK_OTG1 450
|
||||
#define HCLK_NANDC 453
|
||||
#define HCLK_SDMMC 456
|
||||
#define HCLK_SDIO 457
|
||||
#define HCLK_EMMC 459
|
||||
#define HCLK_I2S 462
|
||||
#define HCLK_LCDC 465
|
||||
#define HCLK_ROM 467
|
||||
#define HCLK_VIO_BUS 472
|
||||
#define HCLK_VCODEC 476
|
||||
#define HCLK_CPU 477
|
||||
#define HCLK_PERI 478
|
||||
|
||||
#define CLK_NR_CLKS (HCLK_PERI + 1)
|
||||
|
||||
/* soft-reset indices */
|
||||
#define SRST_CORE0 0
|
||||
#define SRST_CORE1 1
|
||||
#define SRST_CORE0_DBG 4
|
||||
#define SRST_CORE1_DBG 5
|
||||
#define SRST_CORE0_POR 8
|
||||
#define SRST_CORE1_POR 9
|
||||
#define SRST_L2C 12
|
||||
#define SRST_TOPDBG 13
|
||||
#define SRST_STRC_SYS_A 14
|
||||
#define SRST_PD_CORE_NIU 15
|
||||
|
||||
#define SRST_TIMER2 16
|
||||
#define SRST_CPUSYS_H 17
|
||||
#define SRST_AHB2APB_H 19
|
||||
#define SRST_TIMER3 20
|
||||
#define SRST_INTMEM 21
|
||||
#define SRST_ROM 22
|
||||
#define SRST_PERI_NIU 23
|
||||
#define SRST_I2S 24
|
||||
#define SRST_DDR_PLL 25
|
||||
#define SRST_GPU_DLL 26
|
||||
#define SRST_TIMER0 27
|
||||
#define SRST_TIMER1 28
|
||||
#define SRST_CORE_DLL 29
|
||||
#define SRST_EFUSE_P 30
|
||||
#define SRST_ACODEC_P 31
|
||||
|
||||
#define SRST_GPIO0 32
|
||||
#define SRST_GPIO1 33
|
||||
#define SRST_GPIO2 34
|
||||
#define SRST_UART0 39
|
||||
#define SRST_UART1 40
|
||||
#define SRST_UART2 41
|
||||
#define SRST_I2C0 43
|
||||
#define SRST_I2C1 44
|
||||
#define SRST_I2C2 45
|
||||
#define SRST_SFC 47
|
||||
|
||||
#define SRST_PWM0 48
|
||||
#define SRST_DAP 51
|
||||
#define SRST_DAP_SYS 52
|
||||
#define SRST_GRF 55
|
||||
#define SRST_PERIPHSYS_A 57
|
||||
#define SRST_PERIPHSYS_H 58
|
||||
#define SRST_PERIPHSYS_P 59
|
||||
#define SRST_CPU_PERI 61
|
||||
#define SRST_EMEM_PERI 62
|
||||
#define SRST_USB_PERI 63
|
||||
|
||||
#define SRST_DMA2 64
|
||||
#define SRST_MAC 66
|
||||
#define SRST_NANDC 68
|
||||
#define SRST_USBOTG0 69
|
||||
#define SRST_OTGC0 71
|
||||
#define SRST_USBOTG1 72
|
||||
#define SRST_OTGC1 74
|
||||
#define SRST_DDRMSCH 79
|
||||
|
||||
#define SRST_MMC0 81
|
||||
#define SRST_SDIO 82
|
||||
#define SRST_EMMC 83
|
||||
#define SRST_SPI0 84
|
||||
#define SRST_WDT 86
|
||||
#define SRST_DDRPHY 88
|
||||
#define SRST_DDRPHY_P 89
|
||||
#define SRST_DDRCTRL 90
|
||||
#define SRST_DDRCTRL_P 91
|
||||
|
||||
#define SRST_HDMI_P 96
|
||||
#define SRST_VIO_BUS_H 99
|
||||
#define SRST_UTMI0 103
|
||||
#define SRST_UTMI1 104
|
||||
#define SRST_USBPOR 105
|
||||
|
||||
#define SRST_VCODEC_A 112
|
||||
#define SRST_VCODEC_H 113
|
||||
#define SRST_VIO1_A 114
|
||||
#define SRST_HEVC 115
|
||||
#define SRST_VCODEC_NIU_A 116
|
||||
#define SRST_LCDC1_A 117
|
||||
#define SRST_LCDC1_H 118
|
||||
#define SRST_LCDC1_D 119
|
||||
#define SRST_GPU 120
|
||||
#define SRST_GPU_NIU_A 122
|
||||
|
||||
#define SRST_DBG_P 131
|
||||
|
||||
#endif
|
220
include/dt-bindings/clock/rk3228-cru.h
Normal file
220
include/dt-bindings/clock/rk3228-cru.h
Normal file
@ -0,0 +1,220 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Rockchip Electronics Co. Ltd.
|
||||
* Author: Jeffy Chen <jeffy.chen@rock-chips.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3228_H
|
||||
#define _DT_BINDINGS_CLK_ROCKCHIP_RK3228_H
|
||||
|
||||
/* core clocks */
|
||||
#define PLL_APLL 1
|
||||
#define PLL_DPLL 2
|
||||
#define PLL_CPLL 3
|
||||
#define PLL_GPLL 4
|
||||
#define ARMCLK 5
|
||||
|
||||
/* sclk gates (special clocks) */
|
||||
#define SCLK_SPI0 65
|
||||
#define SCLK_NANDC 67
|
||||
#define SCLK_SDMMC 68
|
||||
#define SCLK_SDIO 69
|
||||
#define SCLK_EMMC 71
|
||||
#define SCLK_UART0 77
|
||||
#define SCLK_UART1 78
|
||||
#define SCLK_UART2 79
|
||||
#define SCLK_I2S0 80
|
||||
#define SCLK_I2S1 81
|
||||
#define SCLK_I2S2 82
|
||||
#define SCLK_SPDIF 83
|
||||
#define SCLK_TIMER0 85
|
||||
#define SCLK_TIMER1 86
|
||||
#define SCLK_TIMER2 87
|
||||
#define SCLK_TIMER3 88
|
||||
#define SCLK_TIMER4 89
|
||||
#define SCLK_TIMER5 90
|
||||
#define SCLK_I2S_OUT 113
|
||||
#define SCLK_SDMMC_DRV 114
|
||||
#define SCLK_SDIO_DRV 115
|
||||
#define SCLK_EMMC_DRV 117
|
||||
#define SCLK_SDMMC_SAMPLE 118
|
||||
#define SCLK_SDIO_SAMPLE 119
|
||||
#define SCLK_EMMC_SAMPLE 121
|
||||
|
||||
/* aclk gates */
|
||||
#define ACLK_DMAC 194
|
||||
#define ACLK_PERI 210
|
||||
|
||||
/* pclk gates */
|
||||
#define PCLK_GPIO0 320
|
||||
#define PCLK_GPIO1 321
|
||||
#define PCLK_GPIO2 322
|
||||
#define PCLK_GPIO3 323
|
||||
#define PCLK_GRF 329
|
||||
#define PCLK_I2C0 332
|
||||
#define PCLK_I2C1 333
|
||||
#define PCLK_I2C2 334
|
||||
#define PCLK_I2C3 335
|
||||
#define PCLK_SPI0 338
|
||||
#define PCLK_UART0 341
|
||||
#define PCLK_UART1 342
|
||||
#define PCLK_UART2 343
|
||||
#define PCLK_PWM 350
|
||||
#define PCLK_TIMER 353
|
||||
#define PCLK_PERI 363
|
||||
|
||||
/* hclk gates */
|
||||
#define HCLK_NANDC 453
|
||||
#define HCLK_SDMMC 456
|
||||
#define HCLK_SDIO 457
|
||||
#define HCLK_EMMC 459
|
||||
#define HCLK_PERI 478
|
||||
|
||||
#define CLK_NR_CLKS (HCLK_PERI + 1)
|
||||
|
||||
/* soft-reset indices */
|
||||
#define SRST_CORE0_PO 0
|
||||
#define SRST_CORE1_PO 1
|
||||
#define SRST_CORE2_PO 2
|
||||
#define SRST_CORE3_PO 3
|
||||
#define SRST_CORE0 4
|
||||
#define SRST_CORE1 5
|
||||
#define SRST_CORE2 6
|
||||
#define SRST_CORE3 7
|
||||
#define SRST_CORE0_DBG 8
|
||||
#define SRST_CORE1_DBG 9
|
||||
#define SRST_CORE2_DBG 10
|
||||
#define SRST_CORE3_DBG 11
|
||||
#define SRST_TOPDBG 12
|
||||
#define SRST_ACLK_CORE 13
|
||||
#define SRST_NOC 14
|
||||
#define SRST_L2C 15
|
||||
|
||||
#define SRST_CPUSYS_H 18
|
||||
#define SRST_BUSSYS_H 19
|
||||
#define SRST_SPDIF 20
|
||||
#define SRST_INTMEM 21
|
||||
#define SRST_ROM 22
|
||||
#define SRST_OTG_ADP 23
|
||||
#define SRST_I2S0 24
|
||||
#define SRST_I2S1 25
|
||||
#define SRST_I2S2 26
|
||||
#define SRST_ACODEC_P 27
|
||||
#define SRST_DFIMON 28
|
||||
#define SRST_MSCH 29
|
||||
#define SRST_EFUSE1024 30
|
||||
#define SRST_EFUSE256 31
|
||||
|
||||
#define SRST_GPIO0 32
|
||||
#define SRST_GPIO1 33
|
||||
#define SRST_GPIO2 34
|
||||
#define SRST_GPIO3 35
|
||||
#define SRST_PERIPH_NOC_A 36
|
||||
#define SRST_PERIPH_NOC_BUS_H 37
|
||||
#define SRST_PERIPH_NOC_P 38
|
||||
#define SRST_UART0 39
|
||||
#define SRST_UART1 40
|
||||
#define SRST_UART2 41
|
||||
#define SRST_PHYNOC 42
|
||||
#define SRST_I2C0 43
|
||||
#define SRST_I2C1 44
|
||||
#define SRST_I2C2 45
|
||||
#define SRST_I2C3 46
|
||||
|
||||
#define SRST_PWM 48
|
||||
#define SRST_A53_GIC 49
|
||||
#define SRST_DAP 51
|
||||
#define SRST_DAP_NOC 52
|
||||
#define SRST_CRYPTO 53
|
||||
#define SRST_SGRF 54
|
||||
#define SRST_GRF 55
|
||||
#define SRST_GMAC 56
|
||||
#define SRST_PERIPH_NOC_H 58
|
||||
#define SRST_MACPHY 63
|
||||
|
||||
#define SRST_DMA 64
|
||||
#define SRST_NANDC 68
|
||||
#define SRST_USBOTG 69
|
||||
#define SRST_OTGC 70
|
||||
#define SRST_USBHOST0 71
|
||||
#define SRST_HOST_CTRL0 72
|
||||
#define SRST_USBHOST1 73
|
||||
#define SRST_HOST_CTRL1 74
|
||||
#define SRST_USBHOST2 75
|
||||
#define SRST_HOST_CTRL2 76
|
||||
#define SRST_USBPOR0 77
|
||||
#define SRST_USBPOR1 78
|
||||
#define SRST_DDRMSCH 79
|
||||
|
||||
#define SRST_SMART_CARD 80
|
||||
#define SRST_SDMMC 81
|
||||
#define SRST_SDIO 82
|
||||
#define SRST_EMMC 83
|
||||
#define SRST_SPI 84
|
||||
#define SRST_TSP_H 85
|
||||
#define SRST_TSP 86
|
||||
#define SRST_TSADC 87
|
||||
#define SRST_DDRPHY 88
|
||||
#define SRST_DDRPHY_P 89
|
||||
#define SRST_DDRCTRL 90
|
||||
#define SRST_DDRCTRL_P 91
|
||||
#define SRST_HOST0_ECHI 92
|
||||
#define SRST_HOST1_ECHI 93
|
||||
#define SRST_HOST2_ECHI 94
|
||||
#define SRST_VOP_NOC_A 95
|
||||
|
||||
#define SRST_HDMI_P 96
|
||||
#define SRST_VIO_ARBI_H 97
|
||||
#define SRST_IEP_NOC_A 98
|
||||
#define SRST_VIO_NOC_H 99
|
||||
#define SRST_VOP_A 100
|
||||
#define SRST_VOP_H 101
|
||||
#define SRST_VOP_D 102
|
||||
#define SRST_UTMI0 103
|
||||
#define SRST_UTMI1 104
|
||||
#define SRST_UTMI2 105
|
||||
#define SRST_UTMI3 106
|
||||
#define SRST_RGA 107
|
||||
#define SRST_RGA_NOC_A 108
|
||||
#define SRST_RGA_A 109
|
||||
#define SRST_RGA_H 110
|
||||
#define SRST_HDCP_A 111
|
||||
|
||||
#define SRST_VPU_A 112
|
||||
#define SRST_VPU_H 113
|
||||
#define SRST_VPU_NOC_A 116
|
||||
#define SRST_VPU_NOC_H 117
|
||||
#define SRST_RKVDEC_A 118
|
||||
#define SRST_RKVDEC_NOC_A 119
|
||||
#define SRST_RKVDEC_H 120
|
||||
#define SRST_RKVDEC_NOC_H 121
|
||||
#define SRST_RKVDEC_CORE 122
|
||||
#define SRST_RKVDEC_CABAC 123
|
||||
#define SRST_IEP_A 124
|
||||
#define SRST_IEP_H 125
|
||||
#define SRST_GPU_A 126
|
||||
#define SRST_GPU_NOC_A 127
|
||||
|
||||
#define SRST_CORE_DBG 128
|
||||
#define SRST_DBG_P 129
|
||||
#define SRST_TIMER0 130
|
||||
#define SRST_TIMER1 131
|
||||
#define SRST_TIMER2 132
|
||||
#define SRST_TIMER3 133
|
||||
#define SRST_TIMER4 134
|
||||
#define SRST_TIMER5 135
|
||||
#define SRST_VIO_H2P 136
|
||||
#define SRST_HDMIPHY 139
|
||||
#define SRST_VDAC 140
|
||||
#define SRST_TIMER_6CH_P 141
|
||||
|
||||
#endif
|
@ -86,6 +86,8 @@
|
||||
#define SCLK_USBPHY480M_SRC 122
|
||||
#define SCLK_PVTM_CORE 123
|
||||
#define SCLK_PVTM_GPU 124
|
||||
#define SCLK_CRYPTO 125
|
||||
#define SCLK_MIPIDSI_24M 126
|
||||
|
||||
#define SCLK_MAC 151
|
||||
#define SCLK_MACREF_OUT 152
|
||||
@ -164,6 +166,8 @@
|
||||
#define PCLK_DDRUPCTL1 366
|
||||
#define PCLK_PUBL1 367
|
||||
#define PCLK_WDT 368
|
||||
#define PCLK_EFUSE256 369
|
||||
#define PCLK_EFUSE1024 370
|
||||
|
||||
/* hclk gates */
|
||||
#define HCLK_GPS 448
|
||||
|
@ -44,7 +44,7 @@ struct dentry;
|
||||
* @rate: Requested clock rate. This field will be adjusted by
|
||||
* clock drivers according to hardware capabilities.
|
||||
* @min_rate: Minimum rate imposed by clk users.
|
||||
* @max_rate: Maximum rate a imposed by clk users.
|
||||
* @max_rate: Maximum rate imposed by clk users.
|
||||
* @best_parent_rate: The best parent rate a parent can provide to fulfill the
|
||||
* requested constraints.
|
||||
* @best_parent_hw: The most appropriate parent clock that fulfills the
|
||||
@ -715,8 +715,7 @@ static inline int of_clk_add_provider(struct device_node *np,
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#define of_clk_del_provider(np) \
|
||||
{ while (0); }
|
||||
static inline void of_clk_del_provider(struct device_node *np) {}
|
||||
static inline struct clk *of_clk_src_simple_get(
|
||||
struct of_phandle_args *clkspec, void *data)
|
||||
{
|
||||
@ -741,8 +740,7 @@ static inline const char *of_clk_get_parent_name(struct device_node *np,
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#define of_clk_init(matches) \
|
||||
{ while (0); }
|
||||
static inline void of_clk_init(const struct of_device_id *matches) {}
|
||||
#endif /* CONFIG_OF */
|
||||
|
||||
/*
|
||||
|
@ -286,6 +286,7 @@ struct ti_clk_features {
|
||||
#define TI_CLK_DPLL_HAS_FREQSEL BIT(0)
|
||||
#define TI_CLK_DPLL4_DENY_REPROGRAM BIT(1)
|
||||
#define TI_CLK_DISABLE_CLKDM_CONTROL BIT(2)
|
||||
#define TI_CLK_ERRATA_I810 BIT(3)
|
||||
|
||||
void ti_clk_setup_features(struct ti_clk_features *features);
|
||||
const struct ti_clk_features *ti_clk_get_features(void);
|
||||
|
Loading…
Reference in New Issue
Block a user