blob: 6ed199ccee2e35f621ce3f04098eaa9256f3a77f [file] [log] [blame]
chao.zhang44883592024-09-25 14:47:29 +08001// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
2/*
3 * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
4 */
5
6#include <common.h>
7#include <command.h>
8#include <asm/io.h>
9#include <asm/amlogic/arch/secure_apb.h>
10#include <linux/arm-smccc.h>
11#include <amlogic/cpu_id.h>
12#include <linux/libfdt_env.h>
13
14#define cmd_pdvfs_info(fmt...) printf("[cmd_pdvfs] "fmt)
15#define cmd_pdvfs_err(fmt...) printf("[cmd_pdvfs] "fmt)
16#define GET_DVFS_TABLE_INDEX 0x82000088
chao.zhange3982ab2024-12-17 15:28:38 +080017#define REVA 0xA
18#define REVB 0xB
chao.zhang44883592024-09-25 14:47:29 +080019
Liming Xuefe754dc2024-11-20 10:57:19 +080020int get_board_id(void)
chao.zhang44883592024-09-25 14:47:29 +080021{
22 int board_id = 0;
23
24 board_id = (readl(SYSCTRL_SEC_STATUS_REG4) >> 8) & 0XFF;
25 return board_id;
26}
27
28static int get_chip_rev(void)
29{
30 unsigned int chip_rev;
31
32 chip_rev = get_cpu_id().chip_rev;
33 return chip_rev;
34}
35
36static int set_regulator_status(const char *node, const char *status) {
37 int ret = 0;
38 char cmdbuf[256] = {0};
39
40 memset(cmdbuf, 0, sizeof(cmdbuf));
41 sprintf(cmdbuf, "fdt set %s status %s;", node, status);
42 ret = run_command(cmdbuf, 0);
43 if (ret != 0) {
Liming Xuefe754dc2024-11-20 10:57:19 +080044 cmd_pdvfs_err("Error: Failed to set regulator status\n");
45 return -EBADMSG;
46 }
chao.zhang44883592024-09-25 14:47:29 +080047
Liming Xuefe754dc2024-11-20 10:57:19 +080048 return 0;
chao.zhang44883592024-09-25 14:47:29 +080049}
50
Liming Xuefe754dc2024-11-20 10:57:19 +080051int get_phandle(const char *path) {
52 int ret = 0;
53 char cmdbuf[256] = {0};
chao.zhang44883592024-09-25 14:47:29 +080054 char *phandle_str = NULL;
55 unsigned int phandle_val = 0;
56
Liming Xuefe754dc2024-11-20 10:57:19 +080057 memset(cmdbuf, 0, sizeof(cmdbuf));
58 sprintf(cmdbuf, "fdt get value phandle_value %s phandle", path);
59 ret = run_command(cmdbuf, 0);
60 if (ret != 0) {
61 cmd_pdvfs_err("Error: Failed to get phandle for %s\n", path);
62 return -EBADMSG;
63 }
chao.zhang44883592024-09-25 14:47:29 +080064
Liming Xuefe754dc2024-11-20 10:57:19 +080065 phandle_str = env_get("phandle_value");
66 if (phandle_str == NULL) {
67 cmd_pdvfs_err("Error: Failed to retrieve phandle_value from environment\n");
68 return -EBADMSG;
69 }
chao.zhang44883592024-09-25 14:47:29 +080070 phandle_val = strtoul(phandle_str, NULL, 16);
71
Liming Xuefe754dc2024-11-20 10:57:19 +080072 return phandle_val;
chao.zhang44883592024-09-25 14:47:29 +080073}
74
75static int update_pwm_f_board_regulator(void) {
Liming Xuefe754dc2024-11-20 10:57:19 +080076 int ret = 0;
77 char cmdbuf[256] = {0};
chao.zhang44883592024-09-25 14:47:29 +080078 unsigned int pwm_f_board0_phandle = 0;
79
80 pwm_f_board0_phandle = get_phandle("/pwm_f_board0-regulator");
81 memset(cmdbuf, 0, sizeof(cmdbuf));
82 sprintf(cmdbuf, "fdt set /meson-cpufreq cluster0-cpu-supply <0x%x>;", pwm_f_board0_phandle);
83 ret = run_command(cmdbuf, 0);
84 if (ret != 0) {
85 cmd_pdvfs_err("Error: Failed to update cluster0-cpu-supply.\n");
86 return -EBADMSG;
87 }
88 ret = set_regulator_status("/pwm_f_board0-regulator", "okay");
89 if (ret != 0) {
90 cmd_pdvfs_err("Error: Failed to set pwm_f_board0 okay\n");
91 return -EBADMSG;
92 }
93 ret = set_regulator_status("/pwm_f_board2-regulator", "disabled");
94 if (ret != 0) {
95 cmd_pdvfs_err("Error: Failed to set pwm_f_board2 disabled\n");
96 return -EBADMSG;
97 }
98
Liming Xuefe754dc2024-11-20 10:57:19 +080099 return 0;
chao.zhang44883592024-09-25 14:47:29 +0800100}
101
102
Liming Xuefe754dc2024-11-20 10:57:19 +0800103unsigned int get_cpufreq_table_index(u64 function_id,
104 u64 arg0, u64 arg1, u64 arg2)
chao.zhang44883592024-09-25 14:47:29 +0800105{
106 struct arm_smccc_res res;
107
108 arm_smccc_smc((unsigned long)function_id,
109 (unsigned long)arg0,
110 (unsigned long)arg1,
111 (unsigned long)arg2,
112 0, 0, 0, 0, &res);
113 return res.a0;
114}
115
116static int set_cpu_opp_tbl(void)
117{
118 int ret = 0;
119 unsigned int opp_table_0_phandle = 0;
120 unsigned int opp_table_1_phandle = 0;
121 unsigned int opp_table_2_phandle = 0;
122 unsigned int opp_table_3_phandle = 0;
123 char cmdbuf[256] = {0};
124
125 opp_table_0_phandle = get_phandle("/cpu_opp_table0");
126 opp_table_1_phandle = get_phandle("/cpu_opp_table1");
127 opp_table_2_phandle = get_phandle("/cpu_opp_table2_2000");
128 opp_table_3_phandle = get_phandle("/cpu_opp_table3_2000");
Liming Xuefe754dc2024-11-20 10:57:19 +0800129
chao.zhang44883592024-09-25 14:47:29 +0800130 memset(cmdbuf, 0, sizeof(cmdbuf));
131 sprintf(cmdbuf, "fdt set /cpus/cpu@0 operating-points-v2 <0x%x 0x%x 0x%x 0x%x>;", \
132 opp_table_0_phandle, opp_table_1_phandle, \
133 opp_table_2_phandle, opp_table_3_phandle);
134 ret = run_command(cmdbuf, 0);
135 if (ret != 0) {
136 cmd_pdvfs_err("Error: Failed to update operating-points-v2/n");
137 return -EBADMSG;
138 }
139
140 return 0;
141}
142
143static int update_pdvfs_tbl(cmd_tbl_t *cmdtp, int flag, int argc,
144 char *const argv[])
145{
146 unsigned int ret = 0;
147 unsigned int board_id = 0;
chao.zhange3982ab2024-12-17 15:28:38 +0800148 unsigned int chip_rev = 0;
chao.zhang44883592024-09-25 14:47:29 +0800149 unsigned int pdvfs_index = 0;
150
151 board_id = get_board_id();
chao.zhange3982ab2024-12-17 15:28:38 +0800152 chip_rev = get_chip_rev();
chao.zhang44883592024-09-25 14:47:29 +0800153 pdvfs_index = get_cpufreq_table_index(GET_DVFS_TABLE_INDEX, 0, 0, 0);
154 cmd_pdvfs_info("update_pdvfs dtb\n");
155 if (board_id < 2) {
156 ret = update_pwm_f_board_regulator();
157 if (ret != 0)
158 cmd_pdvfs_err("fix_regulator_tbl fail\n");
159 ret = set_cpu_opp_tbl();
160 if (ret != 0)
161 cmd_pdvfs_err("fix_cpu_opp_tbl fail\n");
chao.zhange3982ab2024-12-17 15:28:38 +0800162 } else {
chao.zhang44883592024-09-25 14:47:29 +0800163 if (pdvfs_index == 0 || pdvfs_index == 1) {
164 ret = set_cpu_opp_tbl();
165 if (ret != 0)
166 cmd_pdvfs_err("fix_cpu_opp_tbl fail\n");
167 }
168 }
chao.zhange3982ab2024-12-17 15:28:38 +0800169 if (chip_rev >= REVB) {
170 if (board_id < 2 && pdvfs_index) {
171 cmd_pdvfs_err("board_id is not correct, board_id = %d \n", board_id);
172 while (1)
173 ; // software protect
174 }
175 if (board_id >= 2 && !pdvfs_index) {
176 cmd_pdvfs_err("pdvfs_index is conflict with board_id, pdvfs_index = %d \n", pdvfs_index);
177 while (1)
178 ; // software protect
179 }
180 }
chao.zhang44883592024-09-25 14:47:29 +0800181
182 return 0;
183}
184
185U_BOOT_CMD(
186 update_pdvfs, 1, 0, update_pdvfs_tbl,
187 "update pdvfs",
188 "set_regulator_tbl - set board_A regulator_pwm_tbl\n"
189 "set_cpu_opp_tbl - set 2.0g cpu_opp_tbl\n"
190);