TQ210 —— s5pv210 lowlevel_init.S分析(uboot第一阶段)

发布者:Radiant777最新更新时间:2020-12-16 来源: eefocus关键字:TQ210  s5pv210  S分析  uboot 手机看文章 扫描二维码
随时随地手机看文章

/*

 * Memory Setup stuff - taken from blob memsetup.S

 *

 * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and

 *                     Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl)

 *

 * Modified for the Samsung SMDK2410 by

 * (C) Copyright 2002

 * David Mueller, ELSOFT AG,

 *

 * See file CREDITS for list of people who contributed to this

 * project.

 *

 * 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., 59 Temple Place, Suite 330, Boston,

 * MA 02111-1307 USA

 */

 

 

#include

#include

 

#include

#include "tq210_val.h"

 

@ 讲start.S的时候已经说过这个TEXT_BASE了

_TEXT_BASE:

.word TEXT_BASE

 

.globl lowlevel_init

lowlevel_init:

push {lr}   @ 将上一个函数的返回地址压入栈中

 

/* check reset status  */ 

@ 检查复位标志,如果是睡眠唤醒,跳过接下来的初始化

ldr r0, =(ELFIN_CLOCK_POWER_BASE+RST_STAT_OFFSET) @ 跳转到目的地Reset Control Register的地址传送给r0 Address = 0xE010_A000 =0xE010_0000+0xA000

ldr r1, [r0]  @ 将存储器地址为 R0(内存储的值) 的字数据读入寄存器 R1

bic r1, r1, #0xfff6ffff   @将r1与0xfff6ffff的反码按位进行与运算(既和0xfff6ffff进行与非运算),并写入r1;结合上一步,可知,这一步的作用是16和19bit置一,其他位清零

cmp r1, #0x10000  @ 判断16bit是不是等于1

beq wakeup_reset_pre  @ 如果是从睡眠状态唤醒,就跳转到wakeup_reset_pre,既跳过接下来的初始化

    cmp r1, #0x80000    @ 判断是不是从深度空闲(Deep-IDLE)状态唤醒

beq wakeup_reset_from_didle   @ 如果是,就跳转到wakeup_reset_from_didle

 

/* IO Retention release */

ldr r0, =(ELFIN_CLOCK_POWER_BASE + OTHERS_OFFSET)  @ 将跳转目的地址MISC Register的地址传送给r0   Address = 0xE010_E000 =0xE010_0000+0xE000

ldr r1, [r0]  @ 将存储器地址为 R0(内存储的值) 的字数据读入寄存器 R1

ldr r2, =IO_RET_REL  @将IO_RET_REL( ((1 << 31) | (1 << 29) | (1 << 28)) )存入r2

    orr r1, r1, r2  @ 将r1和r2的值进行或运算,结果存入r1

str r1, [r0]  @ 将r1的值写入以r0内的值为地址的内存空间

 

/* Disable Watchdog */

@ 关闭看门狗

ldr r0, =ELFIN_WATCHDOG_BASE /* 0xE2700000 */

mov r1, #0

str r1, [r0]

 

/* SRAM(2MB) init for SMDKC110 */

/* GPJ1 SROM_ADDR_16to21 */

@ 配置sram引脚,16位数据宽度,22位地址宽度

ldr r0, =ELFIN_GPIO_BASE

