blob: f03b2773190c09b3a5253672d85df4e1107580ad [file] [log] [blame]
/*
* common/cmd_reboot.c
*
* Copyright (C) 2015 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#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/register.h>
#include <serial.h>
/*
* clk_util_set_dsp_clk
* freq_sel:
* 1:400MHz fclk_5
* 2:500MHz fclk_2/2
* 4:333MHz fclk_3/2
* 5:250Mhz fclk_2/4
* 6:200Mhz fclk_5/2
* 7:100Mhz fclk_5/4
* 8:24Mhz oscin
* 10:3Mhz oscin/8
* others:400MHz fclk_5
*/
// --------------------------------------------------
// clk_util_set_dsp_clk
// --------------------------------------------------
void clk_util_set_dsp_clk(uint32_t id, uint32_t freq_sel)
{
uint32_t control;
uint32_t clk_sel;
uint32_t clk_div;
uint32_t addr;
switch ( id ) {
case 0: addr = CLKTREE_DSPA_CLK_CTRL0;break;
default : addr = CLKTREE_DSPB_CLK_CTRL0;break;
}
// Make sure not busy from last setting and we currently match the last setting
control = readl(addr);
pr_info("CLKTREE_DSP_CLK_CTRL0 value 0x%x \n",control);
switch (freq_sel)
{
case 1 : clk_sel = 3; clk_div =0; pr_info ("CLK_UTIL:dsp[%d]:fclk5:400MHz\n" ,id); break;
case 2 : clk_sel = 1; clk_div =1; pr_info ("CLK_UTIL:dsp[%d]:fclk2/2:500MHz\n" ,id); break;
//case 3 : clk_sel = 1; clk_div =0; printf ("CLK_UTIL:dsp[%d]:fclk/3:667MHz\n" ,id); break;
case 4 : clk_sel = 2; clk_div =1; pr_info ("CLK_UTIL:dsp[%d]:fclk3/2:333MHz\n" ,id); break;
case 5 : clk_sel = 1; clk_div =3; pr_info ("CLK_UTIL:dsp[%d]:fclk2/4:250MHz\n",id); break;
case 6 : clk_sel = 3; clk_div =1; pr_info ("CLK_UTIL:dsp[%d]:fclk5/2:200MHz\n",id); break;
case 7 : clk_sel = 3; clk_div =3; pr_info ("CLK_UTIL:dsp[%d]:fclk5/4:100MHz\n",id); break;
case 8 : clk_sel = 0; clk_div =0; pr_info ("CLK_UTIL:dsp[%d]:oscin:24MHz\n",id); break;
case 10 : clk_sel = 0; clk_div =7; pr_info ("CLK_UTIL:dsp[%d]:oscin/8:3MHz\n",id); break;
default : clk_sel = 3; clk_div =0; pr_info ("CLK_UTIL:dsp[%d]:fclk5:400MHz\n" ,id); break;
}
if (control & (1 << 15)) { //if sync_mux ==1, sel mux 0
control = (control & ~( ( 1<<15) | (0x3ff<<0) | (0x7 <<10) ) ) | (1<<13)| (1<<29) | (clk_div<<0) | (clk_sel<<10);
} else {
control = (control & ~( ( 1<<15) | (0x3ff<<16) | (0x7 <<26) ) ) | (1<<13)| (1<<29) | (clk_div<<16) | (clk_sel<<26) | (1<<15);
}
pr_info("CLKTREE_DSP_CLK_CTRL0 value 0x%x \n",control);
writel(control,addr);
pr_info("CLKTREE_DSP_CLK_CTRL0 value 0x%x \n",readl(addr));
}
void dsp_clk_init(unsigned int dspid, uint32_t freq_sel) {
clk_util_set_dsp_clk(dspid, freq_sel);
}
void dsp_power_set(unsigned int dspid, uint32_t powerflag) {
pr_info("power DSP, Audio \n");
power_set_dsp(dspid, powerflag);
if (powerflag) {
power_set_ctl(PDID_ACODEC, powerflag);//audio
power_set_ctl(PDID_AUDIO, powerflag);//audio
power_set_ctl(PDID_PDM, powerflag);//pdm
}
}
static int do_dspset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
unsigned long addr;
unsigned int dspid;
uint32_t freq_sel;
uint32_t powerflag;
int ret=0;
if (argc <= 1) {
pr_err("plese input dsp boot args:id, addrss, clk!\n");
return CMD_RET_USAGE;
}
dspid = simple_strtoul(argv[1], NULL, 16);
freq_sel = simple_strtoul(argv[2], NULL, 16);
powerflag = simple_strtoul(argv[3], NULL, 16);
pr_info("dsp%d boot \n",dspid);
pr_info("dsp clk num:%d\n",freq_sel);
if (powerflag == 1)
pr_info("power on dsp init \n");
else
pr_info("power off dsp init \n");
// writel32(readl(CLKTREE_SYS_CLK_EN0) | (1<<30),CLKTREE_SYS_CLK_EN0);
// printf("CLKTREE_SYS_CLK_EN0 value 0x%x \n",readl(CLKTREE_SYS_CLK_EN0));
dsp_clk_init(dspid, freq_sel);
udelay(20);
dsp_power_set(dspid, powerflag);
pr_info("dsp init CLK, power over! \n");
return ret;
}
U_BOOT_CMD(
dspset, 4, 1, do_dspset,
"set dsp clk, power domain",
"\n arg[0]: cmd\n"
"arg[1]: dspid \n"
"arg[2]: dsp clk set 1:400M 2:500M 4:333M 5:250M 6:200M 7:100M 8 :24M \n"
"arg[3]: power on [1] / power off [0]"
);