xref: /aosp_15_r20/external/coreboot/src/soc/mediatek/common/clkbuf.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <console/console.h>
4 #include <delay.h>
5 #include <device/mmio.h>
6 #include <soc/clkbuf.h>
7 #include <soc/pmif.h>
8 #if CONFIG(SRCLKEN_RC_SUPPORT)
9 #include <soc/srclken_rc.h>
10 #endif
11 
12 #define BUFTAG			"[CLKBUF]"
13 #define buf_info(fmt, arg ...)	printk(BIOS_INFO, BUFTAG "%s,%d: " fmt, \
14 					__func__, __LINE__, ## arg)
15 
16 #define _buf_clrset32_impl(addr, clear, set) \
17 	buf_write(addr, (buf_read(addr) & ~((uint32_t)(clear))) | (set))
18 
19 #define BUF_SET_FIELDS(addr, ...) \
20 	_BF_IMPL(_buf_clrset32_impl, addr, __VA_ARGS__)
21 #define BUF_READ_FIELD(addr, name) \
22 	EXTRACT_BITFIELD(buf_read(addr), name)
23 
24 #define PMIC_CW00_INIT_VAL	0x4005 /* 0100 0000 0000 0101 */
25 #define PMIC_CW09_INIT_VAL	0x01F0 /* 0000 0001 1111 0000 */
26 
27 static struct pmif *pmif_arb;
28 
buf_read(u32 addr)29 static u32 buf_read(u32 addr)
30 {
31 	u32 rdata;
32 
33 	if (!pmif_arb)
34 		pmif_arb = get_pmif_controller(PMIF_SPI, 0);
35 	pmif_arb->read(pmif_arb, 0, addr, &rdata);
36 
37 	return rdata;
38 }
39 
buf_write(u32 addr,u32 wdata)40 static void buf_write(u32 addr, u32 wdata)
41 {
42 	if (!pmif_arb)
43 		pmif_arb = get_pmif_controller(PMIF_SPI, 0);
44 	pmif_arb->write(pmif_arb, 0, addr, wdata);
45 }
46 
dump_clkbuf_log(void)47 static void dump_clkbuf_log(void)
48 {
49 	u32 pmic_cw00, pmic_cw09, pmic_cw12, pmic_cw13, pmic_cw15, pmic_cw19,
50 	    top_spi_con1, ldo_vrfck_op_en, ldo_vbbck_op_en, ldo_vrfck_en,
51 	    ldo_vbbck_en, vrfck_hv_en;
52 
53 	pmic_cw00 = BUF_READ_FIELD(PMIC_RG_DCXO_CW00, PMIC_REG_COMMON);
54 	pmic_cw09 = BUF_READ_FIELD(PMIC_RG_DCXO_CW09, PMIC_REG_COMMON);
55 	pmic_cw12 = BUF_READ_FIELD(PMIC_RG_DCXO_CW12, PMIC_REG_COMMON);
56 	pmic_cw13 = BUF_READ_FIELD(PMIC_RG_DCXO_CW13, PMIC_REG_COMMON);
57 	pmic_cw15 = BUF_READ_FIELD(PMIC_RG_DCXO_CW15, PMIC_REG_COMMON);
58 	pmic_cw19 = BUF_READ_FIELD(PMIC_RG_DCXO_CW19, PMIC_REG_COMMON);
59 	buf_info("DCXO_CW00/09/12/13/15/19=%#x %#x %#x %#x %#x %#x\n",
60 		pmic_cw00, pmic_cw09, pmic_cw12,
61 		pmic_cw13, pmic_cw15, pmic_cw19);
62 
63 	top_spi_con1 = BUF_READ_FIELD(PMIC_RG_TOP_SPI_CON1, PMIC_RG_SRCLKEN_IN3_EN);
64 	ldo_vrfck_op_en = BUF_READ_FIELD(PMIC_RG_LDO_VRFCK_OP_EN,
65 					  PMIC_RG_LDO_VRFCK_HW14_OP_EN);
66 	ldo_vbbck_op_en = BUF_READ_FIELD(PMIC_RG_LDO_VBBCK_OP_EN,
67 					  PMIC_RG_LDO_VBBCK_HW14_OP_EN);
68 	ldo_vrfck_en = BUF_READ_FIELD(PMIC_RG_LDO_VRFCK_CON0, PMIC_RG_LDO_VRFCK_EN);
69 	ldo_vbbck_en = BUF_READ_FIELD(PMIC_RG_LDO_VBBCK_CON0, PMIC_RG_LDO_VBBCK_EN);
70 	buf_info("spi_con1/ldo_rf_op/ldo_bb_op/ldo_rf_en/ldo_bb_en=%#x %#x %#x %#x %#x\n",
71 		top_spi_con1, ldo_vrfck_op_en, ldo_vbbck_op_en,
72 		ldo_vrfck_en, ldo_vbbck_en);
73 
74 	vrfck_hv_en = BUF_READ_FIELD(PMIC_RG_DCXO_ADLDO_BIAS_ELR_0, PMIC_RG_VRFCK_HV_EN);
75 	buf_info("clk buf vrfck_hv_en=%#x\n", vrfck_hv_en);
76 }
77 
clk_buf_init(void)78 int clk_buf_init(void)
79 {
80 	/* Dump registers before setting */
81 	dump_clkbuf_log();
82 
83 	/* Unlock pmic key */
84 	BUF_SET_FIELDS(PMIC_TOP_TMA_KEY, PMIC_REG_COMMON, PMIC_TOP_TMA_KEY_UNLOCK);
85 
86 	/* 1.1 Set VRFCK input supply(11.ac mode) */
87 	BUF_SET_FIELDS(PMIC_RG_DCXO_ADLDO_BIAS_ELR_0, PMIC_RG_VRFCK_HV_EN, 0x0);
88 
89 	/* 1.2.0 Set VRFCK En = 0 */
90 	BUF_SET_FIELDS(PMIC_RG_LDO_VRFCK_CON0, PMIC_RG_LDO_VRFCK_EN, 0x0);
91 	/* 1.2.1 Set VRFCK1 as power src */
92 	BUF_SET_FIELDS(PMIC_RG_LDO_VRFCK_ELR, PMIC_RG_LDO_VRFCK_ANA_SEL, 0x1);
93 
94 	/* 1.2.2 Switch LDO-RFCK to LDO-RFCK1 */
95 	BUF_SET_FIELDS(PMIC_RG_DCXO_ADLDO_BIAS_ELR_0, PMIC_RG_VRFCK_NDIS_EN, 0x0);
96 	BUF_SET_FIELDS(PMIC_RG_DCXO_ADLDO_BIAS_ELR_1, PMIC_RG_VRFCK_1_NDIS_EN, 0x1);
97 
98 	/* 1.2.0 Set VRFCK En = 1 */
99 	BUF_SET_FIELDS(PMIC_RG_LDO_VRFCK_CON0, PMIC_RG_LDO_VRFCK_EN, 0x1);
100 
101 	/* 1.2.3 Lock pmic key */
102 	BUF_SET_FIELDS(PMIC_TOP_TMA_KEY, PMIC_REG_COMMON, 0x0);
103 
104 	/* Enable XO LDO */
105 	BUF_SET_FIELDS(PMIC_RG_LDO_VRFCK_OP_EN_SET, PMIC_RG_LDO_VRFCK_HW14_OP_EN, 0x1);
106 	BUF_SET_FIELDS(PMIC_RG_LDO_VBBCK_OP_EN_SET, PMIC_RG_LDO_VBBCK_HW14_OP_EN, 0x1);
107 	BUF_SET_FIELDS(PMIC_RG_LDO_VRFCK_CON0, PMIC_RG_LDO_VRFCK_EN, 0x0);
108 	BUF_SET_FIELDS(PMIC_RG_LDO_VBBCK_CON0, PMIC_RG_LDO_VBBCK_EN, 0x0);
109 
110 	/* Enable 26M control */
111 	if (!CONFIG(SRCLKEN_RC_SUPPORT)) {
112 		/* Legacy co-clock mode */
113 		BUF_SET_FIELDS(PMIC_RG_TOP_SPI_CON1, PMIC_RG_SRCLKEN_IN3_EN, 0x0);
114 
115 		BUF_SET_FIELDS(PMIC_RG_DCXO_CW00, PMIC_REG_COMMON, PMIC_CW00_INIT_VAL);
116 		BUF_SET_FIELDS(PMIC_RG_DCXO_CW09, PMIC_REG_COMMON, PMIC_CW09_INIT_VAL);
117 	} else {
118 		/* New co-clock mode */
119 		/* All XO mode should set to 2'b01 */
120 		BUF_SET_FIELDS(PMIC_RG_DCXO_CW00, PMIC_REG_COMMON, PMIC_CW00_INIT_VAL);
121 		BUF_SET_FIELDS(PMIC_RG_DCXO_CW09, PMIC_REG_COMMON, PMIC_CW09_INIT_VAL);
122 
123 		/* 1. Update control mapping table */
124 		BUF_SET_FIELDS(PMIC_RG_XO_BUF_CTL0, PMIC_RG_XO_VOTE, 0x005);
125 		BUF_SET_FIELDS(PMIC_RG_XO_BUF_CTL1, PMIC_RG_XO_VOTE, 0x0);
126 		BUF_SET_FIELDS(PMIC_RG_XO_BUF_CTL2, PMIC_RG_XO_VOTE, 0x0);
127 		BUF_SET_FIELDS(PMIC_RG_XO_BUF_CTL3, PMIC_RG_XO_VOTE, 0x0);
128 		BUF_SET_FIELDS(PMIC_RG_XO_BUF_CTL4, PMIC_RG_XO_VOTE, 0x0);
129 		/* Wait 100us */
130 		udelay(100);
131 
132 		/* 2. Switch to new control mode */
133 		BUF_SET_FIELDS(PMIC_RG_DCXO_CW08, PMIC_RG_XO_PMIC_TOP_DIG_SW, 0x0);
134 	}
135 
136 	/* Check if the setting is ok */
137 	dump_clkbuf_log();
138 
139 	return 0;
140 }
141