Files
thead-uboot/board/thead/ice-c860/spl/clock.c
2022-09-13 11:04:33 +08:00

345 lines
10 KiB
C

/*
* Copyright (C) 2017-2020 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: GPL-2.0+
*/
/*************************************************
ENABLED CLOCKs
OSC_CLK = 24MHz
CK810 core_clock = 1GHz
AXI Bus clock = 500MHz
AHB clock = 250MHz(middle-speed peripherals, SFC/SDIO/GMAC/I2S/RDMA..)
CFG_APB clock = 125MHz (CAN, DDR/USB/PCIe PHY...)
PERI_APB clock = 62.5MHz (most of low-speed peripherals, timer/uart/i2c...)
IAS(8core) core_clock = 700MHz
DDR core_clock = 664MHz, 2666MT mode
SDIO0/1 cclk = 100MHz (software should drived cclk_out=25/50MHz in sd_ctrl)
//C910/C860 = 1GHz
//BUS
GATED CLOCK:
1)CK810 core_clock: enable in software driver when needed
2)VIDEO: enable in software driver when needed
3)SCE: enable in software driver when needed
4)I2S/PCIE/USB/GMAC: enable in software driver when needed
*************************************************/
void sys_clk_config(int cpu_freq, int ddr_freq)
{
unsigned int read,i;
for(i=0;i<0x40;i++){
*(volatile unsigned int*)(0xfff78040) = 0x0; //reset ddr
}
//Wait ALL PLLs lock
read = *(volatile unsigned int*)(0xfff77060);
while ((read & 0x1f) != 0x1f) {
read = *(volatile unsigned int*)(0xfff77060);
}
//enable dpu_clk
*(volatile unsigned int*)(0xfff77098) = 0x01601212;//div en
*(volatile unsigned int*)(0xfff77098) = 0x11611212;//pixclk_en, hclk_en
//enable gpu_clk, 500MHz/500MHz
*(volatile unsigned int*)(0xfff7709c) = 0x11212; //gpu_hclk_en, gpu_aclk_div, gpu_cclk_div
//***********************
//C810 DIV
//BUS DIV
//CPU_CNT DIV
//***********************
//C810_CLK=OSC_CLK, BUS_CLK=OSC_CLK/2, CNT_CLK=OSC_CLK/8
*(volatile unsigned int*)(0xfff77070) = 0x871; //AXI BUS 2:1
read = *(volatile unsigned int*)(0xfff77070); //wait
*(volatile unsigned int*)(0xfff77070) = 0x879; //sync
asm("nop"); //MUST NOT REVISE
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
//***********************
//hclk DIV
//cfg_pclk DIV
//peri_pclk DIV
//***********************
//HCLK=OSC_CLK, peri_pclk=OSC_CLK/4, cfg_pclk=OSC_CLK/2
*(volatile unsigned int*)(0xfff77090) = 0x1302;
read = *(volatile unsigned int*)(0xfff77090); //wait
*(volatile unsigned int*)(0xfff77090) = 0x9b0a; //sync
asm("nop"); //MUST NOT REVISE
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
//***********************
//C810_CLK=1GHz, BUS_CLK=500MHz, CNT_CLK=125MHz
//HCLK=250MHz, peri_clk=62.5MHz, cfg_clk=125MHz
//***********************
*(volatile unsigned int*)(0xfff77070) = 0x809;
asm("nop"); //MUST NOT REVISE
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
//PLLF, C910/C860 clock
switch (cpu_freq) {
case 2000:
*(volatile unsigned int*)(0xfff7704c) = 0x0110fa03; //2000MHz, 2000MHz
break;
case 1900:
*(volatile unsigned int*)(0xfff7704c) = 0x01104f01; //1896MHz, 1896MHz
break;
case 1800:
*(volatile unsigned int*)(0xfff7704c) = 0x01104b01; //1800MHz, 1800MHz
break;
case 1700:
*(volatile unsigned int*)(0xfff7704c) = 0x01104701; //1704MHz, 1704MHz
break;
case 1600:
*(volatile unsigned int*)(0xfff7704c) = 0x0110c803; //1600MHz, 1600MHz
break;
case 1500:
*(volatile unsigned int*)(0xfff7704c) = 0x01107d02; //1500MHz, 1500MHz
break;
case 1400:
*(volatile unsigned int*)(0xfff7704c) = 0x01103a01; //1392MHz, 1392MHz
break;
case 1300:
*(volatile unsigned int*)(0xfff7704c) = 0x01103601; //1296MHz, 1296MHz
break;
case 1200: //max legal freq for the ICE
*(volatile unsigned int*)(0xfff7704c) = 0x01103201; //1200MHz, 1200MHz
break;
case 1100:
*(volatile unsigned int*)(0xfff7704c) = 0x01205b01; //2184MHz, 1092MHz
break;
case 1000:
*(volatile unsigned int*)(0xfff7704c) = 0x0120fa03; //2000MHz, 1000MHz
break;
case 900:
*(volatile unsigned int*)(0xfff7704c) = 0x01204b01; //1800MHz, 900MHz
break;
case 800:
*(volatile unsigned int*)(0xfff7704c) = 0x0120c803; //1600MHz, 800MHz
break;
case 700:
*(volatile unsigned int*)(0xfff7704c) = 0x01203a01; //1392MHz, 696MHz
break;
case 600:
*(volatile unsigned int*)(0xfff7704c) = 0x01203201; //1200MHz, 600MHz
break;
case 500:
*(volatile unsigned int*)(0xfff7704c) = 0x0140fa03; //2000MHz, 500MHz
break;
}
*(volatile unsigned int*)(0xfff77050) = 0x03000000;
*(volatile unsigned int*)(0xfff77054) = 0x3; //reconfig
read = *(volatile unsigned int*)(0xfff7704c); //readback
//Wait ALL PLLs Lock
read = *(volatile unsigned int*)(0xfff77060);
read = *(volatile unsigned int*)(0xfff77060);
read = *(volatile unsigned int*)(0xfff77060);
while ((read & 0x3f) != 0x3f) {
read = *(volatile unsigned int*)(0xfff77060);
}
////***********************
////C910 core_clk=24MHz, bus_clk=12MHz
////***********************
////C910_CLK=OSC_CLK, BUS_CLK=OSC_CLK/2
//*(volatile unsigned int*)(0xfe830470) = 0x11; //AXI BUS 2:1
//read = *(volatile unsigned int*)(0xfe830470); //wait
//*(volatile unsigned int*)(0xfe830470) = 0x19; //sync
//asm("nop"); //MUST NOT REVISE
//asm("nop");
//asm("nop");
//asm("nop");
//asm("nop");
//asm("nop");
//asm("nop");
//asm("nop");
//asm("nop");
//asm("nop");
////C910 clock switch from OSC to PLLF
//*(volatile unsigned int*)(0xfe830470) = 0x9; //switch
//asm("nop"); //MUST NOT REVISE
//asm("nop");
//asm("nop");
//asm("nop");
//asm("nop");
//asm("nop");
//asm("nop");
//asm("nop");
//asm("nop");
//***********************
//C860 core_clk=24MHz, bus_clk=12MHz
//***********************
//C860_CLK=OSC_CLK, BUS_CLK=OSC_CLK/2
*(volatile unsigned int*)(0xfe83046c) = 0x11; //AXI BUS 2:1
read = *(volatile unsigned int*)(0xfe83046c); //wait
*(volatile unsigned int*)(0xfe83046c) = 0x19; //sync
asm("nop"); //MUST NOT REVISE
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
//C860 clock switch from OSC to PLLF(1GHz)
*(volatile unsigned int*)(0xfe83046c) = 0x9; //switch
asm("nop"); //MUST NOT REVISE
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
//////enable C860
//////*(volatile unsigned int*)(0xfe830470) = 0x29; //switch
//enable all hclk(250MHz)
*(volatile unsigned int*)(0xfff77094) = 0xffffffff;
//enable all ias_clk(700MHz)
//*(volatile unsigned int*)(0xfff77030) = 0x0160af02; //plld, 350MHz
//*(volatile unsigned int*)(0xfff77038) = 0x2; //re-config
*(volatile unsigned int*)(0xfff770a0) = 0xfff;
*(volatile unsigned int*)(0xfff78044) = 0xff;
//SDIO0/1
*(volatile unsigned int*)(0xfff77078) = 0x0c800c80;
//DDRC clock
switch (ddr_freq) {
case 3192:
*(volatile unsigned int*)(0xfff77020) = 0x01208502; //798MHz, 3192MT
break;
case 3008:
*(volatile unsigned int*)(0xfff77020) = 0x01305e01; //752MHz, 3008MT
break;
case 2912:
*(volatile unsigned int*)(0xfff77020) = 0x01305b01; //728MHz, 2912MT
break;
case 2816:
*(volatile unsigned int*)(0xfff77020) = 0x01305801; //704MHz, 2816MT
break;
case 2720:
*(volatile unsigned int*)(0xfff77020) = 0x01305501; //680MHz, 2720MT
break;
case 2656:
*(volatile unsigned int*)(0xfff77020) = 0x01305301; //664MHz, 2656MT
break;
case 2592:
*(volatile unsigned int*)(0xfff77020) = 0x01305101; //648MHz, 2592MT
break;
case 2496:
*(volatile unsigned int*)(0xfff77020) = 0x01304e01; //624MHz, 2496MT
break;
case 2400:
*(volatile unsigned int*)(0xfff77020) = 0x01406401; //600MHz, 2400MT
break;
case 2184:
*(volatile unsigned int*)(0xfff77020) = 0x01405b01; //546MHz, 2184MT
break;
case 2133:
*(volatile unsigned int*)(0xfff77020) = 0x01405801; //528MHz, 2112MT
break;
case 2000:
*(volatile unsigned int*)(0xfff77020) = 0x01607d01; //500MHz, 2000MT
break;
case 1800:
*(volatile unsigned int*)(0xfff77020) = 0x01404b01; //450MHz, 1800MT
break;
case 1600:
*(volatile unsigned int*)(0xfff77020) = 0x01606401; //400MHz, 1600MT
break;
case 1392:
*(volatile unsigned int*)(0xfff77020) = 0x01605701; //348MHz, 1392MT
break;
default:
*(volatile unsigned int*)(0xfff77020) = 0x01604b01; //300MHz, 1200MT
break;
}
*(volatile unsigned int*)(0xfff77024) = 0x03000000;
*(volatile unsigned int*)(0xfff77028) = 0x3; //reconfig
read = *(volatile unsigned int*)(0xfff77020); //readback
//Wait ALL PLLs Lock
read = *(volatile unsigned int*)(0xfff77060);
read = *(volatile unsigned int*)(0xfff77060);
read = *(volatile unsigned int*)(0xfff77060);
while ((read & 0x1f) != 0x1f) {
read = *(volatile unsigned int*)(0xfff77060);
}
//enable ddr_axi clocks
*(volatile unsigned int*)(0xfff78040) = 0x0;
*(volatile unsigned int*)(0xfff78040) = 0x0;
*(volatile unsigned int*)(0xfff78040) = 0x0;
*(volatile unsigned int*)(0xfff78040) = 0x0;
*(volatile unsigned int*)(0xfff77108) = 0x1ff;
*(volatile unsigned int*)(0xfff77108) = 0x1ff;
*(volatile unsigned int*)(0xfff77108) = 0x1ff;
*(volatile unsigned int*)(0xfff78040) = 0x0;
*(volatile unsigned int*)(0xfff78040) = 0x0;
*(volatile unsigned int*)(0xfff78040) = 0x0;
*(volatile unsigned int*)(0xfff78040) = 0x0;
*(volatile unsigned int*)(0xfff78040) = 0x9;
*(volatile unsigned int*)(0xfff78040) = 0x9;
//disable wdg
*(volatile unsigned int*)(0xfff78000) = 0x5ada7200;
*(volatile unsigned int*)(0xfff78010) = 0x0;
}