Files
BPI-CM9-Linux/aml-comp/uboot/bl33/v2019/cmd/cmd_startm4.c
T

177 lines
4.5 KiB
C
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
/*
* common/cmd_startdsp.c
*
* Copyright (C) 2020 Amlogic, Inc. All rights reserved.
*
*/
#include <common.h>
#include <command.h>
#include <asm/arch/cpu.h>
#include <asm/arch/secure_apb.h>
#include <asm/arch/timer.h>
#include <asm/arch/bl31_apis.h>
#include <asm/arch/pwr_ctrl.h>
#include <serial.h>
#include <asm/arch-p1/register.h>
#define Wr(addr, data) *(volatile uint32_t *)(addr)=(data)
#define Rd(addr) *(volatile uint32_t *)(addr)
// .clk0 (cts_oscin_clk ),
// .clk1 (fclk_div2p5 ),
// .clk2 (fclk_div3 ),
// .clk3 (m4_pll_clk ),
// .clk4 (hifi_pll_clk ),
// .clk5 (fclk_div4 ),
// .clk6 (gp2_pll_clk ),
// .clk7 (cts_rtc_clk ),
void set_m4_clk(int sel, int div)
{
uint32_t reg_val = 0;
reg_val = Rd(CLKCTRL_M4_CLK_CTRL);
// enable osc_clk firstly
if (reg_val == 0) {
reg_val = (1 << 13);
Wr(CLKCTRL_M4_CLK_CTRL, reg_val); /* pre_a clock gate en */
}
reg_val = Rd(CLKCTRL_M4_CLK_CTRL);
if (reg_val & (1 << 15)) {
/* Pre_a source select M4_PLL, pre_a clock gate en, Pre_a div5 */
reg_val = (reg_val & ~((0x7 << 10) | (1 << 13) | (0x3ff << 0)))
| ((sel << 10) | (0 << 13) | (div << 0));
Wr(CLKCTRL_M4_CLK_CTRL, reg_val);
reg_val = (reg_val & ~((0x7 << 10) | (1 << 13) | (0x3ff << 0)))
| ((sel << 10) | (1 << 13) | (div << 0));
Wr(CLKCTRL_M4_CLK_CTRL, reg_val);
/* select pre_a */
reg_val = Rd(CLKCTRL_M4_CLK_CTRL);
reg_val &= ~(1 << 15);
Wr(CLKCTRL_M4_CLK_CTRL, reg_val);
} else {
/* Pre_b source select M4_PLL, pre_b clock gate en, Pre_b div5 */
reg_val = (reg_val & ~((0x7 << 26) | (1 << 29) | (0x3ff << 16)))
| ((sel << 26) | (0 << 29) | (div << 16));
Wr(CLKCTRL_M4_CLK_CTRL, reg_val);
reg_val = (reg_val & ~((0x7 << 26) | (1 << 29) | (0x3ff << 16)))
| ((sel << 26) | (1 << 29) | (div << 16));
Wr(CLKCTRL_M4_CLK_CTRL, reg_val);
/* select pre_b */
reg_val = Rd(CLKCTRL_M4_CLK_CTRL);
reg_val |= (1 << 15);
Wr(CLKCTRL_M4_CLK_CTRL, reg_val);
}
}
void set_m4_pll_clk(uint32_t freq)
{
uint32_t M, N, OD = 0;
uint32_t reg_cntl0;
for (int i = 0; i < 6; i++) {
if ((freq << i) >= 1600 && (freq << i) < 3200) {
OD = i;
break;
}
}
M = ((freq + 12) << OD) / 24;
N = 1;
reg_cntl0 = (OD << 12) | (N << 16) | M;
Wr(CLKCTRL_M4PLL_CTRL0, (0x2 << 28) | reg_cntl0); // reset pll
Wr(CLKCTRL_M4PLL_CTRL0, (0x3 << 28) | reg_cntl0); // reset + en
Wr(CLKCTRL_M4PLL_CTRL1, 0x1420500f);
Wr(CLKCTRL_M4PLL_CTRL2, 0x00023041);
Wr(CLKCTRL_M4PLL_CTRL3, 0x00000000);
Wr(CLKCTRL_M4PLL_CTRL0, (0x1 << 28) | reg_cntl0); // release reset
Wr(CLKCTRL_M4PLL_CTRL2, 0x00023001);
while ((Rd(CLKCTRL_M4PLL_STS) & 0x80000000) == 0)
;
}
static int do_startm4(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
uint32_t cpu_id;
uint32_t bin_addr;
uint32_t bank_config;
uint32_t id;
uint32_t cmd;
int ret = 0;
if (argc != 5) {
printf("Plese input M4 boot args:cpu_id, bin_addr!\n");
return CMD_RET_USAGE;
}
cpu_id = simple_strtoul(argv[1], NULL, 16);
bin_addr = simple_strtoul(argv[2], NULL, 16);
bank_config = simple_strtoul(argv[3], NULL, 16);
cmd = simple_strtoul(argv[4], NULL, 16);
if (bank_config == 0u) {
/*default:M4A_ROM=M4A_RAM=M4B_ROM=M4B_RAM=128K */
bank_config = 0xFCB87430u;
}
if (cpu_id >= 2) {
printf("\nPlese input M4 boot cpu_id less than 2!");
return CMD_RET_USAGE;
}
if (bin_addr & 0x3u) {
printf("Plese load the bin in ddr address in word(4 bytes) align.\n");
return CMD_RET_USAGE;
}
if (cpu_id == 0) {
printf("M4A is boot, cpu_id:%d\n", cpu_id);
printf("M4A bin address:0x%x\n", bin_addr);
} else {
printf("M4B is boot, cpu_id:%d\n", cpu_id);
printf("M4B bin address:0x%x\n", bin_addr);
}
if (cmd == MFH_V2_START) {
/*hold reset M4 */
id = PACK_SMC_SUBID_ID(MFH_V2_RESET, cpu_id);
start_m4(id, bin_addr, bank_config);
if (cpu_id == 0) {
/*repower on cpu */
pwr_ctrl_psci_smc(PM_M4A, 1);
} else {
/*repower on cpu */
pwr_ctrl_psci_smc(PM_M4B, 1);
}
/* 300MHz */
set_m4_clk(3u, 4u);
set_m4_pll_clk(1500);
id = PACK_SMC_SUBID_ID(cmd, cpu_id);
start_m4(id, bin_addr, bank_config);
} else {
id = PACK_SMC_SUBID_ID(MFH_V2_RESET, cpu_id);
start_m4(id, bin_addr, bank_config);
}
return ret;
}
U_BOOT_CMD(
startm4, 5, 1, do_startm4,
"load bin from DDR memory address(soc: p1) ",
"\narg[0]: cmd\n"
"arg[1]: cpu_id, the cpu id 0 is start M4A, the cpu id 1 is start M4B\n"
"arg[2]: bin_ddr, load execution bin from ddr memory address\n"
"arg[3]: bank config, default:0xFCB87430u\n"
"arg[4]: cmd, 0x21--START, 0x22--STOP, 0x22--RESET\n"
);