blob: b4da8aef85d67f466031b7a93b65f457b830dc0e [file] [log] [blame]
bangzheng.liuacb070d2024-01-15 14:05:04 +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/amlogic/arch/register.h>
9#include <asm/amlogic/arch/bl31_apis.h>
10#include <asm/amlogic/arch/pwr_ctrl.h>
11#include <serial.h>
12
13// --------------------------------------------------
14// set_dsp_clk
15// --------------------------------------------------
16
17/*
18 * set_dsp_clk
19 * freq_sel:
20 * [ for S6 ]
21 * 0: 1000MHz gp2_pll
22 * 1: 800MHz fclk_div2p5
23 * 2: 666.67MHz fclk_div3
24 * 3: 24MHz oscin
25 * 4: 500MHz fclk_div4
26 * 5: 400MHz fclk_div2p5/2
27 * 6: 333MHz fclk_div3/2
28 * 7: 250MHz fclk_div4/2
29 * 8: 200MHz fclk_div5/2
30 * 9: 100MHz fclk_div5/4
31 * 10: 245.76MHz hifi_pll/2
32 * default: 800MHz fclk_div2p5
33 */
34
35int set_dsp_clk(uint32_t id, uint32_t freq_sel)
36{
37 uint32_t control;
38 uint32_t clk_sel;
39 uint32_t clk_div;
40 uint32_t addr = 0;
41 char *dsp_clk_tag = NULL;
42 int ret = 0;
43
44 switch (id) {
45 case 0:
46 addr = CLKCTRL_DSPA_CLK_CTRL0;
47 break;
48 default:
49 ret = -1;
50 break;
51 }
52
53 if (ret) {
54 printf("dsp clk set failed: invalid id %d\n", id);
55 return ret;
56 }
57
58 // Make sure not busy from last setting and we currently match the last setting
59
60 control = readl(addr);
61 printf("CLKCTRL_DSP_CLK_CTRL0 = %x\n", readl(addr));
62
63 switch (freq_sel) {
64 case 0:
65 clk_sel = 4;
66 clk_div = 0;
67 dsp_clk_tag = "gp2_pll:1000MHz";
68 break;
69 case 1:
70 clk_sel = 1;
71 clk_div = 0;
72 dsp_clk_tag = "fclk_div2p5:800MHz";
73 break;
74 case 2:
75 clk_sel = 2;
76 clk_div = 0;
77 dsp_clk_tag = "fclk_div3:666.67MHz";
78 break;
79 case 3:
80 clk_sel = 0;
81 clk_div = 0;
82 dsp_clk_tag = "oscin:24MHz";
83 break;
84 case 4:
85 clk_sel = 5;
86 clk_div = 0;
87 dsp_clk_tag = "fclk_div4:500MHz";
88 break;
89 case 5:
90 clk_sel = 3;
91 clk_div = 0;
92 dsp_clk_tag = "fclk_div5:400MHz";
93 break;
94 case 6:
95 clk_sel = 2;
96 clk_div = 1;
97 dsp_clk_tag = "fclk_div3/2:333MHz";
98 break;
99 case 7:
100 clk_sel = 5;
101 clk_div = 1;
102 dsp_clk_tag = "fclk_div4/2:250MHz";
103 break;
104 case 8:
105 clk_sel = 3;
106 clk_div = 1;
107 dsp_clk_tag = "fclk_div2p5/2:200MHz";
108 break;
109 case 9:
110 clk_sel = 3;
111 clk_div = 3;
112 dsp_clk_tag = "fclk_div5/4:100MHz";
113 break;
114 case 10:
115 clk_sel = 6;
116 clk_div = 1;
117 dsp_clk_tag = "hifi_pll/2:245.76MHz";
118 break;
119 default:
120 clk_sel = 1;
121 clk_div = 0;
122 dsp_clk_tag = "fclk_div2p5:800MHz (default)";
123 break;
124 }
125
126 printf("CLK_UTIL:dsp[%d]:%s\n", id, dsp_clk_tag);
127
128 if (control & (1 << 15)) { //if sync_mux ==1, sel mux 0
129 control = (control & ~((1 << 15) | (0x3ff << 0) | (0x7 << 10))) |
130 (1 << 13) | (1 << 29) | (clk_div << 0) | (clk_sel << 10);
131 } else {
132 control = (control & ~((1 << 15) | (0x3ff << 16) | (0x7 << 26))) |
133 (1 << 13) | (1 << 29) | (clk_div << 16) | (clk_sel << 26) | (1 << 15);
134 }
135
136 writel(control, addr);
137
138 if (id == 0)
139 printf("CLKCTRL_DSPA_CLK_CTRL0 = %x\n", readl(addr));
140
141 return ret;
142}
143
144static int do_startdsp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
145{
146 uint32_t dspid;
147 uint32_t addr;
148 uint32_t freq_sel;
149 uint32_t bus_cfg;
150 uint32_t cfg0;
151 uint32_t StatVectorSel;
152 uint32_t strobe = 1;
153
154 if (argc <= 1) {
155 printf("please input dsp boot args: id, address, clk!\n");
156 return CMD_RET_USAGE;
157 }
158
159 dspid = simple_strtoul(argv[1], NULL, 16);
160 if (dspid > 1) {
161 printf("start dsp failed: invalid id\n");
162 return -1;
163 }
164
165 addr = simple_strtoul(argv[2], NULL, 16);
166 freq_sel = simple_strtoul(argv[3], NULL, 16);
167
168 printf("dsp%d boot\n", dspid);
169 printf("dspboot start address: 0x%x\n", addr);
170 printf("dsp clk num:%d\n", freq_sel);
171
172 StatVectorSel = (addr != 0xfffa0000);
173 cfg0 = 0x1 | StatVectorSel << 1 | strobe << 2;
174
175 power_set_dsp(PDID_DSPA, PWR_ON);
176
177 udelay(100);
178
179 if (set_dsp_clk(dspid, freq_sel))
180 return -1;
181
182 udelay(100);
183
184 init_dsp(dspid, addr, cfg0, bus_cfg);
185 printf("dsp init over!\n");
186
187 return 0;
188}
189
190U_BOOT_CMD(
191 startdsp, 5, 1, do_startdsp,
192 "load dspboot.bin from address",
193 "\narg[0]: cmd\n"
194 "arg[1]: dspid\n"
195 "arg[2]: dspboot.bin load address!\n"
196 "arg[3]: dsp clk set\n 0:1G 1:800M 2:667M 3:24M 4:500M 5:400M 6:333M 7:250M 8:200M 9:100M 10:245.76M\n"
197 "arg[4]: bus select for dsp access one 4G of 16G ddr: 0x00: 0~4G 0x01: 4~8G 0x10: 8~12G 0x11: 12~16G\n"
198);
199