Add support for MSM's mmio clock/reset controller
Subsystems (6)
v4 cover Add support for MSM's mmio clock/reset controller
The first breaks a reset-controller include ordering requirement. I hope it can go through the clock tree.
The next 3 patches are generic clock framework patches. They add support for regmap and for setting the rate and the parent at the same time based on patches from James Hogan's remuxing set_rate series.
After that we add MSM clock hardware support and SoC specific drivers. The DT node additions will be sent through the MSM maintainers once these patches are accepted.
Changes since v3:
* Moved binding include to clock/
* New patch for 8660 GCC driver
* Renamed directory to qcom to match vendor prefix
* Added some missing clocks in 8974 GCC driver
* New patch for 8974 MMCC driver
Changes since v2:
* Completed 8960 and 8974 GCC data & dt-bindings
* Added support for reset controllers
* Squashed some bugs in 8974 gcc clocks
* New patch to fix clk NULL pointer deref
* New patch to fix #include requirement for reset-controller.h
Changes since v1:
* Rewrote binding to use #clock-cells=1
* Reworked library components (pll, rcg, branch) to use regmap
* Dropped common clock framework patches that did DT parsing
* New patches for regmap support in common clock framework
Stephen Boyd (15):
reset: Silence warning in reset-controller.h
clk: Allow drivers to pass in a regmap
clk: Add regmap core helpers for enable/disable/is_enabled
clk: Add set_rate_and_parent() op
clk: qcom: Add support for phase locked loops (PLLs)
clk: qcom: Add support for root clock generators (RCGs)
clk: qcom: Add support for branches/gate clocks
clk: qcom: Add reset controller support
clk: qcom: Add support for MSM8960's global clock controller (GCC)
clk: qcom: Add support for MSM8960's multimedia clock controller
(MMCC)
clk: qcom: Add support for MSM8974's global clock controller (GCC)
clk: qcom: Add support for MSM8974's multimedia clock controller
(MMCC) clk: qcom: Add support for MSM8660's global clock controller (GCC)
devicetree: bindings: Document qcom,gcc
devicetree: bindings: Document qcom,mmcc
Documentation/clk.txt | 3 + .../devicetree/bindings/clock/qcom,gcc.txt | 21 + .../devicetree/bindings/clock/qcom,mmcc.txt | 21 + drivers/clk/Kconfig | 2 + drivers/clk/Makefile | 1 + drivers/clk/clk.c | 156 +- drivers/clk/qcom/Kconfig | 47 + drivers/clk/qcom/Makefile | 13 + drivers/clk/qcom/clk-branch.c | 159 ++ drivers/clk/qcom/clk-branch.h | 53 + drivers/clk/qcom/clk-pll.c | 222 ++ drivers/clk/qcom/clk-pll.h | 65 + drivers/clk/qcom/clk-rcg.c | 517 ++++ drivers/clk/qcom/clk-rcg.h | 157 + drivers/clk/qcom/clk-rcg2.c | 291 ++ drivers/clk/qcom/gcc-msm8660.c | 2818 ++++++++++++++++++ drivers/clk/qcom/gcc-msm8960.c | 2992 ++++++++++++++++++++ drivers/clk/qcom/gcc-msm8974.c | 2693 ++++++++++++++++++ drivers/clk/qcom/mmcc-msm8960.c | 2320 +++++++++++++++ drivers/clk/qcom/mmcc-msm8974.c | 2624 +++++++++++++++++ drivers/clk/qcom/reset.c | 63 + drivers/clk/qcom/reset.h | 37 + include/dt-bindings/clock/qcom,gcc-msm8660.h | 276 ++ include/dt-bindings/clock/qcom,gcc-msm8960.h | 313 ++ include/dt-bindings/clock/qcom,gcc-msm8974.h | 320 +++ include/dt-bindings/clock/qcom,mmcc-msm8960.h | 137 + include/dt-bindings/clock/qcom,mmcc-msm8974.h | 161 ++ include/dt-bindings/reset/qcom,gcc-msm8660.h | 134 + include/dt-bindings/reset/qcom,gcc-msm8960.h | 118 + include/dt-bindings/reset/qcom,gcc-msm8974.h | 96 + include/dt-bindings/reset/qcom,mmcc-msm8960.h | 93 + include/dt-bindings/reset/qcom,mmcc-msm8974.h | 62 + include/linux/clk-provider.h | 35 + include/linux/reset-controller.h | 1 + 34 files changed, 17002 insertions(+), 19 deletions(-) create mode 100644 Documentation/devicetree/bindings/clock/qcom,gcc.txt create mode 100644 Documentation/devicetree/bindings/clock/qcom,mmcc.txt create mode 100644 drivers/clk/qcom/Kconfig create mode 100644 drivers/clk/qcom/Makefile create mode 100644 drivers/clk/qcom/clk-branch.c create mode 100644 drivers/clk/qcom/clk-branch.h create mode 100644 drivers/clk/qcom/clk-pll.c create mode 100644 drivers/clk/qcom/clk-pll.h create mode 100644 drivers/clk/qcom/clk-rcg.c create mode 100644 drivers/clk/qcom/clk-rcg.h create mode 100644 drivers/clk/qcom/clk-rcg2.c create mode 100644 drivers/clk/qcom/gcc-msm8660.c create mode 100644 drivers/clk/qcom/gcc-msm8960.c create mode 100644 drivers/clk/qcom/gcc-msm8974.c create mode 100644 drivers/clk/qcom/mmcc-msm8960.c create mode 100644 drivers/clk/qcom/mmcc-msm8974.c create mode 100644 drivers/clk/qcom/reset.c create mode 100644 drivers/clk/qcom/reset.h create mode 100644 include/dt-bindings/clock/qcom,gcc-msm8660.h create mode 100644 include/dt-bindings/clock/qcom,gcc-msm8960.h create mode 100644 include/dt-bindings/clock/qcom,gcc-msm8974.h create mode 100644 include/dt-bindings/clock/qcom,mmcc-msm8960.h create mode 100644 include/dt-bindings/clock/qcom,mmcc-msm8974.h create mode 100644 include/dt-bindings/reset/qcom,gcc-msm8660.h create mode 100644 include/dt-bindings/reset/qcom,gcc-msm8960.h create mode 100644 include/dt-bindings/reset/qcom,gcc-msm8974.h create mode 100644 include/dt-bindings/reset/qcom,mmcc-msm8960.h create mode 100644 include/dt-bindings/reset/qcom,mmcc-msm8974.h
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
PATCH v4 1/15 reset: Silence warning in reset-controller.h
If a user of <linux/reset-controller.h> doesn't include <linux/of.h> before including reset-controller.h they'll get a warning as follows:
include/linux/reset-controller.h:44:17:
warning: 'struct of_phandle_args' declared inside parameter list
This is because of_phandle_args is not forward declared. Add the declaration to silence this warning.
--- include/linux/reset-controller.h | 1 + 1 file changed, 1 insertion(+)
include/linux/reset-controller.h +1 -0
@@ -21,6 +21,7 @@ struct reset_control_ops {struct module ;struct device_node ; +struct of_phandle_args ;/** * struct reset_controller_dev - reset controller entity that might
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
Re: [PATCH v4 01/15] reset: Silence warning in reset-controller.h
Am Montag, den 23.12.2013, 17:12 -0800 schrieb Stephen Boyd:
Quoted 21 lines
If a user of <
linux/reset-controller.h> doesn't include <linux/of.h> before includingreset-controller.hthey'll get a warning as follows:
include/linux/reset-controller.h:44:17:
warning: 'structof_phandle_args' declared inside parameter listThis is because
of_phandle_argsis not forward declared. Add the declaration to silence this warning.Cc Philipp Zabel <[email protected]>Signed-off-by Stephen Boyd <[email protected]>--- include/linux/reset-controller.h | 1 + 1 file changed, 1 insertion(+)include/linux/reset-controller.h +0
-0
include/linux/reset-controller.h struct reset_control_ops { · line 27
Quoted 7 lines
include/linux/reset-controller.h +1
-0@@ -21,6 +21,7 @@ struct reset_control_ops {struct module ;struct device_node ; +struct of_phandle_args ;/** * struct reset_controller_dev - reset controller entity that might
Since this is only a warning, I see no need for this to go through the clock tree. On the other hand there are no merge conflicts to be expected, so that's fine with me either way.
regards
Philipp
PATCH v4 2/15 clk: Allow drivers to pass in a regmap
In reply to Stephen BoydAdd support to the clock core so that drivers can pass in a regmap. If no regmap is specified try to query the device that's registering the clock for its regmap. This should allow drivers to use the core regmap helpers. This is based on a similar design in the regulator framework.
--- drivers/clk/clk.c | 8 ++++++++ include/linux/clk-provider.h | 7 +++++++ 2 files changed, 15 insertions(+)
drivers/clk/clk.c +8 -0
@@ -20,6 +20,7 @@#include <linux/device.h> #include <linux/init.h> #include <linux/sched.h> +#include <linux/regmap.h> static DEFINE_SPINLOCK (enable_lock);static DEFINE_MUTEX (prepare_lock);
@@ -1834,6 +1835,13 @@ static int _clk_register(struct device *dev, struct clk_hw *hw, struct clk *clk) clk->num_parents = hw->init->num_parents; hw->clk = clk; +if (hw->init->regmap) + hw->regmap = hw->init->regmap; +else if (dev &&dev_get_regmap (dev,NULL )) + hw->regmap =dev_get_regmap (dev,NULL ); +else if (dev && dev->parent) + hw->regmap =dev_get_regmap (dev->parent,NULL ); +/* allocate local copy in case parent_names is __initdata */ clk->parent_names =kcalloc (clk->num_parents,sizeof (char *),GFP_KERNEL );
include/linux/clk-provider.h +7 -0
@@ -142,6 +142,8 @@ struct clk_ops {void (*init)(struct clk_hw *hw); }; +struct regmap ; +/** * struct clk_init_data - holds init data that's common to all clocks and is * shared between the clock provider and the common clock framework.
@@ -151,6 +153,7 @@ struct clk_ops {* @parent_names: array of string names for all possible parents * @num_parents: number of possible parents * @flags: framework-level hints and quirks +* @regmap: regmap to use for regmap helpers and/or by providers */ struct clk_init_data {const char *name;
@@ -158,6 +161,7 @@ struct clk_init_data {const char **parent_names;u8 num_parents;unsigned long flags; +struct regmap *regmap; };/**
@@ -171,10 +175,13 @@ struct clk_init_data {* * @init: pointer to struct clk_init_data that contains the init data shared * with the common clock framework. +* +* @regmap: regmap to use for regmap helpers and/or by providers */ struct clk_hw {struct clk *clk;const struct clk_init_data *init; +struct regmap *regmap; };/*
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
Re: [PATCH v4 02/15] clk: Allow drivers to pass in a regmap
Quoted 5 lines · Stephen Boyd
Add support to the clock core so that drivers can pass in a regmap. If no regmap is specified try to query the device that's registering the clock for its regmap. This should allow drivers to use the core regmap helpers. This is based on a similar design in the regulator framework.
PATCH v4 2/15 clk: Allow drivers to pass in a regmap
In reply to Stephen BoydQuoting Stephen Boyd (2013-12-23 17:12:26)
Quoted 26 lines
Add support to the clock core so that drivers can pass in a regmap. If no regmap is specified try to query the device that's registering the clock for its regmap. This should allow drivers to use the core regmap helpers. This is based on a similar design in the regulator framework.
Cc Mark Brown <[email protected]>Signed-off-by Stephen Boyd <[email protected]>--- drivers/clk/clk.c | 8 ++++++++ include/linux/clk-provider.h | 7 +++++++ 2 files changed, 15 insertions(+)drivers/clk/clk.c +1
-0@@ -20,6 +20,7 @@#include <linux/device.h> #include <linux/init.h> #include <linux/sched.h> +#include <linux/regmap.h> static DEFINE_SPINLOCK (enable_lock);static DEFINE_MUTEX (prepare_lock);
drivers/clk/clk.c static int _clk_register(struct device *dev, struct clk_hw *hw, struct clk *clk) · line 1839
Quoted 5 lines
drivers/clk/clk.c +2
-0@@ -1834,6 +1835,13 @@ static int _clk_register(struct device *dev, struct clk_hw *hw, struct clk *clk) clk->num_parents = hw->init->num_parents; hw->clk = clk; +if (hw->init->regmap) + hw->regmap = hw->init->regmap;
Hi Stephen,
The whole series looks good to me except for the placement of the regmap details inside struct clk_hw. That structure exists only to hide struct clk from the hardware-specific clock structure and I'd not like to set the precedent of shoving per-clock data into it.
As an alternative, how about finding a way to put these per-clock regmap details into the hardware-specific clock structure? I understand that you want to make these ops available to others, which is why they are in the public struct clk_hw. I'm just wondering if that is the right way to do it...
Patch #3 illustrates the sort of struct-member-creep that worries me. What is to stop someone from putting "unsigned int divider_reg" or "unsigned int mux_reg", and then the thing just keeps growing.
Regards,
Mike
Quoted 55 lines
drivers/clk/clk.c +5
-0+else if (dev &&dev_get_regmap (dev,NULL )) + hw->regmap =dev_get_regmap (dev,NULL ); +else if (dev && dev->parent) + hw->regmap =dev_get_regmap (dev->parent,NULL ); +/* allocate local copy in case parent_names is __initdata */ clk->parent_names =kcalloc (clk->num_parents,sizeof (char *),GFP_KERNEL );include/linux/clk-provider.h +7
-0@@ -142,6 +142,8 @@ struct clk_ops {void (*init)(struct clk_hw *hw); }; +struct regmap ; +/** * struct clk_init_data - holds init data that's common to all clocks and is * shared between the clock provider and the common clock framework. @@ -151,6 +153,7 @@ struct clk_ops {* @parent_names: array of string names for all possible parents * @num_parents: number of possible parents * @flags: framework-level hints and quirks +* @regmap: regmap to use for regmap helpers and/or by providers */ struct clk_init_data {const char *name;@@ -158,6 +161,7 @@ struct clk_init_data {const char **parent_names;u8 num_parents;unsigned long flags; +struct regmap *regmap; };/** @@ -171,10 +175,13 @@ struct clk_init_data {* * @init: pointer to struct clk_init_data that contains the init data shared * with the common clock framework. +* +* @regmap: regmap to use for regmap helpers and/or by providers */ struct clk_hw {struct clk *clk;const struct clk_init_data *init; +struct regmap *regmap; };/* Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
Re: [PATCH v4 02/15] clk: Allow drivers to pass in a regmap
Quoted 39 lines · Mike Turquette
Quoting Stephen Boyd (2013-12-23 17:12:26)
Quoted 26 lines
Add support to the clock core so that drivers can pass in a regmap. If no regmap is specified try to query the device that's registering the clock for its regmap. This should allow drivers to use the core regmap helpers. This is based on a similar design in the regulator framework.
Cc Mark Brown <[email protected]>Signed-off-by Stephen Boyd <[email protected]>--- drivers/clk/clk.c | 8 ++++++++ include/linux/clk-provider.h | 7 +++++++ 2 files changed, 15 insertions(+)drivers/clk/clk.c +1
-0@@ -20,6 +20,7 @@#include <linux/device.h> #include <linux/init.h> #include <linux/sched.h> +#include <linux/regmap.h> static DEFINE_SPINLOCK (enable_lock);static DEFINE_MUTEX (prepare_lock);drivers/clk/clk.c static int _clk_register(struct device *dev, struct clk_hw *hw, struct clk *clk) · line 1839
Quoted 5 lines
drivers/clk/clk.c +2
-0@@ -1834,6 +1835,13 @@ static int _clk_register(struct device *dev, struct clk_hw *hw, struct clk *clk) clk->num_parents = hw->init->num_parents; hw->clk = clk; +if (hw->init->regmap) + hw->regmap = hw->init->regmap;Hi Stephen,
The whole series looks good to me except for the placement of the regmap details inside struct
clk_hw. That structure exists only to hide struct clk from the hardware-specific clock structure and I'd not like to set the precedent of shoving per-clock data into it.
Quoted 5 lines
As an alternative, how about finding a way to put these per-clock regmap details into the hardware-specific clock structure? I understand that you want to make these ops available to others, which is why they are in the public struct
clk_hw. I'm just wondering if that is the right way to do it...
The regulator framework has gone this way. It seemed like a similar approach in the clock framework would be the right way to go too.
Quoted 5 lines
Patch #3 illustrates the sort of struct-member-creep that worries me. What is to stop someone from putting "unsigned int
divider_reg" or "unsigned intmux_reg", and then the thing just keeps growing.
I see two ways forward if you don't want these members in struct clk_hw.
1) Inheritance: struct clk_regmap wrapper struct and clk_register_regmap() and devm_clk_register_regmap() and then another wrapper struct around that.
example:
struct clk_regmap {
struct clk_hw hw;
struct regmap *regmap;
unsigned int enable_reg;
unsigned int enable_mask;
bool enable_is_inverted;
};struct clk_branch {
u32 hwcg_reg;
u32 halt_reg;
u8 hwcg_bit;
u8 halt_bit;
u8 halt_check;
struct clk_regmap clkr;
};static struct clk_branch gsbi1_uart_clk = {
.halt_reg = 0x2fcc,
.halt_bit = 10,
.clkr = {
.enable_reg = 0x29d4,
.enable_mask = BIT(9),
.hw.init = &(struct clk_init_data){
.name = "gsbi1_uart_clk",
.parent_names = (const char *[]){
"gsbi1_uart_src",
},
.num_parents = 1,
.ops = &clk_branch_ops,
.flags = CLK_SET_RATE_PARENT,
},
},
};2) Interfaces: Add a void *data in struct clk_hw that can point to whatever I want and still have the same clk_regmap_register() and devm_clk_regmap_register()
Example:
struct clk_hw {
struct clk *clk;
const struct clk_init_data *init;
void *data;
};struct clk_regmap {
struct regmap *regmap;
unsigned int enable_reg;
unsigned int enable_mask;
bool enable_is_inverted;
};struct clk_branch {
u32 hwcg_reg;
u32 halt_reg;
u8 hwcg_bit;
u8 halt_bit;
u8 halt_check;
struct clk_hw;
};static struct clk_branch gsbi1_uart_clk = {
.halt_reg = 0x2fcc,
.halt_bit = 10,
.hw = {
.data = &(struct clk_regmap){
.enable_reg = 0x29d4,
.enable_mask = BIT(9),
};
.init = &(struct clk_init_data){
.name = "gsbi1_uart_clk",
.parent_names = (const char *[]){
"gsbi1_uart_src",
},
.num_parents = 1,
.ops = &clk_branch_ops,
.flags = CLK_SET_RATE_PARENT,
},
},
};I guess option 2 is less likely given your comment about clk_hw being nothing more than a traversal mechanism.
Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Re: [PATCH v4 02/15] clk: Allow drivers to pass in a regmap
Quoted 40 lines · Stephen Boyd
Quoted 4 lines · Mike Turquette
Patch #3 illustrates the sort of struct-member-creep that worries me. What is to stop someone from putting "unsigned int
divider_reg" or "unsigned intmux_reg", and then the thing just keeps growing.I see two ways forward if you don't want these members in struct
clk_hw.1) Inheritance: struct
clk_regmapwrapper struct andclk_register_regmap()anddevm_clk_register_regmap()and then another wrapper struct around that.example:
struct clk_regmap { struct clk_hw hw; struct regmap *regmap; unsigned int enable_reg; unsigned int enable_mask; bool enable_is_inverted; };struct clk_branch { u32 hwcg_reg; u32 halt_reg; u8 hwcg_bit; u8 halt_bit; u8 halt_check; struct clk_regmap clkr; };static struct clk_branch gsbi1_uart_clk = { .halt_reg = 0x2fcc, .halt_bit = 10, .clkr = { .enable_reg = 0x29d4, .enable_mask = BIT(9), .hw.init = &(struct clk_init_data){ .name = "gsbi1_uart_clk", .parent_names = (const char *[]){
Quoted 8 lines
"gsbi1_uart_src",
},
.num_parents = 1,
.ops = &clk_branch_ops,
.flags = CLK_SET_RATE_PARENT,
},
},
};The downside to this approach is that we have to have two similar structs for struct clk_gate if we want to support regmap in that code path. If we put the regmap inside struct clk_hw we don't have two different structs, we would just assign different ops.
struct clk_gate {
struct clk_hw hw;
void __iomem *reg;
u8 bit_idx;
u8 flags;
spinlock_t *lock;
};and
struct clk_gate_regmap {
struct clk_regmap hw;
u8 flags;
spinlock_t *lock;
};Do you have any preference on which way we move forward here? I have the wrapper method all finished and ready to send if you agree with that approach.
Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
PATCH v4 2/15 clk: Allow drivers to pass in a regmap
In reply to Stephen BoydQuoting Stephen Boyd (2014-01-08 18:11:40)
Quoted 90 lines · Mike Turquette
Quoted 39 lines
Quoting Stephen Boyd (2013-12-23 17:12:26)
Quoted 26 lines
Add support to the clock core so that drivers can pass in a regmap. If no regmap is specified try to query the device that's registering the clock for its regmap. This should allow drivers to use the core regmap helpers. This is based on a similar design in the regulator framework.
Cc Mark Brown <[email protected]>Signed-off-by Stephen Boyd <[email protected]>--- drivers/clk/clk.c | 8 ++++++++ include/linux/clk-provider.h | 7 +++++++ 2 files changed, 15 insertions(+)drivers/clk/clk.c +1
-0@@ -20,6 +20,7 @@#include <linux/device.h> #include <linux/init.h> #include <linux/sched.h> +#include <linux/regmap.h> static DEFINE_SPINLOCK (enable_lock);static DEFINE_MUTEX (prepare_lock);drivers/clk/clk.c static int _clk_register(struct device *dev, struct clk_hw *hw, struct clk *clk) · line 1839
Quoted 5 lines
drivers/clk/clk.c +2
-0@@ -1834,6 +1835,13 @@ static int _clk_register(struct device *dev, struct clk_hw *hw, struct clk *clk) clk->num_parents = hw->init->num_parents; hw->clk = clk; +if (hw->init->regmap) + hw->regmap = hw->init->regmap;Hi Stephen,
The whole series looks good to me except for the placement of the regmap details inside struct
clk_hw. That structure exists only to hide struct clk from the hardware-specific clock structure and I'd not like to set the precedent of shoving per-clock data into it.Quoted 5 lines
As an alternative, how about finding a way to put these per-clock regmap details into the hardware-specific clock structure? I understand that you want to make these ops available to others, which is why they are in the public struct
clk_hw. I'm just wondering if that is the right way to do it...The regulator framework has gone this way. It seemed like a similar approach in the clock framework would be the right way to go too.
Quoted 5 lines
Patch #3 illustrates the sort of struct-member-creep that worries me. What is to stop someone from putting "unsigned int
divider_reg" or "unsigned intmux_reg", and then the thing just keeps growing.I see two ways forward if you don't want these members in struct
clk_hw.1) Inheritance: struct
clk_regmapwrapper struct andclk_register_regmap()anddevm_clk_register_regmap()and then another wrapper struct around that.example:
struct clk_regmap { struct clk_hw hw; struct regmap *regmap; unsigned int enable_reg; unsigned int enable_mask; bool enable_is_inverted; };struct clk_branch { u32 hwcg_reg; u32 halt_reg; u8 hwcg_bit; u8 halt_bit; u8 halt_check; struct clk_regmap clkr; };static struct clk_branch gsbi1_uart_clk = { .halt_reg = 0x2fcc, .halt_bit = 10, .clkr = { .enable_reg = 0x29d4, .enable_mask = BIT(9), .hw.init = &(struct clk_init_data){ .name = "gsbi1_uart_clk", .parent_names = (const char *[]){
Quoted 8 lines
"gsbi1_uart_src",
},
.num_parents = 1,
.ops = &clk_branch_ops,
.flags = CLK_SET_RATE_PARENT,
},
},
};If we're going to use these wrappers, why make it regmap specific? The struct clk_desc patches[1][2] can achieve this, but in a more generic way.
Quoted 51 lines
2) Interfaces: Add a void *data in struct
clk_hwthat can point to whatever I want and still have the sameclk_regmap_register()anddevm_clk_regmap_register()Example:
struct clk_hw { struct clk *clk; const struct clk_init_data *init; void *data; };struct clk_regmap { struct regmap *regmap; unsigned int enable_reg; unsigned int enable_mask; bool enable_is_inverted; };struct clk_branch { u32 hwcg_reg; u32 halt_reg; u8 hwcg_bit; u8 halt_bit; u8 halt_check; struct clk_hw; };static struct clk_branch gsbi1_uart_clk = { .halt_reg = 0x2fcc, .halt_bit = 10, .hw = { .data = &(struct clk_regmap){ .enable_reg = 0x29d4, .enable_mask = BIT(9), }; .init = &(struct clk_init_data){ .name = "gsbi1_uart_clk", .parent_names = (const char *[]){ "gsbi1_uart_src", }, .num_parents = 1, .ops = &clk_branch_ops, .flags = CLK_SET_RATE_PARENT, }, }, };
Quoted 2 lines
I guess option 2 is less likely given your comment about
clk_hwbeing nothing more than a traversal mechanism.
Instead of private data, how about a .register() callback function that can point to anything you like? The clk_desc patches implement this and it would suffice for registering regmap ops or anything else, without polluting struct clk_hw.
[1] http://www.spinics.net/lists/linux-omap/msg101822.html
[2] http://www.spinics.net/lists/linux-omap/msg101698.html
So you could statically define gsbi1_uart_clk with:
static struct clk_branch_desc gsbi1_uart_clk_desc = {
.halt_reg = 0x2fcc,
.halt_bit = 10,
.enable_reg = 0x29d4,
.enable_mask = BIT(9),
.desc = {
.name = "gsbi1_uart_clk",
.parent_names = (const char *[]){
"gsbi1_uart_src",
},
.num_parents = 1,
.ops = &clk_branch_ops,
.flags = CLK_SET_RATE_PARENT,
},
};And then register it with:
clk_register_desc(NULL, &gsbi1_uart_clk_desc.desc);
This is very analogous to the way that you use use &gsbi1_uart_clk.hw but it is more generic and also doesn't pollute clk_hw any further. I also think your static data is quite a bit prettier using this method.
Thoughts?
Regards,
Mike
Quoted 5 lines
Signature · 3 lines
-- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Re: [PATCH v4 02/15] clk: Allow drivers to pass in a regmap
Quoted 4 lines · Mike Turquette
If we're going to use these wrappers, why make it regmap specific? The struct
clk_descpatches[1][2] can achieve this, but in a more generic way.
I think you're suggesting a way to avoid adding a clk_register_regmap() function? But won't we need to write the same code:
if (dev && dev_get_regmap(dev, NULL))
[clk_type]->regmap = dev_get_regmap(dev, NULL);
else if (dev && dev->parent)
[clk_type]->regmap = dev_get_regmap(dev->parent, NULL);everytime we want to assign the regmap pointer to a different clock type? A macro might work for this little snippet, but it wouldn't have any type safety.
Quoted 82 lines
Quoted 51 lines
2) Interfaces: Add a void *data in struct
clk_hwthat can point to whatever I want and still have the sameclk_regmap_register()anddevm_clk_regmap_register()Example:
struct clk_hw { struct clk *clk; const struct clk_init_data *init; void *data; };struct clk_regmap { struct regmap *regmap; unsigned int enable_reg; unsigned int enable_mask; bool enable_is_inverted; };struct clk_branch { u32 hwcg_reg; u32 halt_reg; u8 hwcg_bit; u8 halt_bit; u8 halt_check; struct clk_hw; };static struct clk_branch gsbi1_uart_clk = { .halt_reg = 0x2fcc, .halt_bit = 10, .hw = { .data = &(struct clk_regmap){ .enable_reg = 0x29d4, .enable_mask = BIT(9), }; .init = &(struct clk_init_data){ .name = "gsbi1_uart_clk", .parent_names = (const char *[]){ "gsbi1_uart_src", }, .num_parents = 1, .ops = &clk_branch_ops, .flags = CLK_SET_RATE_PARENT, }, }, };Quoted 2 lines
I guess option 2 is less likely given your comment about
clk_hwbeing nothing more than a traversal mechanism.Instead of private data, how about a .register() callback function that can point to anything you like? The
clk_descpatches implement this and it would suffice for registering regmap ops or anything else, without polluting structclk_hw.[1] http://www.spinics.net/lists/linux-omap/msg101822.html
[2] http://www.spinics.net/lists/linux-omap/msg101698.htmlSo you could statically define
gsbi1_uart_clkwith:static struct clk_branch_desc gsbi1_uart_clk_desc = { .halt_reg = 0x2fcc, .halt_bit = 10, .enable_reg = 0x29d4, .enable_mask = BIT(9), .desc = { .name = "gsbi1_uart_clk", .parent_names = (const char *[]){ "gsbi1_uart_src", }, .num_parents = 1, .ops = &clk_branch_ops, .flags = CLK_SET_RATE_PARENT, }, };And then register it with:
Quoted 7 lines
clk_register_desc(NULL, &gsbi1_uart_clk_desc.desc);This is very analogous to the way that you use use &gsbi1_uart_clk.hw but it is more generic and also doesn't pollute
clk_hwany further. I also think your static data is quite a bit prettier using this method.Thoughts?
Is the plan to allocate a struct clk_branch at runtime and then copy all the fields over one by one? I'm trying to avoid that because it takes more time and more runtime memory. If I had to go the descriptor route I would probably avoid copying any fields and just point to the descriptor from struct clk_branch, i.e.
struct clk_branch {
struct clk_branch_desc *desc; struct clk_hw;
};
but that still seems wasteful to allocate a bunch of little pointer wrappers when I could have just embedded the clk_hw struct inside the clk_branch struct from the start.
It feels another key point is being missed though. The regmap pointer and the enable_reg/enable_mask is embedded in clk_hw to allow the same code to be used by different types of surrounding structs. Each struct: clk_pll, clk_rcg, and clk_branch in this series use the regmap interface to enable/disable the clock and they can easily do so by passing something that's always available from struct clk_hw (be it via a wrapper struct, private data member, or addition of new fields to clk_hw). If the regmap members move into each specific type of clock we can't just pass a single pointer to the enable/disable regmap functions anymore. This is the reason why I suggested a driver data pointer or container struct so that everything regmap related is contained within one type.
Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Re: [PATCH v4 02/15] clk: Allow drivers to pass in a regmap
Quoted 5 lines · Stephen Boyd
It feels another key point is being missed though. The regmap pointer and the enable_reg/enable_mask is embedded in
clk_hwto allow the same code to be used by different types of surrounding structs. Each struct:clk_pll,clk_rcg, andclk_branchin this series use the regmap interface to enable/disable the clock and
Quoted 9 lines
they can easily do so by passing something that's always available from struct
clk_hw(be it via a wrapper struct, private data member, or addition of new fields toclk_hw). If the regmap members move into each specific type of clock we can't just pass a single pointer to the enable/disable regmap functions anymore. This is the reason why I suggested a driver data pointer or container struct so that everything regmap related is contained within one type.
Any thoughts?
Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
PATCH v4 2/15 clk: Allow drivers to pass in a regmap
In reply to Stephen BoydQuoting Stephen Boyd (2014-01-09 23:05:17)
Quoted 10 lines · Mike Turquette
Quoted 4 lines
If we're going to use these wrappers, why make it regmap specific? The struct
clk_descpatches[1][2] can achieve this, but in a more generic way.I think you're suggesting a way to avoid adding a
clk_register_regmap()function? But won't we need to write the same code:
Quoted 8 lines
if (dev && dev_get_regmap(dev, NULL)) [clk_type]->regmap = dev_get_regmap(dev, NULL); else if (dev && dev->parent) [clk_type]->regmap = dev_get_regmap(dev->parent, NULL);everytime we want to assign the regmap pointer to a different clock type? A macro might work for this little snippet, but it wouldn't have any type safety.
Hi Stephen,
Avoiding a new clk_register_regmap() function is one thing worth doing. But additionally I think that this regmap infrastructure in the core code still is not the right way forward.
Looking at patch #3 I can already see how those helper functions will grow just like the basic clock type implementations. Take a look at drivers/clk/clk-divider.c and check out the HIWORD_MASK stuff. That really shouldn't belong there, but multiple platforms are using the Designware IP that needs this so in the Name Of Consolidation it was done. Basically that code is gross.
A more relevant example: look at the gate clock with a busy bit implementation in arch/arm/mach-imx/clk-gate2.c. The same could be done for your clk_enable_regmap() function: someone could subclass it and add a busy bit or status bit to poll on. But should they? The extra layer of indirection buys us nothing and takes a clean piece of code and complicates it.
I'd rather your .enable, .disable and .is_enabled implementations live in drivers/clk/msm/ so that we can avoid this sort of feature creep in the future. It's perfectly fine if others implement the same code in their clock drivers.
With all of that said, then there is no point in keeping struct regmap *regmap inside of struct clk_hw. It can be moved inside of your struct clk_rcg, struct clk_branch and struct clk_pll definitions.
Quoted 97 lines
Quoted 83 lines
Quoted 52 lines
2) Interfaces: Add a void *data in struct
clk_hwthat can point to whatever I want and still have the sameclk_regmap_register()anddevm_clk_regmap_register()Example:
struct clk_hw { struct clk *clk; const struct clk_init_data *init; void *data; };struct clk_regmap { struct regmap *regmap; unsigned int enable_reg; unsigned int enable_mask; bool enable_is_inverted; };struct clk_branch { u32 hwcg_reg; u32 halt_reg; u8 hwcg_bit; u8 halt_bit; u8 halt_check; struct clk_hw; };static struct clk_branch gsbi1_uart_clk = { .halt_reg = 0x2fcc, .halt_bit = 10, .hw = { .data = &(struct clk_regmap){ .enable_reg = 0x29d4, .enable_mask = BIT(9), }; .init = &(struct clk_init_data){ .name = "gsbi1_uart_clk", .parent_names = (const char *[]){ "gsbi1_uart_src", }, .num_parents = 1, .ops = &clk_branch_ops, .flags = CLK_SET_RATE_PARENT, }, }, };Quoted 2 lines
I guess option 2 is less likely given your comment about
clk_hwbeing nothing more than a traversal mechanism.Instead of private data, how about a .register() callback function that can point to anything you like? The
clk_descpatches implement this and it would suffice for registering regmap ops or anything else, without polluting structclk_hw.[1] http://www.spinics.net/lists/linux-omap/msg101822.html
[2] http://www.spinics.net/lists/linux-omap/msg101698.htmlSo you could statically define
gsbi1_uart_clkwith:static struct clk_branch_desc gsbi1_uart_clk_desc = { .halt_reg = 0x2fcc, .halt_bit = 10, .enable_reg = 0x29d4, .enable_mask = BIT(9), .desc = { .name = "gsbi1_uart_clk", .parent_names = (const char *[]){ "gsbi1_uart_src", }, .num_parents = 1, .ops = &clk_branch_ops, .flags = CLK_SET_RATE_PARENT, }, };And then register it with:
Quoted 7 lines
clk_register_desc(NULL, &gsbi1_uart_clk_desc.desc);This is very analogous to the way that you use use &gsbi1_uart_clk.hw but it is more generic and also doesn't pollute
clk_hwany further. I also think your static data is quite a bit prettier using this method.Thoughts?
Is the plan to allocate a struct
clk_branchat runtime and then copy all the fields over one by one? I'm trying to avoid that because it takes more time and more runtime memory. If I had to go the descriptor route I would probably avoid copying any fields and just point to the descriptor from structclk_branch, i.e.
Quoted 9 lines
struct clk_branch { struct clk_branch_desc *desc; struct clk_hw;};
but that still seems wasteful to allocate a bunch of little pointer wrappers when I could have just embedded the
clk_hwstruct inside theclk_branchstruct from the start.
The pointer copy stuff was done so that every instance of struct clk_init_data could be marked as __initdata.
Quoted 5 lines
It feels another key point is being missed though. The regmap pointer and the enable_reg/enable_mask is embedded in
clk_hwto allow the same code to be used by different types of surrounding structs. Each struct:clk_pll,clk_rcg, andclk_branchin this series use the regmap interface to enable/disable the clock and
Quoted 8 lines
they can easily do so by passing something that's always available from struct
clk_hw(be it via a wrapper struct, private data member, or addition of new fields toclk_hw). If the regmap members move into each specific type of clock we can't just pass a single pointer to the enable/disable regmap functions anymore. This is the reason why I suggested a driver data pointer or container struct so that everything regmap related is contained within one type.
I get understand the goal of reuse and I applaud it. But even if we did pack the regmap data into struct clk_hw it would start to grow out of control as I mentioned in a previous email. In order for this to work you have to package more than just struct regmap *regmap into struct clk_hw. You need the register offset as well as any relevant masks and bit field values. And then you need more stuff for muxes and dividers. And hey now you need busy/poll register values and another platform needs to program shadow registers before flipping the Go Bit ... the list goes on and on.
So in summary: consolidation is over-rated. You can put your regmap functions into drivers/clk/msm/ and not convert over to struct clk_desc by the way, just to remove any confusion on that point.
Quoted 4 lines
Signature · 3 lines
-- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Re: [PATCH v4 02/15] clk: Allow drivers to pass in a regmap
Quoted 5 lines · Mike Turquette
So in summary: consolidation is over-rated. You can put your regmap functions into
drivers/clk/msm/and not convert over to structclk_descby the way, just to remove any confusion on that point.
Ok I've made the wrapper struct clk_regmap and posted the patches. I think I've addressed all your concerns.
Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Re: [PATCH v4 02/15] clk: Allow drivers to pass in a regmap
In reply to Mike TurquetteQuoted 46 lines · Mike Turquette
Quoting Stephen Boyd (2013-12-23 17:12:26)
Quoted 26 lines
Add support to the clock core so that drivers can pass in a regmap. If no regmap is specified try to query the device that's registering the clock for its regmap. This should allow drivers to use the core regmap helpers. This is based on a similar design in the regulator framework.
Cc Mark Brown <[email protected]>Signed-off-by Stephen Boyd <[email protected]>--- drivers/clk/clk.c | 8 ++++++++ include/linux/clk-provider.h | 7 +++++++ 2 files changed, 15 insertions(+)drivers/clk/clk.c +1
-0@@ -20,6 +20,7 @@#include <linux/device.h> #include <linux/init.h> #include <linux/sched.h> +#include <linux/regmap.h> static DEFINE_SPINLOCK (enable_lock);static DEFINE_MUTEX (prepare_lock);drivers/clk/clk.c static int _clk_register(struct device *dev, struct clk_hw *hw, struct clk *clk) · line 1839
Quoted 5 lines
drivers/clk/clk.c +2
-0@@ -1834,6 +1835,13 @@ static int _clk_register(struct device *dev, struct clk_hw *hw, struct clk *clk) clk->num_parents = hw->init->num_parents; hw->clk = clk; +if (hw->init->regmap) + hw->regmap = hw->init->regmap;Hi Stephen,
The whole series looks good to me except for the placement of the regmap details inside struct
clk_hw. That structure exists only to hide struct clk from the hardware-specific clock structure and I'd not like to set the precedent of shoving per-clock data into it.As an alternative, how about finding a way to put these per-clock regmap details into the hardware-specific clock structure? I understand that you want to make these ops available to others, which is why they are in the public struct
clk_hw. I'm just wondering if that is the right way to do it...
Quoted 3 lines
Patch #3 illustrates the sort of struct-member-creep that worries me. What is to stop someone from putting "unsigned int
divider_reg" or "unsigned intmux_reg", and then the thing just keeps growing.
I agree with Mike here. This definitely encourages struct field creep if more people want to use it.
I talked to Stephen is person and my recommendation is to not have any new fields other than struct regmap in clk_hw and remove the above 2 lines of code.
Quoted 2 lines
drivers/clk/clk.c static int _clk_register(struct device *dev, struct clk_hw *hw, struct clk *clk) · line 1841
Quoted 2 lines
drivers/clk/clk.c +2
-0+else if (dev &&dev_get_regmap (dev,NULL )) + hw->regmap =dev_get_regmap (dev,NULL );
Move "struct regmap *regmap" into struct clk_hw (since it's truly reusable across clock types and is technically purely HW related) and update it from the device's regmap like above.
We can then provide __clk_regmap_enable(regmap, offset, enable_mask) helper functions. Then clock specific functions can use the helper. We can even a simple macro to generate these wrappers.
#define DEFINE_REGMAP_EN_DIS(clktype) \
int clk_type##_enable(clktype *c, ....) { }
int clk_type##_disable(clktype *c, ....) { }
That to me seems like a reasonable compromise.
Thanks,
Saravana
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
PATCH v4 2/15 clk: Allow drivers to pass in a regmap
Quoting Saravana Kannan (2014-01-13 19:54:42)
Quoted 58 lines · Mike Turquette
Quoted 46 lines
Quoting Stephen Boyd (2013-12-23 17:12:26)
Quoted 26 lines
Add support to the clock core so that drivers can pass in a regmap. If no regmap is specified try to query the device that's registering the clock for its regmap. This should allow drivers to use the core regmap helpers. This is based on a similar design in the regulator framework.
Cc Mark Brown <[email protected]>Signed-off-by Stephen Boyd <[email protected]>--- drivers/clk/clk.c | 8 ++++++++ include/linux/clk-provider.h | 7 +++++++ 2 files changed, 15 insertions(+)drivers/clk/clk.c +1
-0@@ -20,6 +20,7 @@#include <linux/device.h> #include <linux/init.h> #include <linux/sched.h> +#include <linux/regmap.h> static DEFINE_SPINLOCK (enable_lock);static DEFINE_MUTEX (prepare_lock);drivers/clk/clk.c static int _clk_register(struct device *dev, struct clk_hw *hw, struct clk *clk) · line 1839
Quoted 5 lines
drivers/clk/clk.c +2
-0@@ -1834,6 +1835,13 @@ static int _clk_register(struct device *dev, struct clk_hw *hw, struct clk *clk) clk->num_parents = hw->init->num_parents; hw->clk = clk; +if (hw->init->regmap) + hw->regmap = hw->init->regmap;Hi Stephen,
The whole series looks good to me except for the placement of the regmap details inside struct
clk_hw. That structure exists only to hide struct clk from the hardware-specific clock structure and I'd not like to set the precedent of shoving per-clock data into it.As an alternative, how about finding a way to put these per-clock regmap details into the hardware-specific clock structure? I understand that you want to make these ops available to others, which is why they are in the public struct
clk_hw. I'm just wondering if that is the right way to do it...Quoted 3 lines
Patch #3 illustrates the sort of struct-member-creep that worries me. What is to stop someone from putting "unsigned int
divider_reg" or "unsigned intmux_reg", and then the thing just keeps growing.I agree with Mike here. This definitely encourages struct field creep if more people want to use it.
I talked to Stephen is person and my recommendation is to not have any new fields other than struct regmap in
clk_hwand remove the above 2 lines of code.
Quoted 6 lines
Quoted 2 lines
drivers/clk/clk.c static int _clk_register(struct device *dev, struct clk_hw *hw, struct clk *clk) · line 1841
Quoted 2 lines
drivers/clk/clk.c +2
-0+else if (dev &&dev_get_regmap (dev,NULL )) + hw->regmap =dev_get_regmap (dev,NULL );Move "struct regmap *regmap" into struct
clk_hw(since it's truly reusable across clock types and is technically purely HW related) and update it from the device's regmap like above.
Hi Saravana,
Thanks for your comments. In the paragraph above you mean "struct clk_hw" or do you mean the hardware-specific structure(s) defined in a clock driver?
Quoted 5 lines
We can then provide
__clk_regmap_enable(regmap, offset, enable_mask)helper functions. Then clock specific functions can use the helper. We can even a simple macro to generate these wrappers.
Quoted 7 lines
#define
DEFINE_REGMAP_EN_DIS(clktype)\int clk_type##_enable(clktype *c, ....) { }
int clk_type##_disable(clktype *c, ....) { }That to me seems like a reasonable compromise.
Providing common functions for the basic case (e.g. read-modify-write on a register using a known mask) is reasonable. But that is exactly what the existing basic clock types do (sans regmap) and they have all become pretty ugly over time. And the clk-composite implementation just makes me a sad panda.
I'm not opposed to providing public implementations of clk_ops callbacks that use regmap, but I will be very mindful of any feature creep in the future.
I am still unconvinced that adding struct regmap to struct clk_hw is a good idea. The regmap data is a function of hardware-specific details and those details always have and always will belong in the clock driver.
Regards,
Mike
Quoted 6 lines
Thanks,
SaravanaSignature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
Re: [PATCH v4 02/15] clk: Allow drivers to pass in a regmap
Quoted 5 lines · Mike Turquette
Providing common functions for the basic case (e.g. read-modify-write on a register using a known mask) is reasonable. But that is exactly what the existing basic clock types do (sans regmap) and they have all become pretty ugly over time. And the clk-composite implementation just makes me a sad panda.
What we've tried to do with regulators is just have multiple helper
functions in the core rather than trying to merge their implementation,
the drivers pick the right one for their usage, and in cases where there
aren't many drivers doing the same thing we just have the driver either
copy the bits of the implementation they reuse or call the helper
function from within the implementation.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140115/8b75c283/attachment.sig>
Re: [PATCH v4 02/15] clk: Allow drivers to pass in a regmap
In reply to Mike TurquetteQuoted 91 lines · Mike Turquette
Quoting Saravana Kannan (2014-01-13 19:54:42)
Quoted 58 lines · Mike Turquette
Quoted 46 lines
Quoting Stephen Boyd (2013-12-23 17:12:26)
Quoted 26 lines
Add support to the clock core so that drivers can pass in a regmap. If no regmap is specified try to query the device that's registering the clock for its regmap. This should allow drivers to use the core regmap helpers. This is based on a similar design in the regulator framework.
Cc Mark Brown <[email protected]>Signed-off-by Stephen Boyd <[email protected]>--- drivers/clk/clk.c | 8 ++++++++ include/linux/clk-provider.h | 7 +++++++ 2 files changed, 15 insertions(+)drivers/clk/clk.c +1
-0@@ -20,6 +20,7 @@#include <linux/device.h> #include <linux/init.h> #include <linux/sched.h> +#include <linux/regmap.h> static DEFINE_SPINLOCK (enable_lock);static DEFINE_MUTEX (prepare_lock);drivers/clk/clk.c static int _clk_register(struct device *dev, struct clk_hw *hw, struct clk *clk) · line 1839
Quoted 5 lines
drivers/clk/clk.c +2
-0@@ -1834,6 +1835,13 @@ static int _clk_register(struct device *dev, struct clk_hw *hw, struct clk *clk) clk->num_parents = hw->init->num_parents; hw->clk = clk; +if (hw->init->regmap) + hw->regmap = hw->init->regmap;Hi Stephen,
The whole series looks good to me except for the placement of the regmap details inside struct
clk_hw. That structure exists only to hide struct clk from the hardware-specific clock structure and I'd not like to set the precedent of shoving per-clock data into it.As an alternative, how about finding a way to put these per-clock regmap details into the hardware-specific clock structure? I understand that you want to make these ops available to others, which is why they are in the public struct
clk_hw. I'm just wondering if that is the right way to do it...Quoted 3 lines
Patch #3 illustrates the sort of struct-member-creep that worries me. What is to stop someone from putting "unsigned int
divider_reg" or "unsigned intmux_reg", and then the thing just keeps growing.I agree with Mike here. This definitely encourages struct field creep if more people want to use it.
I talked to Stephen is person and my recommendation is to not have any new fields other than struct regmap in
clk_hwand remove the above 2 lines of code.Quoted 6 lines
Quoted 2 lines
drivers/clk/clk.c static int _clk_register(struct device *dev, struct clk_hw *hw, struct clk *clk) · line 1841
Quoted 2 lines
drivers/clk/clk.c +2
-0+else if (dev &&dev_get_regmap (dev,NULL )) + hw->regmap =dev_get_regmap (dev,NULL );Move "struct regmap *regmap" into struct
clk_hw(since it's truly reusable across clock types and is technically purely HW related) and update it from the device's regmap like above.Hi Saravana,
Thanks for your comments. In the paragraph above you mean "struct
clk_hw" or do you mean the hardware-specific structure(s) defined in a clock driver?Quoted 5 lines
We can then provide
__clk_regmap_enable(regmap, offset, enable_mask)helper functions. Then clock specific functions can use the helper. We can even a simple macro to generate these wrappers.Quoted 7 lines
#define
DEFINE_REGMAP_EN_DIS(clktype)\int clk_type##_enable(clktype *c, ....) { }
int clk_type##_disable(clktype *c, ....) { }That to me seems like a reasonable compromise.
Providing common functions for the basic case (e.g. read-modify-write on a register using a known mask) is reasonable. But that is exactly what the existing basic clock types do (sans regmap) and they have all become pretty ugly over time. And the clk-composite implementation just makes me a sad panda.
Quoted 8 lines
I'm not opposed to providing public implementations of
clk_opscallbacks that use regmap, but I will be very mindful of any feature creep in the future.I am still unconvinced that adding struct regmap to struct
clk_hwis a good idea. The regmap data is a function of hardware-specific details and those details always have and always will belong in the clock driver
The details of the bits inside the register and how it's used would be clock type specific. Meaning, a Vendor X clock gate might have a busy bit and Vendor Y clock gate might not have a busy bit.
Regmap doesn't try to consolidate that. I'm not saying those clock gates should not be consolidated, but that's not what regmap is trying to do.
Regmap is helpful to consolidate clocks that behave exactly the same way, but differ in how the clock registers are accessed. Eg: mem-mapped IO, I2C, CP15 read/writes. So, even with a MSM based board, just because the way to access the registers are different, we could have to implement 3 different clock gate types. Which I think would be the wrong thing to do. Regmap cleanly consolidates this because the clock types just need to store the offsets and operate on them as usual using regmap APIs.
Since the regmap for the clock is assigned based on the device that's registering the enable/disable code for a clock gate can be agnostic of how the registers are accesses. Yes, regmap does provide helpers for read/modify writes, but that's not the main reason for using it.
Btw, this is a very real case on MSMs. The CPU clocks are accesses thru CP15 instructions, and the other clock trees are accessed through mem-mapped IO. But they pretty much behave the same way. That's what reg map is solving.
And I think this is a common problem for ANY clock type that one might implement. Which is why I think it should be in some common clock struct. The clock drivers will need access to the regmap. So, I picked clk_hw (the struct defined by the clock framework) and not struct clk. This also allows for the framework registration code to go populate the regmap pointer for all clocks from the regmap of the device.
Thoughts?
Thanks,
Saravana
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
PATCH v4 3/15 clk: Add regmap core helpers for enable/disable/is_enabled
In reply to Stephen BoydThe clock framework already has support for simple gate clocks but if drivers want to use the gate clock functionality they need to wrap the gate clock in another struct and chain the ops by calling the gate ops from their own custom ops. Plus the gate clock implementation only supports MMIO accessors so other bus type clocks don't benefit from the potential code reuse. Add some simple regmap helpers for enable/disable/is_enabled that drivers can use as drop in replacements for their clock ops or as simple functions they call from their own custom ops. This is based on similar helps in the regulator framework.
--- drivers/clk/clk.c | 70 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/clk-provider.h | 13 ++++++++ 2 files changed, 83 insertions(+)
drivers/clk/clk.c +70 -0
@@ -742,6 +742,76 @@ out:return best; } +/** +* clk_is_enabled_regmap - standard is_enabled() for regmap users +* +* @hw: clk to operate on +* +* Clocks that use regmap for their register I/O can set the +* enable_reg and enable_mask fields in their struct clk_hw and then use +* this as their is_enabled operation, saving some code. +*/ +int clk_is_enabled_regmap (struct clk_hw *hw) +{ +unsigned int val; +int ret; + + ret =regmap_read (hw->regmap, hw->enable_reg, &val); +if (ret !=0 ) +return ret; + +if (hw->enable_is_inverted) +return (val & hw->enable_mask) ==0 ; +else +return (val & hw->enable_mask) !=0 ; +} +EXPORT_SYMBOL_GPL (clk_is_enabled_regmap); + +/** +* clk_enable_regmap - standard enable() for regmap users +* +* @hw: clk to operate on +* +* Clocks that use regmap for their register I/O can set the +* enable_reg and enable_mask fields in their struct clk_hw and then use +* this as their enable() operation, saving some code. +*/ +int clk_enable_regmap (struct clk_hw *hw) +{ +unsigned int val; + +if (hw->enable_is_inverted) + val =0 ; +else + val = hw->enable_mask; + +return regmap_update_bits (hw->regmap, hw->enable_reg, + hw->enable_mask, val); +} +EXPORT_SYMBOL_GPL (clk_enable_regmap); + +/** +* clk_disable_regmap - standard disable() for regmap users +* +* @hw: clk to operate on +* +* Clocks that use regmap for their register I/O can set the +* enable_reg and enable_mask fields in their struct clk_hw and then use +* this as their disable() operation, saving some code. +*/ +void clk_disable_regmap (struct clk_hw *hw) +{ +unsigned int val; + +if (hw->enable_is_inverted) + val = hw->enable_mask; +else + val =0 ; + +regmap_update_bits (hw->regmap, hw->enable_reg, hw->enable_mask, val); +} +EXPORT_SYMBOL_GPL (clk_disable_regmap); +/*** clk api ***/ void __clk_unprepare (struct clk *clk)
include/linux/clk-provider.h +13 -0
@@ -177,11 +177,21 @@ struct clk_init_data {* with the common clock framework. * * @regmap: regmap to use for regmap helpers and/or by providers +* +* @enable_reg: register when using regmap enable/disable ops +* +* @enable_mask: mask when using regmap enable/disable ops +* +* @enable_is_inverted: flag to indicate set enable_mask bits to disable +* when using clock_enable_regmap and friends APIs. */ struct clk_hw {struct clk *clk;const struct clk_init_data *init;struct regmap *regmap; +unsigned int enable_reg; +unsigned int enable_mask; +bool enable_is_inverted; };/*
@@ -447,6 +457,9 @@ struct clk *__clk_lookup(const char *name);long __clk_mux_determine_rate (struct clk_hw *hw,unsigned long rate,unsigned long *best_parent_rate,struct clk **best_parent_p); +int clk_is_enabled_regmap (struct clk_hw *hw); +int clk_enable_regmap (struct clk_hw *hw); +void clk_disable_regmap (struct clk_hw *hw);/* * FIXME clock api without lock protection
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
Re: [PATCH v4 03/15] clk: Add regmap core helpers for enable/disable/is_enabled
Quoted 4 lines · Stephen Boyd
The clock framework already has support for simple gate clocks but if drivers want to use the gate clock functionality they need to wrap the gate clock in another struct and chain the ops by calling the gate ops from their own custom ops. Plus the gate
Re: [PATCH v4 03/15] clk: Add regmap core helpers for enable/disable/is_enabled
In reply to Stephen BoydQuoted 11 lines · Stephen Boyd
The clock framework already has support for simple gate clocks but if drivers want to use the gate clock functionality they need to wrap the gate clock in another struct and chain the ops by calling the gate ops from their own custom ops. Plus the gate clock implementation only supports MMIO accessors so other bus type clocks don't benefit from the potential code reuse. Add some simple regmap helpers for enable/disable/is_enabled that drivers can use as drop in replacements for their clock ops or as simple functions they call from their own custom ops. This is based on similar helps in the regulator framework.
The same comment applies as to the previous version. Is it useful to introduce copies of the gate handling while the difference in only in how the hardware registers get accessed?
include/linux/clk-provider.h struct clk *__clk_lookup(const char *name); · line 462
Quoted 11 lines
include/linux/clk-provider.h +3
-0@@ -177,11 +177,21 @@ struct clk_init_data {@@ -447,6 +457,9 @@ struct clk *__clk_lookup(const char *name);long __clk_mux_determine_rate (struct clk_hw *hw,unsigned long rate,unsigned long *best_parent_rate,struct clk **best_parent_p); +int clk_is_enabled_regmap (struct clk_hw *hw); +int clk_enable_regmap (struct clk_hw *hw); +void clk_disable_regmap (struct clk_hw *hw);
Looking at the patch: Do you expect callers to remember whether a clock gate is backed by mmio or by regmap access, to call a different set of routines? Should this not be hidden behind the API and be transparent after clock registration?
I'd suggest to fold regmap support into Tero Kristo's ll_ops approach, and to discuss this in his v12 thread.
virtually yours
Gerhard Sittig
Signature · 3 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr. 5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office at denx.de
Re: [PATCH v4 03/15] clk: Add regmap core helpers for enable/disable/is_enabled
Quoted 13 lines · Gerhard Sittig
Quoted 11 lines · Stephen Boyd
The clock framework already has support for simple gate clocks but if drivers want to use the gate clock functionality they need to wrap the gate clock in another struct and chain the ops by calling the gate ops from their own custom ops. Plus the gate clock implementation only supports MMIO accessors so other bus type clocks don't benefit from the potential code reuse. Add some simple regmap helpers for enable/disable/is_enabled that drivers can use as drop in replacements for their clock ops or as simple functions they call from their own custom ops. This is based on similar helps in the regulator framework.
Quoted 4 lines
The same comment applies as to the previous version. Is it useful to introduce copies of the gate handling while the difference in only in how the hardware registers get accessed?
I don't plan to use the clk-gate.c implementation because I need more than just a bit toggling clock. We can easily make clk-gate.c use these helpers if you're worried about the very small amount of code duplication between the two. I'd be glad to do that, I just didn't include it here because I don't have a use for it.
Quoted 7 lines
Quoted 7 lines
include/linux/clk-provider.h +0
-0@@ -177,11 +177,21 @@ struct clk_init_data {@@ -447,6 +457,9 @@ struct clk *__clk_lookup(const char *name); long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate, unsigned long *best_parent_rate,
Quoted 8 lines
include/linux/clk-provider.h struct clk *__clk_lookup(const char *name); · line 462
Quoted 4 lines
include/linux/clk-provider.h +3
-0struct clk **best_parent_p); +int clk_is_enabled_regmap (struct clk_hw *hw); +int clk_enable_regmap (struct clk_hw *hw); +void clk_disable_regmap (struct clk_hw *hw);Looking at the patch: Do you expect callers to remember whether a clock gate is backed by mmio or by regmap access, to call a different set of routines?
There are only regmap functions. I'm not sure where the choice is, but I expect the callers to know what they're doing. If you look at the rest of this series you'll see that I assign these functions directly to the clk_ops, or I call them from the enable/disable functions that need to do some status bit polling after the clock is enabled or disabled.
Quoted 2 lines
Should this not be hidden behind the
API and be transparent after clock registration?
I don't really understand what you mean by hiding it behind the API? What API? If we're talking about clk_register_gate() I think we would need to add a clk_register_regmap_gate() function because the reg argument is an __iomem pointer. It doesn't look like it can be transparent unless that pointer is reused as an offset. I don't attempt to do anything about that here though because I don't use the clk-gate.c code.
Quoted 3 lines
I'd suggest to fold regmap support into Tero Kristo's
ll_opsapproach, and to discuss this in his v12 thread.
Sure, I'll go look at and reply to that thread. How do you think I can benefit from Tero's patch series? From what I can tell ll_ops are a simplified version of regmap. Was regmap dismissed because the omap clock driver is not actually a platform driver? There doesn't seem to be any details in the thread(s) about why the ll_ops were proposed over regmap. From my perspective, using a regmap like is proposed in my patches is the better way to do this and it doesn't require any thing like ll_ops or clk_readl() to do it.
Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Re: [PATCH v4 03/15] clk: Add regmap core helpers for enable/disable/is_enabled
Quoted 20 lines · Stephen Boyd
Quoted 13 lines · Gerhard Sittig
Quoted 11 lines · Stephen Boyd
The clock framework already has support for simple gate clocks but if drivers want to use the gate clock functionality they need to wrap the gate clock in another struct and chain the ops by calling the gate ops from their own custom ops. Plus the gate clock implementation only supports MMIO accessors so other bus type clocks don't benefit from the potential code reuse. Add some simple regmap helpers for enable/disable/is_enabled that drivers can use as drop in replacements for their clock ops or as simple functions they call from their own custom ops. This is based on similar helps in the regulator framework.
Quoted 4 lines
The same comment applies as to the previous version. Is it useful to introduce copies of the gate handling while the difference in only in how the hardware registers get accessed?
Quoted 6 lines
I don't plan to use the
clk-gate.cimplementation because I need more than just a bit toggling clock. We can easily makeclk-gate.cuse these helpers if you're worried about the very small amount of code duplication between the two. I'd be glad to do that, I just didn't include it here because I don't have a use for it.
OK, then I simply misunderstood. From past threads I got the impression that your clock item was "a gate with regmap instead of mmio for hardware access, everything else being the same". The concerns were not so much about the size of duplicated code, but the "quality step" in starting duplication at all. But since I was wrong, nevermind.
Quoted 26 lines
Quoted 7 lines
Quoted 7 lines
include/linux/clk-provider.h +0
-0@@ -177,11 +177,21 @@ struct clk_init_data {@@ -447,6 +457,9 @@ struct clk *__clk_lookup(const char *name); long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate, unsigned long *best_parent_rate,Quoted 8 lines
include/linux/clk-provider.h struct clk *__clk_lookup(const char *name); · line 462
Quoted 4 lines
include/linux/clk-provider.h +3
-0struct clk **best_parent_p); +int clk_is_enabled_regmap (struct clk_hw *hw); +int clk_enable_regmap (struct clk_hw *hw); +void clk_disable_regmap (struct clk_hw *hw);Looking at the patch: Do you expect callers to remember whether a clock gate is backed by mmio or by regmap access, to call a different set of routines?
There are only regmap functions. I'm not sure where the choice is, but I expect the callers to know what they're doing. If you look at the rest of this series you'll see that I assign these functions directly to the
clk_ops, or I call them from the enable/disable functions that need to do some status bit polling after the clock is enabled or disabled.Quoted 2 lines
Should this not be hidden behind the
API and be transparent after clock registration?
Quoted 7 lines
I don't really understand what you mean by hiding it behind the API? What API? If we're talking about
clk_register_gate()I think we would need to add aclk_register_regmap_gate()function because the reg argument is an__iomempointer. It doesn't look like it can be transparent unless that pointer is reused as an offset. I don't attempt to do anything about that here though because I don't use theclk-gate.ccode.
See above, it's simple. I misunderstood, asked (in a previous thread), got no response, saw another submission, asked again. Now that you told me, it's clear I got something wrong. Thank you for telling me what I missed before.
virtually yours
Gerhard Sittig
Signature · 3 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr. 5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office at denx.de
PATCH v4 4/15 clk: Add set_rate_and_parent() op
In reply to Stephen BoydSome of Qualcomm's clocks can change their parent and rate at the same time with a single register write. Add support for this hardware to the common clock framework by adding a new set_rate_and_parent() op. When the clock framework determines that both the parent and the rate are going to change during clk_set_rate() it will call the .set_rate_and_parent() op if available and fall back to calling .set_parent() followed by .set_rate() otherwise.
--- Documentation/clk.txt | 3 ++ drivers/clk/clk.c | 78 +++++++++++++++++++++++++++++++++----------- include/linux/clk-provider.h | 15 +++++++++ 3 files changed, 77 insertions(+), 19 deletions(-)
Documentation/clk.txt +3 -0
@@ -77,6 +77,9 @@ the operations defined in clk.h: int (*set_parent)(struct clk_hw *hw, u8 index); u8 (*get_parent)(struct clk_hw *hw); int (*set_rate)(struct clk_hw *hw, unsigned long); + int (*set_rate_and_parent)(struct clk_hw *hw, + unsigned long rate, + unsigned long parent_rate, u8 index); void (*init)(struct clk_hw *hw); };
drivers/clk/clk.c +59 -19
116 lines not on this page · raw message
include/linux/clk-provider.h +15 -0
@@ -108,6 +108,18 @@ struct clk_hw;* which is likely helpful for most .set_rate implementation. * Returns 0 on success, -EERROR otherwise. * +* @set_rate_and_parent: Change the rate and the parent of this clock. The +* requested rate is specified by the second argument, which +* should typically be the return of .round_rate call. The +* third argument gives the parent rate which is likely helpful +* for most .set_rate_and_parent implementation. The fourth +* argument gives the parent index. This callback is optional (and +* unnecessary) for clocks with 0 or 1 parents as well as +* for clocks that can tolerate switching the rate and the parent +* separately via calls to .set_parent and .set_rate. +* Returns 0 on success, -EERROR otherwise. +* +* * The clk_enable/clk_disable and clk_prepare/clk_unprepare pairs allow * implementations to split any work between atomic (enable) and sleepable * (prepare) contexts. If enabling a clock requires code that might sleep,
@@ -139,6 +151,9 @@ struct clk_ops {u8 (*get_parent)(struct clk_hw *hw);int (*set_rate)(struct clk_hw *hw,unsigned long ,unsigned long ); +int (*set_rate_and_parent)(struct clk_hw *hw, +unsigned long rate, +unsigned long parent_rate,u8 index);void (*init)(struct clk_hw *hw); };
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
PATCH v4 5/15 clk: qcom: Add support for phase locked loops (PLLs)
In reply to Stephen BoydAdd support for Qualcomm's PLLs (phase locked loops). This is sufficient enough to be able to determine the rate the PLL is running at. We can add rate setting support later when it's needed.
--- drivers/clk/Kconfig | 2 + drivers/clk/Makefile | 1 + drivers/clk/qcom/Kconfig | 5 + drivers/clk/qcom/Makefile | 3 + drivers/clk/qcom/clk-pll.c | 222 +++++++++++++++++++++++++++++++++++++++++++++ drivers/clk/qcom/clk-pll.h | 65 +++++++++++++ 6 files changed, 298 insertions(+) create mode 100644 drivers/clk/qcom/Kconfig create mode 100644 drivers/clk/qcom/Makefile create mode 100644 drivers/clk/qcom/clk-pll.c create mode 100644 drivers/clk/qcom/clk-pll.h
drivers/clk/Kconfig +2 -0
@@ -107,6 +107,8 @@ config COMMON_CLK_KEYSTONE Supports clock drivers for Keystone based SOCs. These SOCs have local a power sleep control module that gate the clock to the IPs and PLLs. +source "drivers/clk/qcom/Kconfig" + endmenu source "drivers/clk/mvebu/Kconfig"
drivers/clk/Makefile +1 -0
@@ -21,6 +21,7 @@ obj-$(CONFIG_PLAT_SPEAR) += spear/ obj-$(CONFIG_ARCH_U300) += clk-u300.o obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/ obj-$(CONFIG_ARCH_SIRF) += clk-prima2.o +obj-$(CONFIG_COMMON_CLK_QCOM) += qcom/ obj-$(CONFIG_PLAT_ORION) += mvebu/ ifeq ($(CONFIG_COMMON_CLK), y) obj-$(CONFIG_ARCH_MMP) += mmp/
drivers/clk/qcom/Kconfig new file +5 -0
@@ -0,0 +1,5 @@ +config COMMON_CLK_QCOM + tristate "Support for Qualcomm's clock controllers" + depends on OF + select REGMAP_MMIO +
drivers/clk/qcom/Makefile new file +3 -0
@@ -0,0 +1,3 @@ +obj-$(CONFIG_COMMON_CLK_QCOM) += clk-qcom.o + +clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-pll.o
drivers/clk/qcom/clk-pll.c new file +222 -0
222 lines not on this page · raw message
drivers/clk/qcom/clk-pll.h new file +65 -0
65 lines not on this page · raw message
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
PATCH v4 6/15 clk: qcom: Add support for root clock generators (RCGs)
In reply to Stephen BoydAdd support for the root clock generators on Qualcomm devices. RCGs are highly customizable mux/divider/counter clocks that can be used to generate almost any rate desired given some input source that is faster than the desired rate.
--- drivers/clk/qcom/Makefile | 2 + drivers/clk/qcom/clk-rcg.c | 517 ++++++++++++++++++++++++++++++++++++++++++++ drivers/clk/qcom/clk-rcg.h | 157 ++++++++++++++ drivers/clk/qcom/clk-rcg2.c | 291 +++++++++++++++++++++++++ 4 files changed, 967 insertions(+) create mode 100644 drivers/clk/qcom/clk-rcg.c create mode 100644 drivers/clk/qcom/clk-rcg.h create mode 100644 drivers/clk/qcom/clk-rcg2.c
drivers/clk/qcom/Makefile +2 -0
@@ -1,3 +1,5 @@ obj-$(CONFIG_COMMON_CLK_QCOM) += clk-qcom.o clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-pll.o +clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-rcg.o +clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-rcg2.o
drivers/clk/qcom/clk-rcg.c new file +517 -0
517 lines not on this page · raw message
drivers/clk/qcom/clk-rcg.h new file +157 -0
157 lines not on this page · raw message
drivers/clk/qcom/clk-rcg2.c new file +291 -0
291 lines not on this page · raw message
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
PATCH v4 7/15 clk: qcom: Add support for branches/gate clocks
In reply to Stephen Boyd--- drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/clk-branch.c | 159 ++++++++++++++++++++++++++++++++++++++++++ drivers/clk/qcom/clk-branch.h | 53 ++++++++++++++ 3 files changed, 213 insertions(+) create mode 100644 drivers/clk/qcom/clk-branch.c create mode 100644 drivers/clk/qcom/clk-branch.h
drivers/clk/qcom/Makefile +1 -0
@@ -3,3 +3,4 @@ obj-$(CONFIG_COMMON_CLK_QCOM) += clk-qcom.o clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-pll.o clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-rcg.o clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-rcg2.o +clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-branch.o
drivers/clk/qcom/clk-branch.c new file +159 -0
159 lines not on this page · raw message
drivers/clk/qcom/clk-branch.h new file +53 -0
53 lines not on this page · raw message
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
PATCH v4 8/15 clk: qcom: Add reset controller support
In reply to Stephen BoydReset controllers and clock controllers are combined into one IP block on Qualcomm chipsets. Usually a reset signal is associated with each clock branch but sometimes a reset signal is associated with a handful of clocks. Either way the register interface is the same; set a bit to assert a reset and clear a bit to deassert a reset. Add support for these types of resets signals.
--- drivers/clk/qcom/Kconfig | 2 +- drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/reset.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++ drivers/clk/qcom/reset.h | 37 ++++++++++++++++++++++++++++ 4 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 drivers/clk/qcom/reset.c create mode 100644 drivers/clk/qcom/reset.h
drivers/clk/qcom/Kconfig +1 -1
@@ -2,4 +2,4 @@ config COMMON_CLK_QCOM tristate "Support for Qualcomm's clock controllers" depends on OF select REGMAP_MMIO - + select RESET_CONTROLLER
drivers/clk/qcom/Makefile +1 -0
@@ -4,3 +4,4 @@ clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-pll.o clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-rcg.o clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-rcg2.o clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-branch.o +clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += reset.o
drivers/clk/qcom/reset.c new file +63 -0
63 lines not on this page · raw message
drivers/clk/qcom/reset.h new file +37 -0
@@ -0,0 +1,37 @@ +/* +* Copyright (c) 2013, 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 __MSM_CLK_RESET_H__ +#define __MSM_CLK_RESET_H__ + +#include <linux/reset-controller.h> + +struct qcom_reset_map { +unsigned int reg; +u8 bit; +}; + +struct regmap ; + +struct qcom_reset_controller { +const struct qcom_reset_map *reset_map; +struct regmap *regmap; +struct reset_controller_dev rcdev; +}; + +#define to_qcom_reset_controller (r) \ + container_of(r, struct qcom_reset_controller, rcdev); + +extern struct reset_control_ops qcom_reset_ops; + +#endif
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
PATCH v4 9/15 clk: qcom: Add support for MSM8960's global clock controller (GCC)
In reply to Stephen BoydAdd a driver for the global clock controller found on MSM8960 based platforms. This should allow most non-multimedia device drivers to probe and control their clocks.
--- drivers/clk/qcom/Kconfig | 8 + drivers/clk/qcom/Makefile | 2 + drivers/clk/qcom/gcc-msm8960.c | 2992 ++++++++++++++++++++++++++ include/dt-bindings/clock/qcom,gcc-msm8960.h | 313 +++ include/dt-bindings/reset/qcom,gcc-msm8960.h | 118 + 5 files changed, 3433 insertions(+) create mode 100644 drivers/clk/qcom/gcc-msm8960.c create mode 100644 include/dt-bindings/clock/qcom,gcc-msm8960.h create mode 100644 include/dt-bindings/reset/qcom,gcc-msm8960.h
drivers/clk/qcom/Kconfig +8 -0
@@ -3,3 +3,11 @@ config COMMON_CLK_QCOM depends on OF select REGMAP_MMIO select RESET_CONTROLLER + +config MSM_GCC_8960 + tristate "MSM8960 Global Clock Controller" + depends on COMMON_CLK_QCOM + help + Support for the global clock controller on msm8960 devices. + Say Y if you want to use peripheral devices such as UART, SPI, + i2c, USB, SD/eMMC, SATA, PCIe, etc.
drivers/clk/qcom/Makefile +2 -0
@@ -5,3 +5,5 @@ clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-rcg.o clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-rcg2.o clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-branch.o clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += reset.o + +obj-$(CONFIG_MSM_GCC_8960) += gcc-msm8960.o
drivers/clk/qcom/gcc-msm8960.c new file +2992 -0
2,984 lines not on this page · raw message
include/dt-bindings/clock/qcom,gcc-msm8960.h new file +313 -0
313 lines not on this page · raw message
include/dt-bindings/reset/qcom,gcc-msm8960.h new file +118 -0
118 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
Part of the diff is not shown here. View the raw message.
PATCH v4 10/15 clk: qcom: Add support for MSM8960's multimedia clock controller (MMCC)
In reply to Stephen BoydAdd a driver for the multimedia clock controller found on MSM 8960 based platforms. This should allow multimedia device drivers to probe and control their clocks.
--- drivers/clk/qcom/Kconfig | 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/mmcc-msm8960.c | 2320 +++++++++++++++++++++++++ include/dt-bindings/clock/qcom,mmcc-msm8960.h | 137 ++ include/dt-bindings/reset/qcom,mmcc-msm8960.h | 93 + 5 files changed, 2560 insertions(+) create mode 100644 drivers/clk/qcom/mmcc-msm8960.c create mode 100644 include/dt-bindings/clock/qcom,mmcc-msm8960.h create mode 100644 include/dt-bindings/reset/qcom,mmcc-msm8960.h
drivers/clk/qcom/Kconfig +9 -0
@@ -11,3 +11,12 @@ config MSM_GCC_8960 Support for the global clock controller on msm8960 devices. Say Y if you want to use peripheral devices such as UART, SPI, i2c, USB, SD/eMMC, SATA, PCIe, etc. + +config MSM_MMCC_8960 + tristate "MSM8960 Multimedia Clock Controller" + select MSM_GCC_8960 + depends on COMMON_CLK_QCOM + help + Support for the multimedia clock controller on msm8960 devices. + Say Y if you want to support multimedia devices such as display, + graphics, video encode/decode, camera, etc.
drivers/clk/qcom/Makefile +1 -0
@@ -7,3 +7,4 @@ clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-branch.o clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += reset.o obj-$(CONFIG_MSM_GCC_8960) += gcc-msm8960.o +obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o
drivers/clk/qcom/mmcc-msm8960.c new file +2320 -0
2,320 lines not on this page · raw message
include/dt-bindings/clock/qcom,mmcc-msm8960.h new file +137 -0
137 lines not on this page · raw message
include/dt-bindings/reset/qcom,mmcc-msm8960.h new file +93 -0
93 lines not on this page · raw message
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
PATCH v4 11/15 clk: qcom: Add support for MSM8974's global clock controller (GCC)
In reply to Stephen BoydAdd a driver for the global clock controller found on MSM 8974 based platforms. This should allow most non-multimedia device drivers to probe and control their clocks.
--- drivers/clk/qcom/Kconfig | 8 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/gcc-msm8974.c | 2693 ++++++++++++++++++++++++++ include/dt-bindings/clock/qcom,gcc-msm8974.h | 320 +++ include/dt-bindings/reset/qcom,gcc-msm8974.h | 96 + 5 files changed, 3118 insertions(+) create mode 100644 drivers/clk/qcom/gcc-msm8974.c create mode 100644 include/dt-bindings/clock/qcom,gcc-msm8974.h create mode 100644 include/dt-bindings/reset/qcom,gcc-msm8974.h
drivers/clk/qcom/Kconfig +8 -0
@@ -20,3 +20,11 @@ config MSM_MMCC_8960 Support for the multimedia clock controller on msm8960 devices. Say Y if you want to support multimedia devices such as display, graphics, video encode/decode, camera, etc. + +config MSM_GCC_8974 + tristate "MSM8974 Global Clock Controller" + depends on COMMON_CLK_QCOM + help + Support for the global clock controller on msm8974 devices. + Say Y if you want to use peripheral devices such as UART, SPI, + i2c, USB, SD/eMMC, SATA, PCIe, etc.
drivers/clk/qcom/Makefile +1 -0
@@ -7,4 +7,5 @@ clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-branch.o clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += reset.o obj-$(CONFIG_MSM_GCC_8960) += gcc-msm8960.o +obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o
drivers/clk/qcom/gcc-msm8974.c new file +2693 -0
2,693 lines not on this page · raw message
include/dt-bindings/clock/qcom,gcc-msm8974.h new file +320 -0
291 lines not on this page · raw message
include/dt-bindings/reset/qcom,gcc-msm8974.h new file +96 -0
96 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
Part of the diff is not shown here. View the raw message.
PATCH v4 12/15 clk: qcom: Add support for MSM8974's multimedia clock controller (MMCC)
In reply to Stephen BoydAdd a driver for the global clock controller found on MSM 8974 based platforms. This should allow most multimedia device drivers to probe and control their clocks.
--- drivers/clk/qcom/Kconfig | 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/mmcc-msm8974.c | 2624 +++++++++++++++++++++++++ include/dt-bindings/clock/qcom,mmcc-msm8974.h | 161 ++ include/dt-bindings/reset/qcom,mmcc-msm8974.h | 62 + 5 files changed, 2857 insertions(+) create mode 100644 drivers/clk/qcom/mmcc-msm8974.c create mode 100644 include/dt-bindings/clock/qcom,mmcc-msm8974.h create mode 100644 include/dt-bindings/reset/qcom,mmcc-msm8974.h
drivers/clk/qcom/Kconfig +9 -0
@@ -28,3 +28,12 @@ config MSM_GCC_8974 Support for the global clock controller on msm8974 devices. Say Y if you want to use peripheral devices such as UART, SPI, i2c, USB, SD/eMMC, SATA, PCIe, etc. + +config MSM_MMCC_8974 + tristate "MSM8974 Multimedia Clock Controller" + select MSM_GCC_8974 + depends on COMMON_CLK_QCOM + help + 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.
drivers/clk/qcom/Makefile +1 -0
@@ -9,3 +9,4 @@ clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += reset.o obj-$(CONFIG_MSM_GCC_8960) += gcc-msm8960.o obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o +obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o
drivers/clk/qcom/mmcc-msm8974.c new file +2624 -0
2,624 lines not on this page · raw message
include/dt-bindings/clock/qcom,mmcc-msm8974.h new file +161 -0
161 lines not on this page · raw message
include/dt-bindings/reset/qcom,mmcc-msm8974.h new file +62 -0
62 lines not on this page · raw message
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
PATCH v4 13/15 clk: qcom: Add support for MSM8660's global clock controller (GCC)
In reply to Stephen BoydAdd a driver for the global clock controller found on MSM8660 based platforms. This should allow most non-multimedia device drivers to probe and control their clocks.
--- drivers/clk/qcom/Kconfig | 8 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/gcc-msm8660.c | 2818 ++++++++++++++++++++++++++ include/dt-bindings/clock/qcom,gcc-msm8660.h | 276 +++ include/dt-bindings/reset/qcom,gcc-msm8660.h | 134 ++ 5 files changed, 3237 insertions(+) create mode 100644 drivers/clk/qcom/gcc-msm8660.c create mode 100644 include/dt-bindings/clock/qcom,gcc-msm8660.h create mode 100644 include/dt-bindings/reset/qcom,gcc-msm8660.h
drivers/clk/qcom/Kconfig +8 -0
@@ -4,6 +4,14 @@ config COMMON_CLK_QCOM select REGMAP_MMIO select RESET_CONTROLLER +config MSM_GCC_8660 + tristate "MSM8660 Global Clock Controller" + depends on COMMON_CLK_QCOM + help + Support for the global clock controller on msm8660 devices. + Say Y if you want to use peripheral devices such as UART, SPI, + i2c, USB, SD/eMMC, etc. + config MSM_GCC_8960 tristate "MSM8960 Global Clock Controller" depends on COMMON_CLK_QCOM
drivers/clk/qcom/Makefile +1 -0
@@ -6,6 +6,7 @@ clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-rcg2.o clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-branch.o clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += reset.o +obj-$(CONFIG_MSM_GCC_8660) += gcc-msm8660.o obj-$(CONFIG_MSM_GCC_8960) += gcc-msm8960.o obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o
drivers/clk/qcom/gcc-msm8660.c new file +2818 -0
2,818 lines not on this page · raw message
include/dt-bindings/clock/qcom,gcc-msm8660.h new file +276 -0
161 lines not on this page · raw message
include/dt-bindings/reset/qcom,gcc-msm8660.h new file +134 -0
134 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
Part of the diff is not shown here. View the raw message.
PATCH v4 14/15 devicetree: bindings: Document qcom,gcc
In reply to Stephen BoydDocument the global clock controller found on MSM devices.
--- .../devicetree/bindings/clock/qcom,gcc.txt | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,gcc.txt
Documentation/devicetree/bindings/clock/qcom,gcc.txt new file +21 -0
@@ -0,0 +1,21 @@ +Qualcomm Global Clock & Reset Controller Binding +------------------------------------------------ + +Required properties : +- compatible : shall contain only one of the following: + + "qcom,gcc-msm8660" + "qcom,gcc-msm8960" + "qcom,gcc-msm8974" + +- reg : shall contain base register location and length +- #clock-cells : shall contain 1 +- #reset-cells : shall contain 1 + +Example: + clock-controller at 900000 { + compatible = "qcom,gcc-msm8960"; + reg = <0x900000 0x4000>; + #clock-cells = <1>; + #reset-cells = <1>; + };
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
PATCH v4 15/15 devicetree: bindings: Document qcom,mmcc
In reply to Stephen BoydDocument the multimedia clock controller found on MSM devices
--- .../devicetree/bindings/clock/qcom,mmcc.txt | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,mmcc.txt
Documentation/devicetree/bindings/clock/qcom,mmcc.txt new file +21 -0
@@ -0,0 +1,21 @@ +Qualcomm Multimedia Clock & Reset Controller Binding +---------------------------------------------------- + +Required properties : +- compatible : shall contain only one of the following: + + "qcom,mmcc-msm8660" + "qcom,mmcc-msm8960" + "qcom,mmcc-msm8974" + +- reg : shall contain base register location and length +- #clock-cells : shall contain 1 +- #reset-cells : shall contain 1 + +Example: + clock-controller at 4000000 { + compatible = "qcom,mmcc-msm8960"; + reg = <0x4000000 0x1000>; + #clock-cells = <1>; + #reset-cells = <1>; + };
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation