blob: cc2f34d8aac7f4047b31f0c2fff204f0fad54ade [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
17
18static int get_board_id(void)
19{
20 int board_id = 0;
21
22 board_id = (readl(SYSCTRL_SEC_STATUS_REG4) >> 8) & 0XFF;
23 return board_id;
24}
25
26static int get_chip_rev(void)
27{
28 unsigned int chip_rev;
29
30 chip_rev = get_cpu_id().chip_rev;
31 return chip_rev;
32}
33
34static int set_regulator_status(const char *node, const char *status) {
35 int ret = 0;
36 char cmdbuf[256] = {0};
37
38 memset(cmdbuf, 0, sizeof(cmdbuf));
39 sprintf(cmdbuf, "fdt set %s status %s;", node, status);
40 ret = run_command(cmdbuf, 0);
41 if (ret != 0) {
42 cmd_pdvfs_err("Error: Failed to set regulator status\n");
43 return -EBADMSG;
44 }
45
46 return 0;
47}
48
49static int get_phandle(const char *path) {
50 int ret = 0;
51 char cmdbuf[256] = {0};
52 char *phandle_str = NULL;
53 unsigned int phandle_val = 0;
54
55 memset(cmdbuf, 0, sizeof(cmdbuf));
56 sprintf(cmdbuf, "fdt get value phandle_value %s phandle", path);
57 ret = run_command(cmdbuf, 0);
58 if (ret != 0) {
59 cmd_pdvfs_err("Error: Failed to get phandle for %s\n", path);
60 return -EBADMSG;
61 }
62
63 phandle_str = env_get("phandle_value");
64 if (phandle_str == NULL) {
65 cmd_pdvfs_err("Error: Failed to retrieve phandle_value from environment\n");
66 return -EBADMSG;
67 }
68 phandle_val = strtoul(phandle_str, NULL, 16);
69
70 return phandle_val;
71}
72
73static int update_pwm_f_board_regulator(void) {
74 int ret = 0;
75 char cmdbuf[256] = {0};
76 unsigned int pwm_f_board0_phandle = 0;
77
78 pwm_f_board0_phandle = get_phandle("/pwm_f_board0-regulator");
79 memset(cmdbuf, 0, sizeof(cmdbuf));
80 sprintf(cmdbuf, "fdt set /meson-cpufreq cluster0-cpu-supply <0x%x>;", pwm_f_board0_phandle);
81 ret = run_command(cmdbuf, 0);
82 if (ret != 0) {
83 cmd_pdvfs_err("Error: Failed to update cluster0-cpu-supply.\n");
84 return -EBADMSG;
85 }
86 ret = set_regulator_status("/pwm_f_board0-regulator", "okay");
87 if (ret != 0) {
88 cmd_pdvfs_err("Error: Failed to set pwm_f_board0 okay\n");
89 return -EBADMSG;
90 }
91 ret = set_regulator_status("/pwm_f_board2-regulator", "disabled");
92 if (ret != 0) {
93 cmd_pdvfs_err("Error: Failed to set pwm_f_board2 disabled\n");
94 return -EBADMSG;
95 }
96
97 return 0;
98}
99
100
101static unsigned int get_cpufreq_table_index(u64 function_id,
102 u64 arg0, u64 arg1, u64 arg2)
103{
104 struct arm_smccc_res res;
105
106 arm_smccc_smc((unsigned long)function_id,
107 (unsigned long)arg0,
108 (unsigned long)arg1,
109 (unsigned long)arg2,
110 0, 0, 0, 0, &res);
111 return res.a0;
112}
113
114static int set_cpu_opp_tbl(void)
115{
116 int ret = 0;
117 unsigned int opp_table_0_phandle = 0;
118 unsigned int opp_table_1_phandle = 0;
119 unsigned int opp_table_2_phandle = 0;
120 unsigned int opp_table_3_phandle = 0;
121 char cmdbuf[256] = {0};
122
123 opp_table_0_phandle = get_phandle("/cpu_opp_table0");
124 opp_table_1_phandle = get_phandle("/cpu_opp_table1");
125 opp_table_2_phandle = get_phandle("/cpu_opp_table2_2000");
126 opp_table_3_phandle = get_phandle("/cpu_opp_table3_2000");
127 memset(cmdbuf, 0, sizeof(cmdbuf));
128 sprintf(cmdbuf, "fdt set /cpus/cpu@0 operating-points-v2 <0x%x 0x%x 0x%x 0x%x>;", \
129 opp_table_0_phandle, opp_table_1_phandle, \
130 opp_table_2_phandle, opp_table_3_phandle);
131 ret = run_command(cmdbuf, 0);
132 if (ret != 0) {
133 cmd_pdvfs_err("Error: Failed to update operating-points-v2/n");
134 return -EBADMSG;
135 }
136
137 return 0;
138}
139
140static int update_pdvfs_tbl(cmd_tbl_t *cmdtp, int flag, int argc,
141 char *const argv[])
142{
143 unsigned int ret = 0;
144 unsigned int board_id = 0;
145 unsigned int board_rev = 0;
146 unsigned int pdvfs_index = 0;
147
148 board_id = get_board_id();
149 board_rev = get_chip_rev();
150 pdvfs_index = get_cpufreq_table_index(GET_DVFS_TABLE_INDEX, 0, 0, 0);
151 cmd_pdvfs_info("update_pdvfs dtb\n");
152 if (board_id < 2) {
153 ret = update_pwm_f_board_regulator();
154 if (ret != 0)
155 cmd_pdvfs_err("fix_regulator_tbl fail\n");
156 ret = set_cpu_opp_tbl();
157 if (ret != 0)
158 cmd_pdvfs_err("fix_cpu_opp_tbl fail\n");
159 }
160 else if (board_id == 2) {
161 if (pdvfs_index == 0 || pdvfs_index == 1) {
162 ret = set_cpu_opp_tbl();
163 if (ret != 0)
164 cmd_pdvfs_err("fix_cpu_opp_tbl fail\n");
165 }
166 }
167 else
168 cmd_pdvfs_err("get board_id fail,board_id = %d\n", board_id);
169
170 return 0;
171}
172
173U_BOOT_CMD(
174 update_pdvfs, 1, 0, update_pdvfs_tbl,
175 "update pdvfs",
176 "set_regulator_tbl - set board_A regulator_pwm_tbl\n"
177 "set_cpu_opp_tbl - set 2.0g cpu_opp_tbl\n"
178);