Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Zynq UltraScale+ MPSoC clock controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *  Copyright (C) 2016-2019 Xilinx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Based on drivers/clk/zynq/clkc.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/bitfield.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/of_platform.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include "clk-zynqmp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #define MAX_PARENT			100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #define MAX_NODES			6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define MAX_NAME_LEN			50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) /* Flags for parents */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define PARENT_CLK_SELF			0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define PARENT_CLK_NODE1		1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define PARENT_CLK_NODE2		2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define PARENT_CLK_NODE3		3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define PARENT_CLK_NODE4		4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define PARENT_CLK_EXTERNAL		5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define END_OF_CLK_NAME			"END_OF_CLK"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define END_OF_TOPOLOGY_NODE		1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define END_OF_PARENTS			1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define RESERVED_CLK_NAME		""
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #define CLK_GET_NAME_RESP_LEN		16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define CLK_GET_TOPOLOGY_RESP_WORDS	3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define CLK_GET_PARENTS_RESP_WORDS	3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #define CLK_GET_ATTR_RESP_WORDS		1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) enum clk_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	CLK_TYPE_OUTPUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	CLK_TYPE_EXTERNAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)  * struct clock_parent - Clock parent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)  * @name:	Parent name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)  * @id:		Parent clock ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51)  * @flag:	Parent flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) struct clock_parent {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	char name[MAX_NAME_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	u32 flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60)  * struct zynqmp_clock - Clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61)  * @clk_name:		Clock name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62)  * @valid:		Validity flag of clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63)  * @type:		Clock type (Output/External)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64)  * @node:		Clock topology nodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65)  * @num_nodes:		Number of nodes present in topology
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66)  * @parent:		Parent of clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)  * @num_parents:	Number of parents of clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68)  * @clk_id:		Clock id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) struct zynqmp_clock {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	char clk_name[MAX_NAME_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	u32 valid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	enum clk_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	struct clock_topology node[MAX_NODES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	u32 num_nodes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	struct clock_parent parent[MAX_PARENT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	u32 num_parents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	u32 clk_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) struct name_resp {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	char name[CLK_GET_NAME_RESP_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) struct topology_resp {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) #define CLK_TOPOLOGY_TYPE		GENMASK(3, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) #define CLK_TOPOLOGY_CUSTOM_TYPE_FLAGS	GENMASK(7, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) #define CLK_TOPOLOGY_FLAGS		GENMASK(23, 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) #define CLK_TOPOLOGY_TYPE_FLAGS		GENMASK(31, 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	u32 topology[CLK_GET_TOPOLOGY_RESP_WORDS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) struct parents_resp {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) #define NA_PARENT			0xFFFFFFFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) #define DUMMY_PARENT			0xFFFFFFFE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) #define CLK_PARENTS_ID			GENMASK(15, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) #define CLK_PARENTS_FLAGS		GENMASK(31, 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	u32 parents[CLK_GET_PARENTS_RESP_WORDS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct attr_resp {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define CLK_ATTR_VALID			BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define CLK_ATTR_TYPE			BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define CLK_ATTR_NODE_INDEX		GENMASK(13, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define CLK_ATTR_NODE_TYPE		GENMASK(19, 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define CLK_ATTR_NODE_SUBCLASS		GENMASK(25, 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define CLK_ATTR_NODE_CLASS		GENMASK(31, 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	u32 attr[CLK_GET_ATTR_RESP_WORDS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static const char clk_type_postfix[][10] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	[TYPE_INVALID] = "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	[TYPE_MUX] = "_mux",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	[TYPE_GATE] = "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	[TYPE_DIV1] = "_div1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	[TYPE_DIV2] = "_div2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	[TYPE_FIXEDFACTOR] = "_ff",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	[TYPE_PLL] = ""
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static struct clk_hw *(* const clk_topology[]) (const char *name, u32 clk_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 					const char * const *parents,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 					u8 num_parents,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 					const struct clock_topology *nodes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 					= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	[TYPE_INVALID] = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	[TYPE_MUX] = zynqmp_clk_register_mux,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	[TYPE_PLL] = zynqmp_clk_register_pll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	[TYPE_FIXEDFACTOR] = zynqmp_clk_register_fixed_factor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	[TYPE_DIV1] = zynqmp_clk_register_divider,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	[TYPE_DIV2] = zynqmp_clk_register_divider,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	[TYPE_GATE] = zynqmp_clk_register_gate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) static struct zynqmp_clock *clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static struct clk_hw_onecell_data *zynqmp_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static unsigned int clock_max_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)  * zynqmp_is_valid_clock() - Check whether clock is valid or not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)  * @clk_id:	Clock index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)  * Return: 1 if clock is valid, 0 if clock is invalid else error code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) static inline int zynqmp_is_valid_clock(u32 clk_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	if (clk_id >= clock_max_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	return clock[clk_id].valid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)  * zynqmp_get_clock_name() - Get name of clock from Clock index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)  * @clk_id:	Clock index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)  * @clk_name:	Name of clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)  * Return: 0 on success else error code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static int zynqmp_get_clock_name(u32 clk_id, char *clk_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	ret = zynqmp_is_valid_clock(clk_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	if (ret == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		strncpy(clk_name, clock[clk_id].clk_name, MAX_NAME_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	return ret == 0 ? -EINVAL : ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)  * zynqmp_get_clock_type() - Get type of clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)  * @clk_id:	Clock index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)  * @type:	Clock type: CLK_TYPE_OUTPUT or CLK_TYPE_EXTERNAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)  * Return: 0 on success else error code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static int zynqmp_get_clock_type(u32 clk_id, u32 *type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	ret = zynqmp_is_valid_clock(clk_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	if (ret == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 		*type = clock[clk_id].type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	return ret == 0 ? -EINVAL : ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)  * zynqmp_pm_clock_get_num_clocks() - Get number of clocks in system
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)  * @nclocks:	Number of clocks in system/board.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)  * Call firmware API to get number of clocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)  * Return: 0 on success else error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) static int zynqmp_pm_clock_get_num_clocks(u32 *nclocks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	struct zynqmp_pm_query_data qdata = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	u32 ret_payload[PAYLOAD_ARG_CNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	qdata.qid = PM_QID_CLOCK_GET_NUM_CLOCKS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	ret = zynqmp_pm_query_data(qdata, ret_payload);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	*nclocks = ret_payload[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)  * zynqmp_pm_clock_get_name() - Get the name of clock for given id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)  * @clock_id:	ID of the clock to be queried
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)  * @response:	Name of the clock with the given id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)  * This function is used to get name of clock specified by given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)  * clock ID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)  * Return: Returns 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) static int zynqmp_pm_clock_get_name(u32 clock_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 				    struct name_resp *response)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	struct zynqmp_pm_query_data qdata = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	u32 ret_payload[PAYLOAD_ARG_CNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	qdata.qid = PM_QID_CLOCK_GET_NAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	qdata.arg1 = clock_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	zynqmp_pm_query_data(qdata, ret_payload);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	memcpy(response, ret_payload, sizeof(*response));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)  * zynqmp_pm_clock_get_topology() - Get the topology of clock for given id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)  * @clock_id:	ID of the clock to be queried
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)  * @index:	Node index of clock topology
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)  * @response:	Buffer used for the topology response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)  * This function is used to get topology information for the clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)  * specified by given clock ID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)  * This API will return 3 node of topology with a single response. To get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)  * other nodes, master should call same API in loop with new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)  * index till error is returned. E.g First call should have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)  * index 0 which will return nodes 0,1 and 2. Next call, index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)  * should be 3 which will return nodes 3,4 and 5 and so on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)  * Return: 0 on success else error+reason
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) static int zynqmp_pm_clock_get_topology(u32 clock_id, u32 index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 					struct topology_resp *response)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	struct zynqmp_pm_query_data qdata = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	u32 ret_payload[PAYLOAD_ARG_CNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	qdata.qid = PM_QID_CLOCK_GET_TOPOLOGY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	qdata.arg1 = clock_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	qdata.arg2 = index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	ret = zynqmp_pm_query_data(qdata, ret_payload);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	memcpy(response, &ret_payload[1], sizeof(*response));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)  * zynqmp_clk_register_fixed_factor() - Register fixed factor with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)  *					clock framework
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)  * @name:		Name of this clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)  * @clk_id:		Clock ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)  * @parents:		Name of this clock's parents
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)  * @num_parents:	Number of parents
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)  * @nodes:		Clock topology node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)  * Return: clock hardware to the registered clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) struct clk_hw *zynqmp_clk_register_fixed_factor(const char *name, u32 clk_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 					const char * const *parents,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 					u8 num_parents,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 					const struct clock_topology *nodes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	u32 mult, div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	struct clk_hw *hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	struct zynqmp_pm_query_data qdata = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	u32 ret_payload[PAYLOAD_ARG_CNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	qdata.qid = PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	qdata.arg1 = clk_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	ret = zynqmp_pm_query_data(qdata, ret_payload);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 		return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	mult = ret_payload[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	div = ret_payload[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	hw = clk_hw_register_fixed_factor(NULL, name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 					  parents[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 					  nodes->flag, mult,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 					  div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	return hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)  * zynqmp_pm_clock_get_parents() - Get the first 3 parents of clock for given id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)  * @clock_id:	Clock ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)  * @index:	Parent index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)  * @response:	Parents of the given clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)  * This function is used to get 3 parents for the clock specified by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)  * given clock ID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)  * This API will return 3 parents with a single response. To get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)  * other parents, master should call same API in loop with new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)  * parent index till error is returned. E.g First call should have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)  * index 0 which will return parents 0,1 and 2. Next call, index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)  * should be 3 which will return parent 3,4 and 5 and so on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)  * Return: 0 on success else error+reason
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) static int zynqmp_pm_clock_get_parents(u32 clock_id, u32 index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 				       struct parents_resp *response)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	struct zynqmp_pm_query_data qdata = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	u32 ret_payload[PAYLOAD_ARG_CNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	qdata.qid = PM_QID_CLOCK_GET_PARENTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	qdata.arg1 = clock_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	qdata.arg2 = index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	ret = zynqmp_pm_query_data(qdata, ret_payload);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	memcpy(response, &ret_payload[1], sizeof(*response));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)  * zynqmp_pm_clock_get_attributes() - Get the attributes of clock for given id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)  * @clock_id:	Clock ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)  * @response:	Clock attributes response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)  * This function is used to get clock's attributes(e.g. valid, clock type, etc).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)  * Return: 0 on success else error+reason
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) static int zynqmp_pm_clock_get_attributes(u32 clock_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 					  struct attr_resp *response)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	struct zynqmp_pm_query_data qdata = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	u32 ret_payload[PAYLOAD_ARG_CNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	qdata.qid = PM_QID_CLOCK_GET_ATTRIBUTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	qdata.arg1 = clock_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	ret = zynqmp_pm_query_data(qdata, ret_payload);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	memcpy(response, &ret_payload[1], sizeof(*response));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)  * __zynqmp_clock_get_topology() - Get topology data of clock from firmware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)  *				   response data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)  * @topology:		Clock topology
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)  * @response:		Clock topology data received from firmware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)  * @nnodes:		Number of nodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)  * Return: 0 on success else error+reason
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) static int __zynqmp_clock_get_topology(struct clock_topology *topology,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 				       struct topology_resp *response,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 				       u32 *nnodes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	u32 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	for (i = 0; i < ARRAY_SIZE(response->topology); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 		type = FIELD_GET(CLK_TOPOLOGY_TYPE, response->topology[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 		if (type == TYPE_INVALID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 			return END_OF_TOPOLOGY_NODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 		topology[*nnodes].type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 		topology[*nnodes].flag = FIELD_GET(CLK_TOPOLOGY_FLAGS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 						   response->topology[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 		topology[*nnodes].type_flag =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 				FIELD_GET(CLK_TOPOLOGY_TYPE_FLAGS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 					  response->topology[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 		topology[*nnodes].custom_type_flag =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 			FIELD_GET(CLK_TOPOLOGY_CUSTOM_TYPE_FLAGS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 				  response->topology[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 		(*nnodes)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)  * zynqmp_clock_get_topology() - Get topology of clock from firmware using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)  *				 PM_API
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)  * @clk_id:		Clock index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)  * @topology:		Clock topology
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)  * @num_nodes:		Number of nodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)  * Return: 0 on success else error+reason
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) static int zynqmp_clock_get_topology(u32 clk_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 				     struct clock_topology *topology,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 				     u32 *num_nodes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	int j, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	struct topology_resp response = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	*num_nodes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	for (j = 0; j <= MAX_NODES; j += ARRAY_SIZE(response.topology)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 		ret = zynqmp_pm_clock_get_topology(clock[clk_id].clk_id, j,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 						   &response);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 		ret = __zynqmp_clock_get_topology(topology, &response,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 						  num_nodes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 		if (ret == END_OF_TOPOLOGY_NODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)  * __zynqmp_clock_get_parents() - Get parents info of clock from firmware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)  *				   response data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)  * @parents:		Clock parents
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)  * @response:		Clock parents data received from firmware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)  * @nparent:		Number of parent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)  * Return: 0 on success else error+reason
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) static int __zynqmp_clock_get_parents(struct clock_parent *parents,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 				      struct parents_resp *response,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 				      u32 *nparent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	struct clock_parent *parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	for (i = 0; i < ARRAY_SIZE(response->parents); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 		if (response->parents[i] == NA_PARENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 			return END_OF_PARENTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 		parent = &parents[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 		parent->id = FIELD_GET(CLK_PARENTS_ID, response->parents[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 		if (response->parents[i] == DUMMY_PARENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 			strcpy(parent->name, "dummy_name");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 			parent->flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 			parent->flag = FIELD_GET(CLK_PARENTS_FLAGS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 						 response->parents[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 			if (zynqmp_get_clock_name(parent->id, parent->name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 		*nparent += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)  * zynqmp_clock_get_parents() - Get parents info from firmware using PM_API
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)  * @clk_id:		Clock index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)  * @parents:		Clock parents
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)  * @num_parents:	Total number of parents
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)  * Return: 0 on success else error+reason
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) static int zynqmp_clock_get_parents(u32 clk_id, struct clock_parent *parents,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 				    u32 *num_parents)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	int j = 0, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	struct parents_resp response = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	*num_parents = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 		/* Get parents from firmware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 		ret = zynqmp_pm_clock_get_parents(clock[clk_id].clk_id, j,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 						  &response);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 		ret = __zynqmp_clock_get_parents(&parents[j], &response,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 						 num_parents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 		if (ret == END_OF_PARENTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 		j += ARRAY_SIZE(response.parents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	} while (*num_parents <= MAX_PARENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)  * zynqmp_get_parent_list() - Create list of parents name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)  * @np:			Device node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)  * @clk_id:		Clock index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)  * @parent_list:	List of parent's name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)  * @num_parents:	Total number of parents
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)  * Return: 0 on success else error+reason
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) static int zynqmp_get_parent_list(struct device_node *np, u32 clk_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 				  const char **parent_list, u32 *num_parents)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	int i = 0, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	u32 total_parents = clock[clk_id].num_parents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	struct clock_topology *clk_nodes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	struct clock_parent *parents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	clk_nodes = clock[clk_id].node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	parents = clock[clk_id].parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	for (i = 0; i < total_parents; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 		if (!parents[i].flag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 			parent_list[i] = parents[i].name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 		} else if (parents[i].flag == PARENT_CLK_EXTERNAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 			ret = of_property_match_string(np, "clock-names",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 						       parents[i].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 				strcpy(parents[i].name, "dummy_name");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 			parent_list[i] = parents[i].name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 			strcat(parents[i].name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 			       clk_type_postfix[clk_nodes[parents[i].flag - 1].
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 			       type]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 			parent_list[i] = parents[i].name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 	*num_parents = total_parents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)  * zynqmp_register_clk_topology() - Register clock topology
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)  * @clk_id:		Clock index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)  * @clk_name:		Clock Name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)  * @num_parents:	Total number of parents
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)  * @parent_names:	List of parents name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)  * Return: Returns either clock hardware or error+reason
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) static struct clk_hw *zynqmp_register_clk_topology(int clk_id, char *clk_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 						   int num_parents,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 						   const char **parent_names)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 	u32 num_nodes, clk_dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	char *clk_out[MAX_NODES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	struct clock_topology *nodes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	struct clk_hw *hw = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	nodes = clock[clk_id].node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	num_nodes = clock[clk_id].num_nodes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 	clk_dev_id = clock[clk_id].clk_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	for (j = 0; j < num_nodes; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 		 * Clock name received from firmware is output clock name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 		 * Intermediate clock names are postfixed with type of clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 		if (j != (num_nodes - 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 			clk_out[j] = kasprintf(GFP_KERNEL, "%s%s", clk_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 					    clk_type_postfix[nodes[j].type]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 			clk_out[j] = kasprintf(GFP_KERNEL, "%s", clk_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 		if (!clk_topology[nodes[j].type])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 		hw = (*clk_topology[nodes[j].type])(clk_out[j], clk_dev_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 						    parent_names,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 						    num_parents,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 						    &nodes[j]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 		if (IS_ERR(hw))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 			pr_warn_once("%s() 0x%x: %s register fail with %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 				     __func__,  clk_dev_id, clk_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 				     PTR_ERR(hw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 		parent_names[0] = clk_out[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 	for (j = 0; j < num_nodes; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 		kfree(clk_out[j]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 	return hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)  * zynqmp_register_clocks() - Register clocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)  * @np:		Device node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)  * Return: 0 on success else error code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) static int zynqmp_register_clocks(struct device_node *np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 	u32 i, total_parents = 0, type = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 	const char *parent_names[MAX_PARENT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	for (i = 0; i < clock_max_idx; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 		char clk_name[MAX_NAME_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 		/* get clock name, continue to next clock if name not found */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 		if (zynqmp_get_clock_name(i, clk_name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 		/* Check if clock is valid and output clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 		 * Do not register invalid or external clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 		ret = zynqmp_get_clock_type(i, &type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 		if (ret || type != CLK_TYPE_OUTPUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 		/* Get parents of clock*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 		if (zynqmp_get_parent_list(np, i, parent_names,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 					   &total_parents)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 			WARN_ONCE(1, "No parents found for %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 				  clock[i].clk_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 		zynqmp_data->hws[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 			zynqmp_register_clk_topology(i, clk_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 						     total_parents,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 						     parent_names);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 	for (i = 0; i < clock_max_idx; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 		if (IS_ERR(zynqmp_data->hws[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 			pr_err("Zynq Ultrascale+ MPSoC clk %s: register failed with %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 			       clock[i].clk_name, PTR_ERR(zynqmp_data->hws[i]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 			WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)  * zynqmp_get_clock_info() - Get clock information from firmware using PM_API
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) static void zynqmp_get_clock_info(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 	int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 	u32 type = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	u32 nodetype, subclass, class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 	struct attr_resp attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 	struct name_resp name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 	for (i = 0; i < clock_max_idx; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 		ret = zynqmp_pm_clock_get_attributes(i, &attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 		clock[i].valid = FIELD_GET(CLK_ATTR_VALID, attr.attr[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 		/* skip query for Invalid clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 		ret = zynqmp_is_valid_clock(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 		if (ret != CLK_ATTR_VALID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 		clock[i].type = FIELD_GET(CLK_ATTR_TYPE, attr.attr[0]) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 			CLK_TYPE_EXTERNAL : CLK_TYPE_OUTPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 		nodetype = FIELD_GET(CLK_ATTR_NODE_TYPE, attr.attr[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 		subclass = FIELD_GET(CLK_ATTR_NODE_SUBCLASS, attr.attr[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 		class = FIELD_GET(CLK_ATTR_NODE_CLASS, attr.attr[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 		clock[i].clk_id = FIELD_PREP(CLK_ATTR_NODE_CLASS, class) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 				  FIELD_PREP(CLK_ATTR_NODE_SUBCLASS, subclass) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 				  FIELD_PREP(CLK_ATTR_NODE_TYPE, nodetype) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 				  FIELD_PREP(CLK_ATTR_NODE_INDEX, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 		zynqmp_pm_clock_get_name(clock[i].clk_id, &name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 		if (!strcmp(name.name, RESERVED_CLK_NAME))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 		strncpy(clock[i].clk_name, name.name, MAX_NAME_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 	/* Get topology of all clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 	for (i = 0; i < clock_max_idx; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 		ret = zynqmp_get_clock_type(i, &type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 		if (ret || type != CLK_TYPE_OUTPUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 		ret = zynqmp_clock_get_topology(i, clock[i].node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 						&clock[i].num_nodes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 		ret = zynqmp_clock_get_parents(i, clock[i].parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 					       &clock[i].num_parents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)  * zynqmp_clk_setup() - Setup the clock framework and register clocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)  * @np:		Device node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)  * Return: 0 on success else error code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) static int zynqmp_clk_setup(struct device_node *np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 	ret = zynqmp_pm_clock_get_num_clocks(&clock_max_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 	zynqmp_data = kzalloc(struct_size(zynqmp_data, hws, clock_max_idx),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 			      GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 	if (!zynqmp_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 	clock = kcalloc(clock_max_idx, sizeof(*clock), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 	if (!clock) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 		kfree(zynqmp_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 	zynqmp_get_clock_info();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 	zynqmp_register_clocks(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 	zynqmp_data->num = clock_max_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 	of_clk_add_hw_provider(np, of_clk_hw_onecell_get, zynqmp_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) static int zynqmp_clock_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 	struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 	ret = zynqmp_clk_setup(dev->of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) static const struct of_device_id zynqmp_clock_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 	{.compatible = "xlnx,zynqmp-clk"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 	{.compatible = "xlnx,versal-clk"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 	{},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) MODULE_DEVICE_TABLE(of, zynqmp_clock_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) static struct platform_driver zynqmp_clock_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 		.name = "zynqmp_clock",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 		.of_match_table = zynqmp_clock_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 	.probe = zynqmp_clock_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) module_platform_driver(zynqmp_clock_driver);