ubuntu 在 R40e 上 還有 Debian 在 Sempron 2600 上

2012年11月19日 星期一

iMX51 suspend 最後(底層)的 code

suspend 時,最後 callmx5_suspend_enter( )
會 call 到 suspend_in_iram(suspend_param1, NULL, NULL);

suspend_in_iram 是一個 function pointer. void (*suspend_in_iram)(void *param1, void *param2, void* param3) = NULL; 在 pm_init 時: suspend_param1 = cpu_is_mx51() ? (void *)SUSPEND_ID_MX51: (void *)SUSPEND_ID_MX53; memcpy(suspend_iram_base, cpu_do_suspend_workaround,SZ_4K); suspend_in_iram = (void *)suspend_iram_base; 也就是..把cpu_do_suspend_workaround 這塊區域copy 到 suspend_iram_base 中。
再把 suspend_iram_base 指定給 suspend_in_iram( )

這是因為suspend 時,dram 會disable, 進入 self-refresh,所以不能 access。

所以要把 dram 中的 code 先 copy 到 internal ram (iram) 中,才可以執行。


cpu_do_suspend_workaround 是 assembly code: suspend.S

parameter 1 是 chip ID, 因為這個 function 是mx50,mx51, mx53 共用的。
這段assembly code,作 invalid cache, set ddr to self-refresh mode.
set dd pin to high-z, 然後就進入 wait for interrupt 模式:
    /*
     * PLL1 workaround as the following: For mx51 only.
     * Before enter WFI
     *      (1) switch DDR and ARM to PLL2
     *      (2) Disable AREN bit to avoid PLL1 restart during MFN change)
     *      (3) set PLL1 to ~864Mhz with MFI = 8, MFN = 180, MFD = 179
     *          thus the equation |MFN/(MFD+1)|  < 1
     *      (4) Manual restart PLL1
     *      (5) Wait PLL1 lock
     * After CPU out of WFI
     *      (6) Set PLL1 to 800Mhz with only change MFN to 60, others keep
     *      (7) Wait MFN change complete by delay 4.6us,
     *      (8) Switch DDR and ARM back to PLL1
     */

沒有留言:

標籤

網誌存檔