clk-scu.c (5392c5de096a1cad7cc06265a8cbf18de2da22c7) clk-scu.c (5964012ce37e66d2588a9bc82f7184a008851cac)
1// SPDX-License-Identifier: GPL-2.0+
2/*
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright 2018 NXP
3 * Copyright 2018-2021 NXP
4 * Dong Aisheng <aisheng.dong@nxp.com>
5 */
6
7#include <dt-bindings/firmware/imx/rsrc.h>
8#include <linux/arm-smccc.h>
4 * Dong Aisheng <aisheng.dong@nxp.com>
5 */
6
7#include <dt-bindings/firmware/imx/rsrc.h>
8#include <linux/arm-smccc.h>
9#include <linux/bsearch.h>
9#include <linux/clk-provider.h>
10#include <linux/err.h>
11#include <linux/of_platform.h>
12#include <linux/platform_device.h>
13#include <linux/pm_domain.h>
14#include <linux/pm_runtime.h>
15#include <linux/slab.h>
16
17#include "clk-scu.h"
18
19#define IMX_SIP_CPUFREQ 0xC2000001
20#define IMX_SIP_SET_CPUFREQ 0x00
21
22static struct imx_sc_ipc *ccm_ipc_handle;
23static struct device_node *pd_np;
24static struct platform_driver imx_clk_scu_driver;
10#include <linux/clk-provider.h>
11#include <linux/err.h>
12#include <linux/of_platform.h>
13#include <linux/platform_device.h>
14#include <linux/pm_domain.h>
15#include <linux/pm_runtime.h>
16#include <linux/slab.h>
17
18#include "clk-scu.h"
19
20#define IMX_SIP_CPUFREQ 0xC2000001
21#define IMX_SIP_SET_CPUFREQ 0x00
22
23static struct imx_sc_ipc *ccm_ipc_handle;
24static struct device_node *pd_np;
25static struct platform_driver imx_clk_scu_driver;
26static const struct imx_clk_scu_rsrc_table *rsrc_table;
25
26struct imx_scu_clk_node {
27 const char *name;
28 u32 rsrc;
29 u8 clk_type;
30 const char * const *parents;
31 int num_parents;
32

--- 129 unchanged lines hidden (view full) ---

162 u8 autog;
163} __packed __aligned(4);
164
165static inline struct clk_scu *to_clk_scu(struct clk_hw *hw)
166{
167 return container_of(hw, struct clk_scu, hw);
168}
169
27
28struct imx_scu_clk_node {
29 const char *name;
30 u32 rsrc;
31 u8 clk_type;
32 const char * const *parents;
33 int num_parents;
34

--- 129 unchanged lines hidden (view full) ---

164 u8 autog;
165} __packed __aligned(4);
166
167static inline struct clk_scu *to_clk_scu(struct clk_hw *hw)
168{
169 return container_of(hw, struct clk_scu, hw);
170}
171
170int imx_clk_scu_init(struct device_node *np)
172static inline int imx_scu_clk_search_cmp(const void *rsrc, const void *rsrc_p)
171{
173{
174 return *(u32 *)rsrc - *(u32 *)rsrc_p;
175}
176
177static bool imx_scu_clk_is_valid(u32 rsrc_id)
178{
179 void *p;
180
181 if (!rsrc_table)
182 return true;
183
184 p = bsearch(&rsrc_id, rsrc_table->rsrc, rsrc_table->num,
185 sizeof(rsrc_table->rsrc[0]), imx_scu_clk_search_cmp);
186
187 return p != NULL;
188}
189
190int imx_clk_scu_init(struct device_node *np,
191 const struct imx_clk_scu_rsrc_table *data)
192{
172 u32 clk_cells;
173 int ret, i;
174
175 ret = imx_scu_get_handle(&ccm_ipc_handle);
176 if (ret)
177 return ret;
178
179 of_property_read_u32(np, "#clock-cells", &clk_cells);
180
181 if (clk_cells == 2) {
182 for (i = 0; i < IMX_SC_R_LAST; i++)
183 INIT_LIST_HEAD(&imx_scu_clks[i]);
184
185 /* pd_np will be used to attach power domains later */
186 pd_np = of_find_compatible_node(NULL, NULL, "fsl,scu-pd");
187 if (!pd_np)
188 return -EINVAL;
193 u32 clk_cells;
194 int ret, i;
195
196 ret = imx_scu_get_handle(&ccm_ipc_handle);
197 if (ret)
198 return ret;
199
200 of_property_read_u32(np, "#clock-cells", &clk_cells);
201
202 if (clk_cells == 2) {
203 for (i = 0; i < IMX_SC_R_LAST; i++)
204 INIT_LIST_HEAD(&imx_scu_clks[i]);
205
206 /* pd_np will be used to attach power domains later */
207 pd_np = of_find_compatible_node(NULL, NULL, "fsl,scu-pd");
208 if (!pd_np)
209 return -EINVAL;
210
211 rsrc_table = data;
189 }
190
191 return platform_driver_register(&imx_clk_scu_driver);
192}
193
194/*
195 * clk_scu_recalc_rate - Get clock rate for a SCU clock
196 * @hw: clock to get rate for

--- 381 unchanged lines hidden (view full) ---

578 .rsrc = rsrc_id,
579 .clk_type = clk_type,
580 .parents = parents,
581 .num_parents = num_parents,
582 };
583 struct platform_device *pdev;
584 int ret;
585
212 }
213
214 return platform_driver_register(&imx_clk_scu_driver);
215}
216
217/*
218 * clk_scu_recalc_rate - Get clock rate for a SCU clock
219 * @hw: clock to get rate for

--- 381 unchanged lines hidden (view full) ---

601 .rsrc = rsrc_id,
602 .clk_type = clk_type,
603 .parents = parents,
604 .num_parents = num_parents,
605 };
606 struct platform_device *pdev;
607 int ret;
608
609 if (!imx_scu_clk_is_valid(rsrc_id))
610 return ERR_PTR(-EINVAL);
611
586 pdev = platform_device_alloc(name, PLATFORM_DEVID_NONE);
587 if (!pdev) {
588 pr_err("%s: failed to allocate scu clk dev rsrc %d type %d\n",
589 name, rsrc_id, clk_type);
590 return ERR_PTR(-ENOMEM);
591 }
592
593 ret = platform_device_add_data(pdev, &clk, sizeof(clk));

--- 151 unchanged lines hidden (view full) ---

745
746 if (rsrc_id >= IMX_SC_R_LAST || gpr_id >= IMX_SC_C_LAST)
747 return ERR_PTR(-EINVAL);
748
749 clk_node = kzalloc(sizeof(*clk_node), GFP_KERNEL);
750 if (!clk_node)
751 return ERR_PTR(-ENOMEM);
752
612 pdev = platform_device_alloc(name, PLATFORM_DEVID_NONE);
613 if (!pdev) {
614 pr_err("%s: failed to allocate scu clk dev rsrc %d type %d\n",
615 name, rsrc_id, clk_type);
616 return ERR_PTR(-ENOMEM);
617 }
618
619 ret = platform_device_add_data(pdev, &clk, sizeof(clk));

--- 151 unchanged lines hidden (view full) ---

771
772 if (rsrc_id >= IMX_SC_R_LAST || gpr_id >= IMX_SC_C_LAST)
773 return ERR_PTR(-EINVAL);
774
775 clk_node = kzalloc(sizeof(*clk_node), GFP_KERNEL);
776 if (!clk_node)
777 return ERR_PTR(-ENOMEM);
778
779 if (!imx_scu_clk_is_valid(rsrc_id))
780 return ERR_PTR(-EINVAL);
781
753 clk = kzalloc(sizeof(*clk), GFP_KERNEL);
754 if (!clk) {
755 kfree(clk_node);
756 return ERR_PTR(-ENOMEM);
757 }
758
759 clk->rsrc_id = rsrc_id;
760 clk->gpr_id = gpr_id;

--- 33 unchanged lines hidden ---
782 clk = kzalloc(sizeof(*clk), GFP_KERNEL);
783 if (!clk) {
784 kfree(clk_node);
785 return ERR_PTR(-ENOMEM);
786 }
787
788 clk->rsrc_id = rsrc_id;
789 clk->gpr_id = gpr_id;

--- 33 unchanged lines hidden ---