From: Igal Liberman igal.liber...@freescale.com
This patch depends on the following patches:
https://patchwork.ozlabs.org/patch/461151/
https://patchwork.ozlabs.org/patch/461155/
This patche is described by the following binding document update:
https://patchwork.ozlabs.org/patch/461166/
v3: Updated commit message
v2: - Added clock maintainers
- Cached FMan clock parent during initialization
- Register the clock after checking if the hardware exists
- updated error messages
Signed-off-by: Igal Liberman igal.liber...@freescale.com
---
drivers/clk/clk-qoriq.c | 208 +++
1 file changed, 208 insertions(+)
diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c
index cda90a9..d588e90 100644
--- a/drivers/clk/clk-qoriq.c
+++ b/drivers/clk/clk-qoriq.c
@@ -19,6 +19,8 @@
#include linux/of.h
#include linux/slab.h
+#include asm/fsl_guts.h
+
struct cmux_clk {
struct clk_hw hw;
void __iomem *reg;
@@ -155,6 +157,211 @@ err_name:
kfree(parent_names);
}
+/* Table for matching compatible strings, for device tree
+ * guts node, for QorIQ SOCs.
+ * fsl,qoriq-device-config-2.0 corresponds to T4 B4
+ * SOCs. For the older SOCs fsl,qoriq-device-config-1.0
+ * string would be used.
+ */
+
+static const struct of_device_id guts_device_ids[] = {
+ { .compatible = fsl,qoriq-device-config-1.0, },
+ { .compatible = fsl,qoriq-device-config-2.0, },
+ {}
+};
+
+/* P2, P3, P4, P5 */
+#define FM1_CLK_SEL_SHIFT 30
+#define FM1_CLK_SELBIT(FM1_CLK_SEL_SHIFT)
+#define FM2_CLK_SEL_SHIFT 29
+#define FM2_CLK_SELBIT(FM2_CLK_SEL_SHIFT)
+#define HWA_ASYNC_DIV_SHIFT26
+#define HWA_ASYNC_DIV BIT(HWA_ASYNC_DIV_SHIFT)
+
+/* B4, T2 */
+#define HWA_CGA_M1_CLK_SEL_SHIFT 29
+#define HWA_CGA_M1_CLK_SEL (BIT(HWA_CGA_M1_CLK_SEL_SHIFT + 2) |\
+BIT(HWA_CGA_M1_CLK_SEL_SHIFT + 1) |\
+BIT(HWA_CGA_M1_CLK_SEL_SHIFT))
+
+/* T4240 */
+#define HWA_CGB_M1_CLK_SEL_SHIFT 26
+#define HWA_CGB_M1_CLK_SEL (BIT(HWA_CGB_M1_CLK_SEL_SHIFT + 2) |\
+BIT(HWA_CGB_M1_CLK_SEL_SHIFT + 1) |\
+BIT(HWA_CGB_M1_CLK_SEL_SHIFT))
+#define HWA_CGB_M2_CLK_SEL_SHIFT 3
+#define HWA_CGB_M2_CLK_SEL (BIT(HWA_CGB_M2_CLK_SEL_SHIFT + 2) |\
+BIT(HWA_CGB_M2_CLK_SEL_SHIFT + 1) |\
+BIT(HWA_CGB_M2_CLK_SEL_SHIFT))
+
+static u8 get_fm_clk_parent(struct clk_hw *hw)
+{
+ return hw-init-flags;
+}
+
+static const struct clk_ops fm_clk_ops = {
+ .get_parent = get_fm_clk_parent,
+};
+
+static int get_fm_clk_idx(int fm_id, int *fm_clk_idx)
+{
+ struct ccsr_guts __iomem *guts_regs = NULL;
+ struct device_node *guts;
+ uint32_t reg = 0;
+ int clk_src = 0;
+
+ guts = of_find_matching_node(NULL, guts_device_ids);
+ if (!guts) {
+ pr_err(could not find GUTS node\n);
+ return -ENODEV;
+ }
+
+ guts_regs = of_iomap(guts, 0);
+ of_node_put(guts);
+ if (!guts_regs) {
+ pr_err(ioremap of GUTS node failed\n);
+ return -ENODEV;
+ }
+
+ if (of_device_is_compatible(guts, fsl,p1023-guts) ||
+ of_device_is_compatible(guts, fsl,t1040-device-config)) {
+ /* P1023 and T1040 have only one optional clock source */
+ *fm_clk_idx = 0;
+ } else if (of_device_is_compatible(guts, fsl,p2041-device-config) ||
+ of_device_is_compatible(guts, fsl,p3041-device-config) ||
+ of_device_is_compatible(guts, fsl,p4080-device-config)) {
+ /* Read RCW*/
+ reg = ioread32be(guts_regs-rcwsr[7]);
+
+ if (fm_id == 0)
+ *fm_clk_idx = (reg FM1_CLK_SEL)
+ FM1_CLK_SEL_SHIFT;
+ else
+ *fm_clk_idx = (reg FM2_CLK_SEL)
+ FM2_CLK_SEL_SHIFT;
+ } else if (of_device_is_compatible(guts, fsl,p5020-device-config) ||
+ of_device_is_compatible(guts, fsl,p5040-device-config)) {
+ /* Read RCW */
+ reg = ioread32be(guts_regs-rcwsr[7]);
+
+ if (fm_id == 0)
+ clk_src = (reg FM1_CLK_SEL) FM1_CLK_SEL_SHIFT;
+ else
+ clk_src = (reg FM2_CLK_SEL) FM2_CLK_SEL_SHIFT;
+
+ if (clk_src == 0) {
+ *fm_clk_idx = 0;
+ } else {
+ clk_src = (reg HWA_ASYNC_DIV) HWA_ASYNC_DIV_SHIFT;
+ *fm_clk_idx = clk_src + 1;
+