blob: d7cb4f50251366626039ce5e993df108a7fb175b [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
Liming Xuefe754dc2024-11-20 10:57:19 +080018int get_board_id(void)
chao.zhang44883592024-09-25 14:47:29 +080019{
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) {
Liming Xuefe754dc2024-11-20 10:57:19 +080042 cmd_pdvfs_err("Error: Failed to set regulator status\n");
43 return -EBADMSG;
44 }
chao.zhang44883592024-09-25 14:47:29 +080045
Liming Xuefe754dc2024-11-20 10:57:19 +080046 return 0;
chao.zhang44883592024-09-25 14:47:29 +080047}
48
Liming Xuefe754dc2024-11-20 10:57:19 +080049int get_phandle(const char *path) {
50 int ret = 0;
51 char cmdbuf[256] = {0};
chao.zhang44883592024-09-25 14:47:29 +080052 char *phandle_str = NULL;
53 unsigned int phandle_val = 0;
54
Liming Xuefe754dc2024-11-20 10:57:19 +080055 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 }
chao.zhang44883592024-09-25 14:47:29 +080062
Liming Xuefe754dc2024-11-20 10:57:19 +080063 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 }
chao.zhang44883592024-09-25 14:47:29 +080068 phandle_val = strtoul(phandle_str, NULL, 16);
69
Liming Xuefe754dc2024-11-20 10:57:19 +080070 return phandle_val;
chao.zhang44883592024-09-25 14:47:29 +080071}
72
73static int update_pwm_f_board_regulator(void) {
Liming Xuefe754dc2024-11-20 10:57:19 +080074 int ret = 0;
75 char cmdbuf[256] = {0};
chao.zhang44883592024-09-25 14:47:29 +080076 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
Liming Xuefe754dc2024-11-20 10:57:19 +080097 return 0;
chao.zhang44883592024-09-25 14:47:29 +080098}
99
100
Liming Xuefe754dc2024-11-20 10:57:19 +0800101unsigned int get_cpufreq_table_index(u64 function_id,
102 u64 arg0, u64 arg1, u64 arg2)
chao.zhang44883592024-09-25 14:47:29 +0800103{
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");
Liming Xuefe754dc2024-11-20 10:57:19 +0800127
chao.zhang44883592024-09-25 14:47:29 +0800128 memset(cmdbuf, 0, sizeof(cmdbuf));
129 sprintf(cmdbuf, "fdt set /cpus/cpu@0 operating-points-v2 <0x%x 0x%x 0x%x 0x%x>;", \
130 opp_table_0_phandle, opp_table_1_phandle, \
131 opp_table_2_phandle, opp_table_3_phandle);
132 ret = run_command(cmdbuf, 0);
133 if (ret != 0) {
134 cmd_pdvfs_err("Error: Failed to update operating-points-v2/n");
135 return -EBADMSG;
136 }
137
138 return 0;
139}
140
141static int update_pdvfs_tbl(cmd_tbl_t *cmdtp, int flag, int argc,
142 char *const argv[])
143{
144 unsigned int ret = 0;
145 unsigned int board_id = 0;
146 unsigned int board_rev = 0;
147 unsigned int pdvfs_index = 0;
148
149 board_id = get_board_id();
150 board_rev = get_chip_rev();
151 pdvfs_index = get_cpufreq_table_index(GET_DVFS_TABLE_INDEX, 0, 0, 0);
152 cmd_pdvfs_info("update_pdvfs dtb\n");
153 if (board_id < 2) {
154 ret = update_pwm_f_board_regulator();
155 if (ret != 0)
156 cmd_pdvfs_err("fix_regulator_tbl fail\n");
157 ret = set_cpu_opp_tbl();
158 if (ret != 0)
159 cmd_pdvfs_err("fix_cpu_opp_tbl fail\n");
160 }
161 else if (board_id == 2) {
162 if (pdvfs_index == 0 || pdvfs_index == 1) {
163 ret = set_cpu_opp_tbl();
164 if (ret != 0)
165 cmd_pdvfs_err("fix_cpu_opp_tbl fail\n");
166 }
167 }
168 else
Liming Xuefe754dc2024-11-20 10:57:19 +0800169 cmd_pdvfs_err("get board_id fail,board_id = %d\n", board_id);
chao.zhang44883592024-09-25 14:47:29 +0800170
171 return 0;
172}
173
174U_BOOT_CMD(
175 update_pdvfs, 1, 0, update_pdvfs_tbl,
176 "update pdvfs",
177 "set_regulator_tbl - set board_A regulator_pwm_tbl\n"
178 "set_cpu_opp_tbl - set 2.0g cpu_opp_tbl\n"
179);