1. 程式人生 > >第七章:基於九鼎X210開發板移植2014.10版U-boot之初始化時鐘模組

第七章:基於九鼎X210開發板移植2014.10版U-boot之初始化時鐘模組

重新燒錄,啟動,發現可以正常執行,然後卡死在DRAM之後,還打印出了一個O,這個O看起來挺熟悉的,開機時候列印的那個O?一下子就想到,我們雖然自己移植的那個重定位程式碼(拷貝BL2到記憶體中),但原版程式碼中應該也有一份,要將它移除。

首先定位到DRAM是由board.c中的board_init_f函式呼叫display_dram_config打印出,board_init_f函式被crt0.S中的_main中被呼叫,看到這裡可以很明顯的看出,呼叫完board_init_f之後就開始執行程式碼重定位了。那麼,將這段程式碼遮蔽掉,應該就能解決上述問題。


再往下看程式碼,發現一個小細節問題,呼叫了coloured_LED_init

red_led_on,我們開發板應該沒有什麼彩色led吧,遮蔽掉就可以了,防止出問題。


編譯完後,再次啟動,問題解決,進入了命令列,但是還是有一些問題還需要修改。


首先可以看到cpu打印出來的時鐘不對,其次就是sdhci應該是nand初始化失敗了吧,這裡我為了驗證猜想,使用了uboot提供的mmc操作命令,讀取nand中的某塊資料出來,但結果顯示有問題。


目前就開始著手解決這兩個問題吧。

Cpu時鐘的初始化在2014.10版中的lowlevel_init.S中有寫,但是並未被呼叫。這裡可以分析下到底都做了些啥。

彙編不常用,細節就不寫了,大致就是讀取CPU的id號,來判斷是S5PV100還是V110,我們的晶片是s5pv210,暫存器和110是相同的。Review完程式碼後,我們發現開頭對cpu的判斷會在system_clock_init

中用到,那麼我們就將100相關的程式碼刪除,留下有用的程式碼就好了。

程式碼處理完後,就需要對時鐘相關的暫存器進行配置了,這裡我偷懶了,直接在網上看到別人寫的帖子,覺得不錯,直接用他的資料好了。
參考:http://blog.csdn.net/u010346967/article/details/46461255
他這裡設定的時鐘是datasheet推薦的,和我之前移植三星版本的uboot一致。