ldr r1, [r0, #GPJ1CON_OFFSET]

bic r1, r1, #0xFFFFFF

ldr r2, =0x444444

orr r1, r1, r2

str r1, [r0, #GPJ1CON_OFFSET]

 

ldr r1, [r0, #GPJ1PUD_OFFSET]

ldr r2, =0x3ff

bic r1, r1, r2

str r1, [r0, #GPJ1PUD_OFFSET]

 

/* GPJ4 SROM_ADDR_16to21 */

ldr r1, [r0, #GPJ4CON_OFFSET]

bic r1, r1, #(0xf<<16)

ldr r2, =(0x4<<16)

orr r1, r1, r2

str r1, [r0, #GPJ4CON_OFFSET]

 

ldr r1, [r0, #GPJ4PUD_OFFSET]

ldr r2, =(0x3<<8)

bic r1, r1, r2

str r1, [r0, #GPJ4PUD_OFFSET]

 

 

/* CS0 - 16bit sram, enable nBE, Byte base address */

ldr r0, =ELFIN_SROM_BASE /* 0xE8000000 */

mov r1, #0x1

str r1, [r0]

 

/* PS_HOLD pin(GPH0_0) set to high */

@ 设置PMIC(Power Management IC)控制引脚,既电源管理ic引脚(基于I2C)

ldr r0, =(ELFIN_CLOCK_POWER_BASE + PS_HOLD_CONTROL_OFFSET)

ldr r1, [r0]

orr r1, r1, #0x300

orr r1, r1, #0x1

str r1, [r0]

 

/* when we already run in ram, we don't need to relocate U-Boot.

* and actually, memory controller must be configured before U-Boot

* is running in ram.

*/

/*下面的代码事实上只是判断pc和_TEXT_BASE(0X23e00000)的最高两位是否相同*/

     /* 根据s5pv210的数据手册可知,首先,系统会运行固化在irom的BL0,紧接着会从外部nand

      * 或sdcard等设备读取前16K的BL1代码到IRAM中的0xD0020000处。然后从0xD0020010处运行(因为前16byte是校验和的值)

      * BL1的作用是初始化DRAM,拷贝BL2到DRAM中_TEXT_BASE(0X23e00000)处,然后跳到DRAM中运行

      * 因此可以通过最高两位来判断代码是在哪里运行

      * 同时可知,当代码已经就在DRAM中运行时,就必须跳过DRAM的初始化

     */

ldr r0, =0xff000fff

bic r1, pc, r0 /* r0 <- current base addr of code */

ldr r2, _TEXT_BASE /* r1 <- original base addr in ram */

bic r2, r2, r0 /* r0 <- current base addr of code */

cmp     r1, r2                  /* compare r0, r1                  */

beq     1f /* r0 == r1 then skip sdram init   */

 

/* init PMIC chip */

#ifdef CONFIG_TQ210_IIC_PM_CHIP

bl PMIC_InitIp

#endif

 

/* init system clock */

@ 时钟初始化 PLL初始化,要想看懂此汇编,请查看datsheet中,clk control章节

bl system_clock_init

 

/* Memory initialize */

@ 内存初始化

bl mem_ctrl_asm_init

1:

/* for UART */

@ 串口初始化,要看懂此汇编, 请查看datsheet中, 请查看串口章节

bl uart_asm_init

 

bl tzpc_init

 

@ 这段不执行

#if defined(CONFIG_ONENAND)

bl onenandcon_init

#endif

 

    @ nand初始化

#if defined(CONFIG_NAND)

/* simple init for NAND */

bl nand_asm_init

#endif

 

/* check reset status  */

ldr r0, =(ELFIN_CLOCK_POWER_BASE+RST_STAT_OFFSET)

ldr r1, [r0]

bic r1, r1, #0xfffeffff

cmp r1, #0x10000

beq wakeup_reset_pre

 

/* ABB disable */

ldr r0, =0xE010C300

orr r1, r1, #(0x1<<23)

str r1, [r0]

 

/* Print 'K' */

ldr r0, =ELFIN_UART_CONSOLE_BASE

ldr r1, =0x4b4b4b4b

str r1, [r0, #UTXH_OFFSET]

 

pop {pc} @ 返回到start.S

 

wakeup_reset_from_didle: @ 从深度睡眠中唤醒

/* Wait when APLL is locked */

ldr r0, =ELFIN_CLOCK_POWER_BASE

lockloop:

ldr r1, [r0, #APLL_CON0_OFFSET]

and r1, r1, #(1<<29)

cmp r1, #(1<<29)

bne lockloop @ 这里使用循环

beq exit_wakeup

 

wakeup_reset_pre:

mrc p15, 0, r1, c1, c0, 1 @Read CP15 Auxiliary control register

and r1, r1, #0x80000000 @Check L2RD is disable or not

cmp r1, #0x80000000

bne wakeup_reset @if L2RD is not disable jump to wakeup_reset 

bl disable_l2cache

bl v7_flush_dcache_all

/* L2 cache enable at sleep.S of kernel

* bl enable_l2cache 

*/

#ifdef CONFIG_TQ210

bl enable_l2cache

#endif

 

wakeup_reset:

/* init system clock */

bl system_clock_init

bl mem_ctrl_asm_init

bl tzpc_init

#if defined(CONFIG_ONENAND)

bl onenandcon_init

#endif

#if defined(CONFIG_NAND)

bl nand_asm_init

#endif

 

exit_wakeup:

/*Load return address and jump to kernel*/

ldr r0, =(INF_REG_BASE+INF_REG0_OFFSET)

ldr r1, [r0] /* r1 = physical address of s5pc110_cpu_resume function*/

 

mov pc, r1 /*Jump to kernel */

nop

nop

 

/*

 * system_clock_init: Initialize core clock and bus clock.

 * void system_clock_init(void)

 */

system_clock_init:

   /* 这一段的作用是将Clock Source Control Registers值清空

    * 具体的作用是将VPLL_SEL、EPLL_SEL、MPLL_SEL和APLL_SEL的时钟源设置为FINVPLL,将MUX_MSYS_SEL、MUX_DSYS_SEL和MUX_PSYS_SEL时钟源设置为SCLKMPLL

    * 将ONENAND_SEL时钟源设置为HCLK_PSYS

    * 为什么这样设置,因为未设置 PLL 和各种分频系数之前,我们不能使用 PLL,为了保险起见,暂时直接使用频率较低

    * 的外接的 24MHz 晶振,待设置好 PLL 和分频系数后再重新设置各种时钟开关

    */

ldr r0, =ELFIN_CLOCK_POWER_BASE @0xe0100000

 

/* Set Mux to FIN */

ldr r1, =0x0

str r1, [r0, #CLK_SRC0_OFFSET]

 

ldr r1, =APLL_LOCKTIME_VAL   @将APLL_LOCKTIME_VAL(0x2cf)装入r1

str r1, [r0, #APLL_LOCK_OFFSET]  @将r1内的值装入地址为(r0内的值+CLK_SRC0_OFFSET = 0xe0100000)的内存,即设置APLL的锁定周期

 

    /*

* A PLL requires locking period when input frequency is changed or frequency division (multiplication) values are

     * changed.PLL_LOCK register specifies this locking period, which is based on PLL’s source clock. During this

     * period, output will be low state

    */

/* Disable PLL */

#if defined(CONFIG_CHECK_MPLL_LOCK)

retryloop:

#endif

ldr r1, =0x0

str r1, [r0, #APLL_CON0_OFFSET]  @ 将APLL控制寄存器的值清空,这个寄存器的第31位置零关闭APLL 25-16bit配置MDIV的分频 

@ 13-8bit配置PDIV的分频 2-0bit配置SDIV的分频

ldr r1, =0x0

str r1, [r0, #MPLL_CON_OFFSET]   @ 配置MPLL

 

ldr r1, =0x0

str r1, [r0, #MPLL_CON_OFFSET]   @ 重复配置MPLL,确保MPLL配置成功

 

ldr    r1, [r0, #CLK_DIV0_OFFSET] @ Clock Divider Control Register(0xe0100300)

ldr r2, =CLK_DIV0_MASK             @ CLK_DIV0_MASK(0x7fffffff)

bic r1, r1, r2                     @ 首先清零

 

ldr r2, =CLK_DIV0_VAL              @ CLK_DIV0_VAL

orr r1, r1, r2

str r1, [r0, #CLK_DIV0_OFFSET]

    /*

    *CLK_DIV0_VAL = ((0<    *   |(3<    *#define APLL_RATIO         0

    *#define A2M_RATIO          4

    *#define HCLK_MSYS_RATIO    8

    *#define PCLK_MSYS_RATIO    12

    *#define HCLK_DSYS_RATIO    16

    *#define PCLK_DSYS_RATIO    20

    *#define HCLK_PSYS_RATIO    24

    *#define PCLK_PSYS_RATIO    28

    */

ldr r1, =APLL_VAL

str r1, [r0, #APLL_CON0_OFFSET]

 

ldr r1, =MPLL_VAL

str r1, [r0, #MPLL_CON_OFFSET]

 

ldr r1, =VPLL_VAL

str r1, [r0, #VPLL_CON_OFFSET]

#if defined(CONFIG_EVT1)

ldr r1, =AFC_ON

str r1, [r0, #APLL_CON1_OFFSET]

#endif

mov r1, #0x10000

1: subs r1, r1, #1    @ 延时 将r1-1的值存入r1

bne 1b                @ 如果运算结果不等零(即CPSR寄存器标志位Z不等于一),退回到前面标签“1”处执行  当 CPSR 寄存器中的 Z 

                          @ 条件码置位时(即前面的计算结果为零),则顺序执行(即运行接下来的:ldr   r1, [r0, #CLK_SRC0_OFFSET])

[1] [2] [3]
关键字:TQ210  s5pv210  S分析  uboot 引用地址:TQ210 —— s5pv210 lowlevel_init.S分析(uboot第一阶段)

上一篇:TQ210 —— s5pv210 board.c分析(uboot第二阶段)
下一篇:TQ210 —— s5pv210 start.S分析

推荐阅读最新更新时间:2024-11-11 04:59

S5PV210(TQ210)学习笔记——USB HOST移植
在写USB驱动程序的时候意外发现默认状态下内核没有驱动S5PV210的USB HOST控制器,于是,我自己动手移植了一下S5PV210的USB HOST模块,S5PV210的USB HOST控制器跟S3C2440的有些不同,S5PV210同时支持EHCI和OHCI接口(两者的区别自己谷歌搜一下),这样,S5PV210在功能上就完全支持USB2.0接口了。 Linux内核(以3.8.3为例)默认仅提供了ehci-s5p.c,但是提供了很多其他平台的ohci源码,因此,我们可以参考ohci-exynos.c来编写自己的ohci-s5p.c,然后参考ehci-s5p.c的代码组织方式添加到内核就可以了。下面废话少说,直接进入正题,开始US
[单片机]
使用全新R&S FSW85分析宽带和脉冲信号
全新的R&S FSW85是市面上唯一单次扫描频率范围覆盖2Hz至85GHz的高端信号与频谱分析仪。这使得用户可以使用一台信号分析仪测试基带和射频信号。由于不需 要外置的谐波混频器,R&S FSW85使得测试连接和设置都大为简化。内置的预选器可以有效的抑制谐波混频引起的镜频和杂散。   R&S FSW85可以选配高达500MHz的内部分析带宽,这给雷达器件的研发人员带来很多新的分析选择,特别是汽车雷达领域和航天与国防雷达领域。当它安装R&S FSW-B2000选件并和R&S RTO示波器配合使用时,它甚至可以达到2GHz的分析带宽,这使得研发人员可以分析5G下一代移动通信和复杂脉冲参数及线性调频雷达系统中的宽带信号。   R&S
[测试测量]
使用全新R&<font color='red'>S</font> FSW85<font color='red'>分析</font>宽带和脉冲信号
S5PV210定时器
在S5PV210内部,一共有4类定时器件。这4类定时器件的功能、特征是不同的。 1、PWM定时器 (1)这种是最常用的,平时所说的定时器一般指的是这个。像简单单片机(譬如51单片机)中的定时器也是这类。 (2)为什么叫PWM定时器,因为一般SoC中产生PWM信号都是靠这个定时器模块的。 2、系统定时器 (1)系统(指的是操作系统)定时器,系统定时器也是用来产生固定时间间隔(TCNT×时钟周期)信号的,称为systick,这个systick用来给操作系统提供tick信号。 (2)产生systick作为操作系统的时间片(time slice)的,一般是用在操作系统的调度系统下,用来做调度系统的进程间切换。 (3)一般做操作系统移
[单片机]
德国R&S罗德与施瓦茨FPS 信号与频谱分析
FPS 信号与频谱分析仪 R&S®FPS 是一款快速小巧的信号与频谱分析仪,专为追求性能的用户提供。在生产和监控系统中,只需 2 HU 的机架空间,比传统仪器减少一半。 主要特点 频率范围最高为 4/7/13.6/30/40 GHz 最高 160 MHz 信号分析带宽 0.4 dB 电平测量不确定度(最高 7 GHz) GSM/EDGE(包括 EDGE Evolution)、WCDMA/HSPA+、LTE、WLAN、矢量信号分析测量应用 在 10 kHz 频率偏移条件下,相位噪声为 –110 dBc (1 Hz) +15 dBm 三阶截止点 (TOI) 1 Hz 带宽、1 GHz 条件下,显示平均噪声电平 (DA
[测试测量]
从sys/power/state分析并实现S3C2416的睡眠和唤醒
环境: PC: debian-7.6.0 ARM CPU: S3C2416 Linux-Kernel: 3.6.0(FriendlyARM) U-boot: 1.3.4 一、问题来源 依据须要,在S3C2416上加入中断睡眠和唤醒功能。于是我就查查Linux支持S3C2416的睡眠模式: cat /sys/power/state 运行完,万万没想到:居然是空的,该命令没有不论什么输出!也就是说,我的内核眼下不支持不论什么方式的睡眠。 不可能啊!之前我用S3C2440的CPU(内核版本号Linux_2_6_31)实现了中断的睡眠和唤醒
[单片机]
从sys/power/state<font color='red'>分析</font>并实现<font color='red'>S</font>3C2416的睡眠和唤醒
ARM-Linux s3c2440 之UART分析(一)
在分析ARM-Linux s3c2440中UART的时有必要先了解 s3c2440A中串口的硬件知识。也就是本文---- 硬件篇: S3c2440A串口提供三个独立的异步串行通信I/O端口(asynchronousserial I/O ports)。每一个串口均可以以普通中断方式或者DMA方式进行数据收发,采用系统时钟时,最大速率为115.2kbps.如果采用外部时钟(UEXTCLK),UART速度可以更快。每个串口包含有2个64-byte的FIFO缓存区用来发送或传输数据。 S3c2440A 串口具有可编程波特率,红外(IR)收发数据,1或者2 位的停止位(stop),5/6/7/8 位数据宽度和奇偶校验功能(parity c
[单片机]
ARM-Linux <font color='red'>s</font>3c2440 之UART<font color='red'>分析</font>(一)
tq210 内存配置
S5PV210有两个独立的DRAM控制器,分别是DMC0和DMC1,其中,DMC0最大支持512MByte,DMC1最大支持1GByte,而DMC0和DMC1又同时支持两个片选CS0和CS1。S5PV210的内存模块相比2440和6410来讲要更加复杂一些,要想正确的配置S5PV210的内存,应该仔细阅读芯片手册相关部分,在配置参数时也应该适当的阅读下内存芯片的手册。这部分的寄存器和配置过程比较复杂(但是不难),我只简单的讲一下我配置时遇到的问题。 一 接线原理 我的开发板是TQ210,开发板上有8片128M*8bits的内存芯片,从原理图上可以看到,其中4片并联接在DMC0上,另外四片并联在DMC1上,这里我只贴出一个链接
[单片机]
S5PV210的NandFlash应用(三)
准备分析 经过了《S5PV210的NandFlash应用(二)》对于二进制文件前16k的存取方式都了一定的了解。这次要证明的是第NandFlash第4页以后存取方式。《S5PV210的NandFlash应用(二)》里边的210.bin(大小为16k)是以存到4k为单位存到了前4页(0, 1, 2 ,3)的每页的前4k处。为此我自己写了一个8k的二进制文件(名字叫AB),贴在210.bin的后边,按照推断这8k应该存在了第4页。然后改到nand_cp.c以8k的方式,读取第4页,然后数据都输出到串口,再与原二进制文件对比。 资源工具 同《 S5PV210的LED应用(一)》 NandFlash: K9GAG08U0F (
[单片机]
<font color='red'>S5PV210</font>的NandFlash应用(三)
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved