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)  * Copyright (C) 2016 Freescale Semiconductor, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright 2017~2018 NXP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Author: Dong Aisheng <aisheng.dong@nxp.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *
^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/bits.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/iopoll.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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include "clk.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) /* PLL Control Status Register (xPLLCSR) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #define PLL_CSR_OFFSET		0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #define PLL_VLD			BIT(24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define PLL_EN			BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) /* PLL Configuration Register (xPLLCFG) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define PLL_CFG_OFFSET		0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define BP_PLL_MULT		16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define BM_PLL_MULT		(0x7f << 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) /* PLL Numerator Register (xPLLNUM) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define PLL_NUM_OFFSET		0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) /* PLL Denominator Register (xPLLDENOM) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define PLL_DENOM_OFFSET	0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define MAX_MFD			0x3fffffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define DEFAULT_MFD		1000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) struct clk_pllv4 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	struct clk_hw	hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	void __iomem	*base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) /* Valid PLL MULT Table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) static const int pllv4_mult_table[] = {33, 27, 22, 20, 17, 16};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #define to_clk_pllv4(__hw) container_of(__hw, struct clk_pllv4, hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #define LOCK_TIMEOUT_US		USEC_PER_MSEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) static inline int clk_pllv4_wait_lock(struct clk_pllv4 *pll)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	u32 csr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	return readl_poll_timeout(pll->base  + PLL_CSR_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 				  csr, csr & PLL_VLD, 0, LOCK_TIMEOUT_US);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) static int clk_pllv4_is_prepared(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	struct clk_pllv4 *pll = to_clk_pllv4(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	if (readl_relaxed(pll->base) & PLL_EN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) static unsigned long clk_pllv4_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 					   unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	struct clk_pllv4 *pll = to_clk_pllv4(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	u32 mult, mfn, mfd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	u64 temp64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	mult = readl_relaxed(pll->base + PLL_CFG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	mult &= BM_PLL_MULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	mult >>= BP_PLL_MULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	mfn = readl_relaxed(pll->base + PLL_NUM_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	mfd = readl_relaxed(pll->base + PLL_DENOM_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	temp64 = parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	temp64 *= mfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	do_div(temp64, mfd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	return (parent_rate * mult) + (u32)temp64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) static long clk_pllv4_round_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 				 unsigned long *prate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	unsigned long parent_rate = *prate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	unsigned long round_rate, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	u32 mfn, mfd = DEFAULT_MFD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	bool found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	u64 temp64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	for (i = 0; i < ARRAY_SIZE(pllv4_mult_table); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		round_rate = parent_rate * pllv4_mult_table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		if (rate >= round_rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 			found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	if (!found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		pr_warn("%s: unable to round rate %lu, parent rate %lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 			clk_hw_get_name(hw), rate, parent_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		return 0;
^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) 	if (parent_rate <= MAX_MFD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		mfd = parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	temp64 = (u64)(rate - round_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	temp64 *= mfd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	do_div(temp64, parent_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	mfn = temp64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	 * NOTE: The value of numerator must always be configured to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	 * less than the value of the denominator. If we can't get a proper
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	 * pair of mfn/mfd, we simply return the round_rate without using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	 * the frac part.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	if (mfn >= mfd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		return round_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	temp64 = (u64)parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	temp64 *= mfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	do_div(temp64, mfd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	return round_rate + (u32)temp64;
^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 bool clk_pllv4_is_valid_mult(unsigned int mult)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	/* check if mult is in valid MULT table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	for (i = 0; i < ARRAY_SIZE(pllv4_mult_table); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 		if (pllv4_mult_table[i] == mult)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 			return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) static int clk_pllv4_set_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 			      unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	struct clk_pllv4 *pll = to_clk_pllv4(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	u32 val, mult, mfn, mfd = DEFAULT_MFD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	u64 temp64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	mult = rate / parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	if (!clk_pllv4_is_valid_mult(mult))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	if (parent_rate <= MAX_MFD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		mfd = parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	temp64 = (u64)(rate - mult * parent_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	temp64 *= mfd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	do_div(temp64, parent_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	mfn = temp64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	val = readl_relaxed(pll->base + PLL_CFG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	val &= ~BM_PLL_MULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	val |= mult << BP_PLL_MULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	writel_relaxed(val, pll->base + PLL_CFG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	writel_relaxed(mfn, pll->base + PLL_NUM_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	writel_relaxed(mfd, pll->base + PLL_DENOM_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) static int clk_pllv4_prepare(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	struct clk_pllv4 *pll = to_clk_pllv4(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	val = readl_relaxed(pll->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	val |= PLL_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	writel_relaxed(val, pll->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	return clk_pllv4_wait_lock(pll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static void clk_pllv4_unprepare(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	struct clk_pllv4 *pll = to_clk_pllv4(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	val = readl_relaxed(pll->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	val &= ~PLL_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	writel_relaxed(val, pll->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) static const struct clk_ops clk_pllv4_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	.recalc_rate	= clk_pllv4_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	.round_rate	= clk_pllv4_round_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	.set_rate	= clk_pllv4_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	.prepare	= clk_pllv4_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	.unprepare	= clk_pllv4_unprepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	.is_prepared	= clk_pllv4_is_prepared,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) struct clk_hw *imx_clk_hw_pllv4(const char *name, const char *parent_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 			  void __iomem *base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	struct clk_pllv4 *pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	struct clk_hw *hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	struct clk_init_data init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	if (!pll)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	pll->base = base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	init.name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	init.ops = &clk_pllv4_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	init.parent_names = &parent_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	init.num_parents = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	init.flags = CLK_SET_RATE_GATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	pll->hw.init = &init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	hw = &pll->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	ret = clk_hw_register(NULL, hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		kfree(pll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		hw = ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	return hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }