會 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 */
沒有留言:
張貼留言