2020-04-21 07:28:34 +00:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
|
|
|
/*
|
|
|
|
* Copyright (C) 2020 MediaTek Inc.
|
|
|
|
*
|
|
|
|
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <common.h>
|
|
|
|
#include <clk.h>
|
|
|
|
#include <dm.h>
|
|
|
|
#include <dm/uclass.h>
|
|
|
|
#include <dt-bindings/clock/mt7628-clk.h>
|
|
|
|
#include <linux/io.h>
|
|
|
|
#include "mt7628.h"
|
|
|
|
|
|
|
|
DECLARE_GLOBAL_DATA_PTR;
|
|
|
|
|
|
|
|
static void set_init_timer_freq(void)
|
|
|
|
{
|
|
|
|
void __iomem *sysc;
|
|
|
|
u32 bs, val, timer_freq_post;
|
|
|
|
|
|
|
|
sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
|
|
|
|
|
|
|
|
/* We can't use the clk driver as the DM has not been initialized yet */
|
|
|
|
bs = readl(sysc + SYSCTL_SYSCFG0_REG);
|
|
|
|
if ((bs & XTAL_FREQ_SEL) == XTAL_25MHZ) {
|
|
|
|
gd->arch.timer_freq = 25000000;
|
|
|
|
timer_freq_post = 575000000;
|
|
|
|
} else {
|
|
|
|
gd->arch.timer_freq = 40000000;
|
|
|
|
timer_freq_post = 580000000;
|
|
|
|
}
|
|
|
|
|
|
|
|
val = readl(sysc + SYSCTL_CLKCFG0_REG);
|
|
|
|
if (!(val & (CPU_PLL_FROM_BBP | CPU_PLL_FROM_XTAL)))
|
|
|
|
gd->arch.timer_freq = timer_freq_post;
|
|
|
|
}
|
|
|
|
|
|
|
|
void mt7628_init(void)
|
|
|
|
{
|
|
|
|
set_init_timer_freq();
|
|
|
|
|
|
|
|
mt7628_ddr_init();
|
|
|
|
}
|
|
|
|
|
|
|
|
int print_cpuinfo(void)
|
|
|
|
{
|
|
|
|
void __iomem *sysc;
|
|
|
|
struct udevice *clkdev;
|
|
|
|
u32 val, ver, eco, pkg, ddr, chipmode, ee;
|
|
|
|
ulong cpu_clk, bus_clk, xtal_clk, timer_freq;
|
|
|
|
struct clk clk;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
|
|
|
|
|
|
|
|
val = readl(sysc + SYSCTL_CHIP_REV_ID_REG);
|
|
|
|
ver = (val & VER_M) >> VER_S;
|
|
|
|
eco = (val & ECO_M) >> ECO_S;
|
|
|
|
pkg = !!(val & PKG_ID);
|
|
|
|
|
|
|
|
val = readl(sysc + SYSCTL_SYSCFG0_REG);
|
|
|
|
ddr = val & DRAM_TYPE;
|
|
|
|
chipmode = (val & CHIP_MODE_M) >> CHIP_MODE_S;
|
|
|
|
|
|
|
|
val = readl(sysc + SYSCTL_EFUSE_CFG_REG);
|
|
|
|
ee = val & EFUSE_MT7688;
|
|
|
|
|
|
|
|
printf("CPU: MediaTek MT%u%c ver:%u eco:%u\n",
|
|
|
|
ee ? 7688 : 7628, pkg ? 'A' : 'K', ver, eco);
|
|
|
|
|
|
|
|
printf("Boot: DDR%s, SPI-NOR %u-Byte Addr, CPU clock from %s\n",
|
|
|
|
ddr ? "" : "2", chipmode & 0x01 ? 4 : 3,
|
|
|
|
chipmode & 0x02 ? "XTAL" : "CPLL");
|
|
|
|
|
2020-12-29 03:34:56 +00:00
|
|
|
ret = uclass_get_device_by_driver(UCLASS_CLK, DM_DRIVER_GET(mt7628_clk),
|
2020-04-21 07:28:34 +00:00
|
|
|
&clkdev);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
clk.dev = clkdev;
|
|
|
|
|
|
|
|
clk.id = CLK_CPU;
|
|
|
|
cpu_clk = clk_get_rate(&clk);
|
|
|
|
|
|
|
|
clk.id = CLK_SYS;
|
|
|
|
bus_clk = clk_get_rate(&clk);
|
|
|
|
|
|
|
|
clk.id = CLK_XTAL;
|
|
|
|
xtal_clk = clk_get_rate(&clk);
|
|
|
|
|
|
|
|
clk.id = CLK_MIPS_CNT;
|
|
|
|
timer_freq = clk_get_rate(&clk);
|
|
|
|
|
|
|
|
/* Set final timer frequency */
|
|
|
|
if (timer_freq)
|
|
|
|
gd->arch.timer_freq = timer_freq;
|
|
|
|
|
|
|
|
printf("Clock: CPU: %luMHz, Bus: %luMHz, XTAL: %luMHz\n",
|
|
|
|
cpu_clk / 1000000, bus_clk / 1000000, xtal_clk / 1000000);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
ulong notrace get_tbclk(void)
|
|
|
|
{
|
|
|
|
return gd->arch.timer_freq;
|
|
|
|
}
|