system_clock_init:

	/* Check S5PC100 */
	ldr	r0, =0xE010C000			@ S5PC110_PWR_CFG

	/* Set OSC_FREQ value */
	ldr	r1, =0xf
	str	r1, [r0, #0x100]			@ S5PC110_OSC_FREQ

	/* Set MTC_STABLE value */
	ldr	r1, =0xffffffff	
	str	r1, [r0, #0x110]			@ S5PC110_MTC_STABLE

	/* Set CLAMP_STABLE value */
	ldr	r1, =0x3ff03ff
	str	r1, [r0, #0x114]			@ S5PC110_CLAMP_STABLE
首先將PWR_CFG暫存器的地址放入r0暫存器,大致就是為了方便下面三個暫存器的設定,這三個暫存器分別為OSC_FREQ、MTC_STABLE、CLAMP_STABLE,查了資料手冊,並不是很理解這幾個暫存器是設定啥的,而這個章節講的是cpu的電源模式。
ldr	r0, =S5PC110_CLOCK_BASE		@ 0xE0100000

	/* Set Clock divider */
	ldr	r1, =0x14131330			@ 1:1:4:4, 1:4:5
	str	r1, [r0, #0x300]
	ldr	r1, =0x11110111			@ UART[3210]: MMC[3210]
	str	r1, [r0, #0x310]

	/* Set Lock Time */
	ldr	r1, =0x2cf			@ Locktime : 30us
	str	r1, [r0, #0x000]		@ S5PC110_APLL_LOCK
	ldr	r1, =0xe10			@ Locktime : 0xe10 = 3600
	str	r1, [r0, #0x008]		@ S5PC110_MPLL_LOCK
	str	r1, [r0, #0x010]		@ S5PC110_EPLL_LOCK
	str	r1, [r0, #0x020]		@ S5PC110_VPLL_LOCK
	
	/* S5PC110_APLL_CON */
	ldr	r1, =0x80C80601			@ 800MHz
	str	r1, [r0, #0x100]
	/* S5PC110_MPLL_CON */
	ldr	r1, =0x829B0C01			@ 667MHz
	str	r1, [r0, #0x108]
	/* S5PC110_EPLL_CON */
	ldr	r1, =0x80600602			@  96MHz VSEL 0 P 6 M 96 S 2
	str	r1, [r0, #0x110]
	/* S5PC110_VPLL_CON */
	ldr	r1, =0x806C0603			@  54MHz
	str	r1, [r0, #0x120]

	/* Set Source Clock */
	ldr	r1, =0x10001111			@ A, M, E, VPLL Muxing
	str	r1, [r0, #0x200]		@ S5PC1XX_CLK_SRC0
/* OneDRAM(DMC0) clock setting */
	ldr	r1, =0x01000000			@ ONEDRAM_SEL[25:24] 1 SCLKMPLL
	str	r1, [r0, #0x218]		@ S5PC110_CLK_SRC6
	ldr	r1, =0x30000000			@ ONEDRAM_RATIO[31:28] 3 + 1
	str	r1, [r0, #0x318]		@ S5PC110_CLK_DIV6

oneDRAM,開發板中沒有,可以刪除。

/* XCLKOUT = XUSBXTI 24MHz */
	add	r2, r0, #0xE000				@ S5PC110_OTHERS
	ldr     r1, [r2]
	orr	r1, r1, #(0x3 << 8)			@ CLKOUT[9:8] 3 XUSBXTI
	str	r1, [r2]

	/* CLK_IP0 */
	ldr	r1, =0x8fefeeb				@ DMC[1:0] PDMA0[3] IMEM[5]
	str	r1, [r0, #0x460]			@ S5PC110_CLK_IP0

	/* CLK_IP1 */
	ldr	r1, =0xe9fdf0f9				@ FIMD[0] USBOTG[16]
							@ NANDXL[24]
	str	r1, [r0, #0x464]			@ S5PC110_CLK_IP1

	/* CLK_IP2 */
	ldr	r1, =0xf75f7fc				@ CORESIGHT[8] MODEM[9]
							@ HOSTIF[10] HSMMC0[16]
							@ HSMMC2[18] VIC[27:24]
	str	r1, [r0, #0x468]			@ S5PC110_CLK_IP2

	/* CLK_IP3 */
	ldr	r1, =0x8eff038c				@ I2C[8:6]
							@ SYSTIMER[16] UART0[17]
							@ UART1[18] UART2[19]
							@ UART3[20] WDT[22]
							@ PWM[23] GPIO[26] SYSCON[27]
	str	r1, [r0, #0x46c]			@ S5PC110_CLK_IP3

	/* CLK_IP4 */
	ldr	r1, =0xfffffff1				@ CHIP_ID[0] TZPC[8:5]
	str	r1, [r0, #0x470]			@ S5PC110_CLK_IP3

	/* wait at least 200us to stablize all clock */
	mov	r2, #0x10000
1:	subs	r2, r2, #1
	bne	1b
 這部分應該就是和一些內部外設相關的時鐘開啟這類的,先放著不管。

修改完時鐘相關的暫存器後,在lowlevel_int中執行system_clock_init


理論上是不會有太大問題,但是為了驗證是否正確,我移植了三星版本的一個列印各時鐘頻率的函式,移植完後,發現沒有太大的問題。而且之前mmc初始化失敗的問題也被解決了,但是隻是沒有初始化失敗的log而已,所以還是要對mmc進行驗證下。


首先先測試一下,是否能夠對環境變數進行儲存,環境變數會在程式碼中儲存一份,如果儲存裝置不存在環境變數的話,就會先呼叫這份程式碼中的環境變數,因此我們先對這份環境變數進行更改。

開機後在uboot命令列中輸入pri,結果打印出一堆引數,然後通過這些引數定位到X210.h中,接下來就是修改這些環境變數。

將沒用的環境變數遮蔽掉,再次燒錄sd卡並啟動,列印環境變數,嗯,整潔多了。


之後set一個環境變數,並儲存,重啟後,發現環境變數存在,因此可以證明nand是可以使用的,當然,我們還可以直接對mmc read/write進行讀寫測試,寫入一些資料,再讀取出來,如果正確也可以說明mmc可以使用。

Nand、Mmc這類裝置的相容性比較強,移植uboot的時候,大多數都是不需要過多的修改就能使用了。