Exynos4412的Linux时钟驱动开发(一)——Exynos4412的时钟管理单元CMU

系列文章目录

Exynos4412的Linux时钟驱动开发(一)——Exynos4412的时钟管理单元CMU

Exynos4412的Linux时钟驱动开发(二)——时钟驱动的初始化(CLK_OF_DECLARE的机制)

Exynos4412的Linux时钟驱动开发(三)——Common Clock Framework(CCF)简介

Exynos4412的Linux5.4.174时钟驱动开发(四)——clk API的调用方法

Exynos4412的Linux5.4.174时钟驱动开发(五)——时钟设备树的修改方法



一、Exynos4412的CMU

CMU:Clock Management Unit

1、时钟域

Exynos4412有很多时钟功能模块,异步地为不同的硬件提供不同频率,例如

  • CPU时钟模块(CPU block)
  • DMC模块
  • 左总线和右总线
  • CMU_TOP
    Exynos4412时钟域

2、时钟源

(1)顶层时钟包括:

  • 外接晶振: XXTI(24MHz), and XUSBXTI(24MHz),XRTCXTI(32.768kHz),HDMIXTI(27MHz)
  • CMU生成内部时钟:ARMCLK, ACLK, HCLK, and SCLK
  • USB PHY
  • HDMI_PHY
  • GPIO外接输入时钟源

(2)CMU的时钟源

  • 外部晶振
  • 四种PLL:APLL、MPLL、EPLL、VPLL。官方建议APLL, MPLL, EPLL, and VPLL的输入时钟为24MHz
  • USB PHY 和HDMI PHY

APLL和MPLL可以生成22MHz~1.4GHz的时钟。通过配置P、M、S三种数值产生不同频率。数据手册中建议的PMS值,部分如下:
在这里插入图片描述

3、时钟树

产生时钟是由时钟源多路选择器MUX分频器DIV门开关GATEclock_provider共同完成。

在这里插入图片描述
数据手册中时钟树框图,部分如上图所示。可以看出,首先由XOM[0]决定多路选择器,选择XXTI或者XUSBXTI作为FINPLL,成为APLL的输入时钟。

XOM[0]是chipid register中的一位。linux-5.4.174/drivers/clk/samsung/clk-exynos4.c中读取XOM[0]并选择FINPLL。代码如下:

/*
 * The parent of the fin_pll clock is selected by the XOM[0] bit. This bit
 * resides in chipid register space, outside of the clock controller memory
 * mapped space. So to determine the parent of fin_pll clock, the chipid
 * controller is first remapped and the value of XOM[0] bit is read to
 * determine the parent clock.
 */
static unsigned long __init exynos4_get_xom(void)
{
	unsigned long xom = 0;
	void __iomem *chipid_base;
	struct device_node *np;

	np = of_find_compatible_node(NULL, NULL, "samsung,exynos4210-chipid");
	if (np) {
		chipid_base = of_iomap(np, 0);

		if (chipid_base)
			xom = readl(chipid_base + 8);

		iounmap(chipid_base);
		of_node_put(np);
	}

	return xom;
}

static void __init exynos4_clk_register_finpll(struct samsung_clk_provider *ctx)
{
	struct samsung_fixed_rate_clock fclk;
	struct clk *clk;
	unsigned long finpll_f = 24000000;
	char *parent_name;
	unsigned int xom = exynos4_get_xom();

	parent_name = xom & 1 ? "xusbxti" : "xxti";
	clk = clk_get(NULL, parent_name);
	if (IS_ERR(clk)) {
		pr_err("%s: failed to lookup parent clock %s, assuming "
			"fin_pll clock frequency is 24MHz\n", __func__,
			parent_name);
	} else {
		finpll_f = clk_get_rate(clk);
	}

	fclk.id = CLK_FIN_PLL;
	fclk.name = "fin_pll";
	fclk.parent_name = NULL;
	fclk.flags = 0;
	fclk.fixed_rate = finpll_f;
	samsung_clk_register_fixed_rate(ctx, &fclk, 1);

}

4、设置FSYS

系统推荐主频1.4GHz的各种寄存器配置数值,可以参考《【TINY4412】U-BOOT移植笔记:(5)时钟分析》
这里以设置FSYS为例进行分析相关时钟寄存器。我的开发板上网卡控制器DM9000A是连接在SROC控制器上的,FSYS是给SROMC提供时钟的。

在这里插入图片描述
以设置FSYS时钟为例分析。由时钟树图可以看出,设置FSYS的时钟频率,需要设置3个多路选择器MUX和2个分频器DIV,涉及如下寄存器:

  • MUXMPLL_CTRL_USER_T
    CLK_SRC_TOP1
    Base Address: 0x1003_0000,Address = Base Address + 0xC214,
    Reset Value = 0x0000_0000
    在这里插入图片描述
  • MUXACLK_133、MUXONENAND、MUXONENAND_1
    CLK_SRC_TOP0
    Base Address: 0x1003_0000,Address = Base Address + 0xC210,
    Reset Value = 0x0000_0000

在这里插入图片描述
在这里插入图片描述

  • DIVACLK_133、DIVONENAND
    CLK_DIV_TOP
    Base Address: 0x1003_0000,Address = Base Address + 0xC510,
    Reset Value = 0x0000_0000
    在这里插入图片描述
    在这里插入图片描述

二、Linux启动时默认的时钟频率

Exynos4412在刚上电时,会执行64KB的iROM中的代码,初始化系统的时钟。此时,APLL和MPLL的MPS值分别为100、3、1,产生400MHz时钟。
然后,由BootLoader进一步配置时钟,使Exynos4412工作在最佳时钟状态。也就是说,Linux在启动的时候,CMU的各个寄存器已经配置完毕了。
因此,对于Linux而言,就是如何编写关于时钟的驱动程序,配置和使用时钟。其实,对于驱动开发人员来说,只需要调用Common Clock Framework(CCF)的clk API,就能够操作各种类型的时钟,没必要重新配置CMU。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值