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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * Copyright (c) 2017 Rockchip Electronics Co. Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * This program is free software; you can redistribute it and/or modify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * it under the terms of the GNU General Public License as published by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * the Free Software Foundation; either version 2 of the License, or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * (at your option) any later version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * This program is distributed in the hope that it will be useful,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * but WITHOUT ANY WARRANTY; without even the implied warranty of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * GNU General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/mfd/rk618.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include "clk-regmap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define RK618_CRU_CLKSEL0		0x0058
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define RK618_CRU_CLKSEL1		0x005c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define RK618_CRU_CLKSEL2		0x0060
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define RK618_CRU_CLKSEL3		0x0064
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define RK618_CRU_PLL0_CON0		0x0068
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define RK618_CRU_PLL0_CON1		0x006c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define RK618_CRU_PLL0_CON2		0x0070
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define RK618_CRU_PLL1_CON0		0x0074
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define RK618_CRU_PLL1_CON1		0x0078
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define RK618_CRU_PLL1_CON2		0x007c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	LCDC0_CLK = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	LCDC1_CLK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	VIF_PLLIN_CLK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	SCALER_PLLIN_CLK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	VIF_PLL_CLK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	SCALER_PLL_CLK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	VIF0_CLK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	VIF1_CLK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	SCALER_IN_CLK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	SCALER_CLK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	DITHER_CLK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	HDMI_CLK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	MIPI_CLK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	LVDS_CLK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	LVTTL_CLK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	RGB_CLK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	VIF0_PRE_CLK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	VIF1_PRE_CLK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	CODEC_CLK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	NR_CLKS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) struct rk618_cru {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	struct rk618 *parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	struct clk_onecell_data clk_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) static char clkin_name[32] = "dummy";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) static char lcdc0_dclkp_name[32] = "dummy";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) static char lcdc1_dclkp_name[32] = "dummy";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) #define PNAME(x) static const char *const x[]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) PNAME(mux_pll_in_p) = { "lcdc0_clk", "lcdc1_clk", clkin_name };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) PNAME(mux_pll_src_p) = { "vif_pll_clk", "scaler_pll_clk", };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) PNAME(mux_scaler_in_src_p) = { "vif0_clk", "vif1_clk" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) PNAME(mux_hdmi_src_p) = { "vif1_clk", "scaler_clk", "vif0_clk" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) PNAME(mux_dither_src_p) = { "vif0_clk", "scaler_clk" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) PNAME(mux_vif0_src_p) = { "vif0_pre_clk", lcdc0_dclkp_name };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) PNAME(mux_vif1_src_p) = { "vif1_pre_clk", lcdc1_dclkp_name };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) PNAME(mux_codec_src_p) = { "codec_pre_clk", clkin_name };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) /* Two PLL, one for dual datarate input logic, the other for scaler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) static const struct clk_pll_data rk618_clk_plls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	RK618_PLL(VIF_PLL_CLK, "vif_pll_clk", "vif_pllin_clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		  RK618_CRU_PLL0_CON0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		  0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	RK618_PLL(SCALER_PLL_CLK, "scaler_pll_clk", "scaler_pllin_clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		  RK618_CRU_PLL1_CON0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		  0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) static const struct clk_mux_data rk618_clk_muxes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	MUX(VIF_PLLIN_CLK, "vif_pllin_clk", mux_pll_in_p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	    RK618_CRU_CLKSEL0, 6, 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	    0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	MUX(SCALER_PLLIN_CLK, "scaler_pllin_clk", mux_pll_in_p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	    RK618_CRU_CLKSEL0, 8, 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	    0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	MUX(SCALER_IN_CLK, "scaler_in_clk", mux_scaler_in_src_p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	    RK618_CRU_CLKSEL3, 15, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	    0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	MUX(DITHER_CLK, "dither_clk", mux_dither_src_p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	    RK618_CRU_CLKSEL3, 14, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	    0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	MUX(VIF0_CLK, "vif0_clk", mux_vif0_src_p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	    RK618_CRU_CLKSEL3, 1, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	    CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	MUX(VIF1_CLK, "vif1_clk", mux_vif1_src_p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	    RK618_CRU_CLKSEL3, 7, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	    CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	MUX(CODEC_CLK, "codec_clk", mux_codec_src_p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	    RK618_CRU_CLKSEL1, 1, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	    CLK_SET_RATE_PARENT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static const struct clk_divider_data rk618_clk_dividers[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	DIV(LCDC0_CLK, "lcdc0_clk", lcdc0_dclkp_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	    RK618_CRU_CLKSEL0, 0, 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	    0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	DIV(LCDC1_CLK, "lcdc1_clk", lcdc1_dclkp_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	    RK618_CRU_CLKSEL0, 3, 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	    0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static const struct clk_gate_data rk618_clk_gates[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	GATE(MIPI_CLK, "mipi_clk", "dither_clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	     RK618_CRU_CLKSEL1, 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	     CLK_IGNORE_UNUSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	GATE(LVDS_CLK, "lvds_clk", "dither_clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	     RK618_CRU_CLKSEL1, 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	     CLK_IGNORE_UNUSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	GATE(LVTTL_CLK, "lvttl_clk", "dither_clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	     RK618_CRU_CLKSEL1, 12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	     0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	GATE(RGB_CLK, "rgb_clk", "dither_clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	     RK618_CRU_CLKSEL1, 11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	     0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static const struct clk_composite_data rk618_clk_composites[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	COMPOSITE(SCALER_CLK, "scaler_clk", mux_pll_src_p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		  RK618_CRU_CLKSEL1, 3, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 		  RK618_CRU_CLKSEL1, 5, 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		  RK618_CRU_CLKSEL1, 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		  CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	COMPOSITE_NODIV(HDMI_CLK, "hdmi_clk", mux_hdmi_src_p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 			RK618_CRU_CLKSEL3, 12, 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 			RK618_CRU_CLKSEL1, 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 			0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	COMPOSITE(VIF0_PRE_CLK, "vif0_pre_clk", mux_pll_src_p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		  RK618_CRU_CLKSEL3, 0, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		  RK618_CRU_CLKSEL3, 3, 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		  RK618_CRU_CLKSEL3, 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		  CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	COMPOSITE(VIF1_PRE_CLK, "vif1_pre_clk", mux_pll_src_p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		  RK618_CRU_CLKSEL3, 6, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		  RK618_CRU_CLKSEL3, 9, 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		  RK618_CRU_CLKSEL3, 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		  CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	COMPOSITE_FRAC_NOGATE(0, "codec_pre_clk", mux_pll_src_p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 			      RK618_CRU_CLKSEL1, 0, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 			      RK618_CRU_CLKSEL2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 			      0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) static void rk618_clk_add_lookup(struct rk618_cru *cru, struct clk *clk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 				 unsigned int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	if (cru->clk_data.clks && id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		cru->clk_data.clks[id] = clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) static void rk618_clk_register_muxes(struct rk618_cru *cru)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	for (i = 0; i < ARRAY_SIZE(rk618_clk_muxes); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 		const struct clk_mux_data *data = &rk618_clk_muxes[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 		clk = devm_clk_regmap_register_mux(cru->dev, data->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 						   data->parent_names,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 						   data->num_parents,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 						   cru->regmap, data->reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 						   data->shift, data->width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 						   data->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		if (IS_ERR(clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 			dev_err(cru->dev, "failed to register clock %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 				data->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 			continue;
^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) 		rk618_clk_add_lookup(cru, clk, data->id);
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static void rk618_clk_register_dividers(struct rk618_cru *cru)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	for (i = 0; i < ARRAY_SIZE(rk618_clk_dividers); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 		const struct clk_divider_data *data = &rk618_clk_dividers[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		clk = devm_clk_regmap_register_divider(cru->dev, data->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 						       data->parent_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 						       cru->regmap, data->reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 						       data->shift, data->width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 						       data->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		if (IS_ERR(clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 			dev_err(cru->dev, "failed to register clock %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 				data->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 		rk618_clk_add_lookup(cru, clk, data->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) static void rk618_clk_register_gates(struct rk618_cru *cru)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	for (i = 0; i < ARRAY_SIZE(rk618_clk_gates); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		const struct clk_gate_data *data = &rk618_clk_gates[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		clk = devm_clk_regmap_register_gate(cru->dev, data->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 						    data->parent_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 						    cru->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 						    data->reg, data->shift,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 						    data->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		if (IS_ERR(clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 			dev_err(cru->dev, "failed to register clock %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 				data->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		rk618_clk_add_lookup(cru, clk, data->id);
^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) static void rk618_clk_register_composites(struct rk618_cru *cru)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	for (i = 0; i < ARRAY_SIZE(rk618_clk_composites); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		const struct clk_composite_data *data =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 					&rk618_clk_composites[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 		clk = devm_clk_regmap_register_composite(cru->dev, data->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 							 data->parent_names,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 							 data->num_parents,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 							 cru->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 							 data->mux_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 							 data->mux_shift,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 							 data->mux_width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 							 data->div_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 							 data->div_shift,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 							 data->div_width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 							 data->div_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 							 data->gate_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 							 data->gate_shift,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 							 data->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 		if (IS_ERR(clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 			dev_err(cru->dev, "failed to register clock %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 				data->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		rk618_clk_add_lookup(cru, clk, data->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	}
^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) static void rk618_clk_register_plls(struct rk618_cru *cru)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	for (i = 0; i < ARRAY_SIZE(rk618_clk_plls); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 		const struct clk_pll_data *data = &rk618_clk_plls[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 		clk = devm_clk_regmap_register_pll(cru->dev, data->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 						   data->parent_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 						   cru->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 						   data->reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 						   data->pd_shift,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 						   data->dsmpd_shift,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 						   data->lock_shift,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 						   data->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		if (IS_ERR(clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 			dev_err(cru->dev, "failed to register clock %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 				data->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		rk618_clk_add_lookup(cru, clk, data->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) static int rk618_cru_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	struct rk618 *rk618 = dev_get_drvdata(pdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	struct rk618_cru *cru;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	struct clk **clk_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	const char *parent_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	if (!of_device_is_available(dev->of_node))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	cru = devm_kzalloc(dev, sizeof(*cru), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	if (!cru)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	clk_table = devm_kcalloc(dev, NR_CLKS, sizeof(struct clk *),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 				 GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	if (!clk_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	for (i = 0; i < NR_CLKS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 		clk_table[i] = ERR_PTR(-ENOENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	cru->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	cru->parent = rk618;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	cru->regmap = rk618->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	cru->clk_data.clks = clk_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	cru->clk_data.clk_num = NR_CLKS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	platform_set_drvdata(pdev, cru);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	clk = devm_clk_get(dev, "clkin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	if (IS_ERR(clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 		ret = PTR_ERR(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 		dev_err(dev, "failed to get clkin: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	strlcpy(clkin_name, __clk_get_name(clk), sizeof(clkin_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	clk = devm_clk_get(dev, "lcdc0_dclkp");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	if (IS_ERR(clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 		if (PTR_ERR(clk) != -ENOENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 			ret = PTR_ERR(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 			dev_err(dev, "failed to get lcdc0_dclkp: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 			return ret;
^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) 		clk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	parent_name = __clk_get_name(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	if (parent_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 		strlcpy(lcdc0_dclkp_name, parent_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 			sizeof(lcdc0_dclkp_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	clk = devm_clk_get(dev, "lcdc1_dclkp");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	if (IS_ERR(clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 		if (PTR_ERR(clk) != -ENOENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 			ret = PTR_ERR(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 			dev_err(dev, "failed to get lcdc1_dclkp: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 		clk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	parent_name = __clk_get_name(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	if (parent_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 		strlcpy(lcdc1_dclkp_name, parent_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 			sizeof(lcdc1_dclkp_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	rk618_clk_register_plls(cru);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	rk618_clk_register_muxes(cru);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	rk618_clk_register_dividers(cru);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	rk618_clk_register_gates(cru);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	rk618_clk_register_composites(cru);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	return of_clk_add_provider(dev->of_node, of_clk_src_onecell_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 				   &cru->clk_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) static int rk618_cru_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	of_clk_del_provider(pdev->dev.of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) static const struct of_device_id rk618_cru_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	{ .compatible = "rockchip,rk618-cru", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	{},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) MODULE_DEVICE_TABLE(of, rk618_cru_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) static struct platform_driver rk618_cru_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 		.name = "rk618-cru",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 		.of_match_table = of_match_ptr(rk618_cru_of_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	.probe	= rk618_cru_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	.remove = rk618_cru_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) module_platform_driver(rk618_cru_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) MODULE_AUTHOR("Wyon Bi <bivvy.bi@rock-chips.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) MODULE_DESCRIPTION("Rockchip rk618 CRU driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) MODULE_LICENSE("GPL v2");