169d88a00SPaul Walmsley /* 269d88a00SPaul Walmsley * OMAP2/3 System Control Module register access 369d88a00SPaul Walmsley * 469d88a00SPaul Walmsley * Copyright (C) 2007 Texas Instruments, Inc. 569d88a00SPaul Walmsley * Copyright (C) 2007 Nokia Corporation 669d88a00SPaul Walmsley * 769d88a00SPaul Walmsley * Written by Paul Walmsley 869d88a00SPaul Walmsley * 969d88a00SPaul Walmsley * This program is free software; you can redistribute it and/or modify 1069d88a00SPaul Walmsley * it under the terms of the GNU General Public License version 2 as 1169d88a00SPaul Walmsley * published by the Free Software Foundation. 1269d88a00SPaul Walmsley */ 1369d88a00SPaul Walmsley #undef DEBUG 1469d88a00SPaul Walmsley 1569d88a00SPaul Walmsley #include <linux/kernel.h> 16a58caad1STony Lindgren #include <linux/io.h> 1769d88a00SPaul Walmsley 18ce491cf8STony Lindgren #include <plat/common.h> 19ce491cf8STony Lindgren #include <plat/control.h> 20*80140786SRajendra Nayak #include <plat/sdrc.h> 21*80140786SRajendra Nayak #include "cm-regbits-34xx.h" 22*80140786SRajendra Nayak #include "prm-regbits-34xx.h" 23*80140786SRajendra Nayak #include "cm.h" 24*80140786SRajendra Nayak #include "prm.h" 25*80140786SRajendra Nayak #include "sdrc.h" 2669d88a00SPaul Walmsley 27a58caad1STony Lindgren static void __iomem *omap2_ctrl_base; 2869d88a00SPaul Walmsley 29*80140786SRajendra Nayak struct omap3_scratchpad { 30*80140786SRajendra Nayak u32 boot_config_ptr; 31*80140786SRajendra Nayak u32 public_restore_ptr; 32*80140786SRajendra Nayak u32 secure_ram_restore_ptr; 33*80140786SRajendra Nayak u32 sdrc_module_semaphore; 34*80140786SRajendra Nayak u32 prcm_block_offset; 35*80140786SRajendra Nayak u32 sdrc_block_offset; 36*80140786SRajendra Nayak }; 37*80140786SRajendra Nayak 38*80140786SRajendra Nayak struct omap3_scratchpad_prcm_block { 39*80140786SRajendra Nayak u32 prm_clksrc_ctrl; 40*80140786SRajendra Nayak u32 prm_clksel; 41*80140786SRajendra Nayak u32 cm_clksel_core; 42*80140786SRajendra Nayak u32 cm_clksel_wkup; 43*80140786SRajendra Nayak u32 cm_clken_pll; 44*80140786SRajendra Nayak u32 cm_autoidle_pll; 45*80140786SRajendra Nayak u32 cm_clksel1_pll; 46*80140786SRajendra Nayak u32 cm_clksel2_pll; 47*80140786SRajendra Nayak u32 cm_clksel3_pll; 48*80140786SRajendra Nayak u32 cm_clken_pll_mpu; 49*80140786SRajendra Nayak u32 cm_autoidle_pll_mpu; 50*80140786SRajendra Nayak u32 cm_clksel1_pll_mpu; 51*80140786SRajendra Nayak u32 cm_clksel2_pll_mpu; 52*80140786SRajendra Nayak u32 prcm_block_size; 53*80140786SRajendra Nayak }; 54*80140786SRajendra Nayak 55*80140786SRajendra Nayak struct omap3_scratchpad_sdrc_block { 56*80140786SRajendra Nayak u16 sysconfig; 57*80140786SRajendra Nayak u16 cs_cfg; 58*80140786SRajendra Nayak u16 sharing; 59*80140786SRajendra Nayak u16 err_type; 60*80140786SRajendra Nayak u32 dll_a_ctrl; 61*80140786SRajendra Nayak u32 dll_b_ctrl; 62*80140786SRajendra Nayak u32 power; 63*80140786SRajendra Nayak u32 cs_0; 64*80140786SRajendra Nayak u32 mcfg_0; 65*80140786SRajendra Nayak u16 mr_0; 66*80140786SRajendra Nayak u16 emr_1_0; 67*80140786SRajendra Nayak u16 emr_2_0; 68*80140786SRajendra Nayak u16 emr_3_0; 69*80140786SRajendra Nayak u32 actim_ctrla_0; 70*80140786SRajendra Nayak u32 actim_ctrlb_0; 71*80140786SRajendra Nayak u32 rfr_ctrl_0; 72*80140786SRajendra Nayak u32 cs_1; 73*80140786SRajendra Nayak u32 mcfg_1; 74*80140786SRajendra Nayak u16 mr_1; 75*80140786SRajendra Nayak u16 emr_1_1; 76*80140786SRajendra Nayak u16 emr_2_1; 77*80140786SRajendra Nayak u16 emr_3_1; 78*80140786SRajendra Nayak u32 actim_ctrla_1; 79*80140786SRajendra Nayak u32 actim_ctrlb_1; 80*80140786SRajendra Nayak u32 rfr_ctrl_1; 81*80140786SRajendra Nayak u16 dcdl_1_ctrl; 82*80140786SRajendra Nayak u16 dcdl_2_ctrl; 83*80140786SRajendra Nayak u32 flags; 84*80140786SRajendra Nayak u32 block_size; 85*80140786SRajendra Nayak }; 86*80140786SRajendra Nayak 87*80140786SRajendra Nayak /* 88*80140786SRajendra Nayak * This is used to store ARM registers in SDRAM before attempting 89*80140786SRajendra Nayak * an MPU OFF. The save and restore happens from the SRAM sleep code. 90*80140786SRajendra Nayak * The address is stored in scratchpad, so that it can be used 91*80140786SRajendra Nayak * during the restore path. 92*80140786SRajendra Nayak */ 93*80140786SRajendra Nayak u32 omap3_arm_context[128]; 94*80140786SRajendra Nayak 95a58caad1STony Lindgren #define OMAP_CTRL_REGADDR(reg) (omap2_ctrl_base + (reg)) 9669d88a00SPaul Walmsley 97a58caad1STony Lindgren void __init omap2_set_globals_control(struct omap_globals *omap2_globals) 9869d88a00SPaul Walmsley { 99a58caad1STony Lindgren omap2_ctrl_base = omap2_globals->ctrl; 10069d88a00SPaul Walmsley } 10169d88a00SPaul Walmsley 102a58caad1STony Lindgren void __iomem *omap_ctrl_base_get(void) 10369d88a00SPaul Walmsley { 10469d88a00SPaul Walmsley return omap2_ctrl_base; 10569d88a00SPaul Walmsley } 10669d88a00SPaul Walmsley 10769d88a00SPaul Walmsley u8 omap_ctrl_readb(u16 offset) 10869d88a00SPaul Walmsley { 10969d88a00SPaul Walmsley return __raw_readb(OMAP_CTRL_REGADDR(offset)); 11069d88a00SPaul Walmsley } 11169d88a00SPaul Walmsley 11269d88a00SPaul Walmsley u16 omap_ctrl_readw(u16 offset) 11369d88a00SPaul Walmsley { 11469d88a00SPaul Walmsley return __raw_readw(OMAP_CTRL_REGADDR(offset)); 11569d88a00SPaul Walmsley } 11669d88a00SPaul Walmsley 11769d88a00SPaul Walmsley u32 omap_ctrl_readl(u16 offset) 11869d88a00SPaul Walmsley { 11969d88a00SPaul Walmsley return __raw_readl(OMAP_CTRL_REGADDR(offset)); 12069d88a00SPaul Walmsley } 12169d88a00SPaul Walmsley 12269d88a00SPaul Walmsley void omap_ctrl_writeb(u8 val, u16 offset) 12369d88a00SPaul Walmsley { 12469d88a00SPaul Walmsley __raw_writeb(val, OMAP_CTRL_REGADDR(offset)); 12569d88a00SPaul Walmsley } 12669d88a00SPaul Walmsley 12769d88a00SPaul Walmsley void omap_ctrl_writew(u16 val, u16 offset) 12869d88a00SPaul Walmsley { 12969d88a00SPaul Walmsley __raw_writew(val, OMAP_CTRL_REGADDR(offset)); 13069d88a00SPaul Walmsley } 13169d88a00SPaul Walmsley 13269d88a00SPaul Walmsley void omap_ctrl_writel(u32 val, u16 offset) 13369d88a00SPaul Walmsley { 13469d88a00SPaul Walmsley __raw_writel(val, OMAP_CTRL_REGADDR(offset)); 13569d88a00SPaul Walmsley } 13669d88a00SPaul Walmsley 137*80140786SRajendra Nayak #ifdef CONFIG_ARCH_OMAP3 138*80140786SRajendra Nayak /* 139*80140786SRajendra Nayak * Clears the scratchpad contents in case of cold boot- 140*80140786SRajendra Nayak * called during bootup 141*80140786SRajendra Nayak */ 142*80140786SRajendra Nayak void omap3_clear_scratchpad_contents(void) 143*80140786SRajendra Nayak { 144*80140786SRajendra Nayak u32 max_offset = OMAP343X_SCRATCHPAD_ROM_OFFSET; 145*80140786SRajendra Nayak u32 *v_addr; 146*80140786SRajendra Nayak u32 offset = 0; 147*80140786SRajendra Nayak v_addr = OMAP2_L4_IO_ADDRESS(OMAP343X_SCRATCHPAD_ROM); 148*80140786SRajendra Nayak if (prm_read_mod_reg(OMAP3430_GR_MOD, OMAP3_PRM_RSTST_OFFSET) & 149*80140786SRajendra Nayak OMAP3430_GLOBAL_COLD_RST) { 150*80140786SRajendra Nayak for ( ; offset <= max_offset; offset += 0x4) 151*80140786SRajendra Nayak __raw_writel(0x0, (v_addr + offset)); 152*80140786SRajendra Nayak prm_set_mod_reg_bits(OMAP3430_GLOBAL_COLD_RST, OMAP3430_GR_MOD, 153*80140786SRajendra Nayak OMAP3_PRM_RSTST_OFFSET); 154*80140786SRajendra Nayak } 155*80140786SRajendra Nayak } 156*80140786SRajendra Nayak 157*80140786SRajendra Nayak /* Populate the scratchpad structure with restore structure */ 158*80140786SRajendra Nayak void omap3_save_scratchpad_contents(void) 159*80140786SRajendra Nayak { 160*80140786SRajendra Nayak void * __iomem scratchpad_address; 161*80140786SRajendra Nayak u32 arm_context_addr; 162*80140786SRajendra Nayak struct omap3_scratchpad scratchpad_contents; 163*80140786SRajendra Nayak struct omap3_scratchpad_prcm_block prcm_block_contents; 164*80140786SRajendra Nayak struct omap3_scratchpad_sdrc_block sdrc_block_contents; 165*80140786SRajendra Nayak 166*80140786SRajendra Nayak /* Populate the Scratchpad contents */ 167*80140786SRajendra Nayak scratchpad_contents.boot_config_ptr = 0x0; 168*80140786SRajendra Nayak scratchpad_contents.public_restore_ptr = 169*80140786SRajendra Nayak virt_to_phys(get_restore_pointer()); 170*80140786SRajendra Nayak scratchpad_contents.secure_ram_restore_ptr = 0x0; 171*80140786SRajendra Nayak scratchpad_contents.sdrc_module_semaphore = 0x0; 172*80140786SRajendra Nayak scratchpad_contents.prcm_block_offset = 0x2C; 173*80140786SRajendra Nayak scratchpad_contents.sdrc_block_offset = 0x64; 174*80140786SRajendra Nayak 175*80140786SRajendra Nayak /* Populate the PRCM block contents */ 176*80140786SRajendra Nayak prcm_block_contents.prm_clksrc_ctrl = prm_read_mod_reg(OMAP3430_GR_MOD, 177*80140786SRajendra Nayak OMAP3_PRM_CLKSRC_CTRL_OFFSET); 178*80140786SRajendra Nayak prcm_block_contents.prm_clksel = prm_read_mod_reg(OMAP3430_CCR_MOD, 179*80140786SRajendra Nayak OMAP3_PRM_CLKSEL_OFFSET); 180*80140786SRajendra Nayak prcm_block_contents.cm_clksel_core = 181*80140786SRajendra Nayak cm_read_mod_reg(CORE_MOD, CM_CLKSEL); 182*80140786SRajendra Nayak prcm_block_contents.cm_clksel_wkup = 183*80140786SRajendra Nayak cm_read_mod_reg(WKUP_MOD, CM_CLKSEL); 184*80140786SRajendra Nayak prcm_block_contents.cm_clken_pll = 185*80140786SRajendra Nayak cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKEN_PLL); 186*80140786SRajendra Nayak prcm_block_contents.cm_autoidle_pll = 187*80140786SRajendra Nayak cm_read_mod_reg(PLL_MOD, OMAP3430_CM_AUTOIDLE_PLL); 188*80140786SRajendra Nayak prcm_block_contents.cm_clksel1_pll = 189*80140786SRajendra Nayak cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL1_PLL); 190*80140786SRajendra Nayak prcm_block_contents.cm_clksel2_pll = 191*80140786SRajendra Nayak cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL2_PLL); 192*80140786SRajendra Nayak prcm_block_contents.cm_clksel3_pll = 193*80140786SRajendra Nayak cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL3); 194*80140786SRajendra Nayak prcm_block_contents.cm_clken_pll_mpu = 195*80140786SRajendra Nayak cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKEN_PLL); 196*80140786SRajendra Nayak prcm_block_contents.cm_autoidle_pll_mpu = 197*80140786SRajendra Nayak cm_read_mod_reg(MPU_MOD, OMAP3430_CM_AUTOIDLE_PLL); 198*80140786SRajendra Nayak prcm_block_contents.cm_clksel1_pll_mpu = 199*80140786SRajendra Nayak cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL); 200*80140786SRajendra Nayak prcm_block_contents.cm_clksel2_pll_mpu = 201*80140786SRajendra Nayak cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKSEL2_PLL); 202*80140786SRajendra Nayak prcm_block_contents.prcm_block_size = 0x0; 203*80140786SRajendra Nayak 204*80140786SRajendra Nayak /* Populate the SDRC block contents */ 205*80140786SRajendra Nayak sdrc_block_contents.sysconfig = 206*80140786SRajendra Nayak (sdrc_read_reg(SDRC_SYSCONFIG) & 0xFFFF); 207*80140786SRajendra Nayak sdrc_block_contents.cs_cfg = 208*80140786SRajendra Nayak (sdrc_read_reg(SDRC_CS_CFG) & 0xFFFF); 209*80140786SRajendra Nayak sdrc_block_contents.sharing = 210*80140786SRajendra Nayak (sdrc_read_reg(SDRC_SHARING) & 0xFFFF); 211*80140786SRajendra Nayak sdrc_block_contents.err_type = 212*80140786SRajendra Nayak (sdrc_read_reg(SDRC_ERR_TYPE) & 0xFFFF); 213*80140786SRajendra Nayak sdrc_block_contents.dll_a_ctrl = sdrc_read_reg(SDRC_DLLA_CTRL); 214*80140786SRajendra Nayak sdrc_block_contents.dll_b_ctrl = 0x0; 215*80140786SRajendra Nayak sdrc_block_contents.power = sdrc_read_reg(SDRC_POWER); 216*80140786SRajendra Nayak sdrc_block_contents.cs_0 = 0x0; 217*80140786SRajendra Nayak sdrc_block_contents.mcfg_0 = sdrc_read_reg(SDRC_MCFG_0); 218*80140786SRajendra Nayak sdrc_block_contents.mr_0 = (sdrc_read_reg(SDRC_MR_0) & 0xFFFF); 219*80140786SRajendra Nayak sdrc_block_contents.emr_1_0 = 0x0; 220*80140786SRajendra Nayak sdrc_block_contents.emr_2_0 = 0x0; 221*80140786SRajendra Nayak sdrc_block_contents.emr_3_0 = 0x0; 222*80140786SRajendra Nayak sdrc_block_contents.actim_ctrla_0 = 223*80140786SRajendra Nayak sdrc_read_reg(SDRC_ACTIM_CTRL_A_0); 224*80140786SRajendra Nayak sdrc_block_contents.actim_ctrlb_0 = 225*80140786SRajendra Nayak sdrc_read_reg(SDRC_ACTIM_CTRL_B_0); 226*80140786SRajendra Nayak sdrc_block_contents.rfr_ctrl_0 = 227*80140786SRajendra Nayak sdrc_read_reg(SDRC_RFR_CTRL_0); 228*80140786SRajendra Nayak sdrc_block_contents.cs_1 = 0x0; 229*80140786SRajendra Nayak sdrc_block_contents.mcfg_1 = sdrc_read_reg(SDRC_MCFG_1); 230*80140786SRajendra Nayak sdrc_block_contents.mr_1 = sdrc_read_reg(SDRC_MR_1) & 0xFFFF; 231*80140786SRajendra Nayak sdrc_block_contents.emr_1_1 = 0x0; 232*80140786SRajendra Nayak sdrc_block_contents.emr_2_1 = 0x0; 233*80140786SRajendra Nayak sdrc_block_contents.emr_3_1 = 0x0; 234*80140786SRajendra Nayak sdrc_block_contents.actim_ctrla_1 = 235*80140786SRajendra Nayak sdrc_read_reg(SDRC_ACTIM_CTRL_A_1); 236*80140786SRajendra Nayak sdrc_block_contents.actim_ctrlb_1 = 237*80140786SRajendra Nayak sdrc_read_reg(SDRC_ACTIM_CTRL_B_1); 238*80140786SRajendra Nayak sdrc_block_contents.rfr_ctrl_1 = 239*80140786SRajendra Nayak sdrc_read_reg(SDRC_RFR_CTRL_1); 240*80140786SRajendra Nayak sdrc_block_contents.dcdl_1_ctrl = 0x0; 241*80140786SRajendra Nayak sdrc_block_contents.dcdl_2_ctrl = 0x0; 242*80140786SRajendra Nayak sdrc_block_contents.flags = 0x0; 243*80140786SRajendra Nayak sdrc_block_contents.block_size = 0x0; 244*80140786SRajendra Nayak 245*80140786SRajendra Nayak arm_context_addr = virt_to_phys(omap3_arm_context); 246*80140786SRajendra Nayak 247*80140786SRajendra Nayak /* Copy all the contents to the scratchpad location */ 248*80140786SRajendra Nayak scratchpad_address = OMAP2_L4_IO_ADDRESS(OMAP343X_SCRATCHPAD); 249*80140786SRajendra Nayak memcpy_toio(scratchpad_address, &scratchpad_contents, 250*80140786SRajendra Nayak sizeof(scratchpad_contents)); 251*80140786SRajendra Nayak /* Scratchpad contents being 32 bits, a divide by 4 done here */ 252*80140786SRajendra Nayak memcpy_toio(scratchpad_address + 253*80140786SRajendra Nayak scratchpad_contents.prcm_block_offset, 254*80140786SRajendra Nayak &prcm_block_contents, sizeof(prcm_block_contents)); 255*80140786SRajendra Nayak memcpy_toio(scratchpad_address + 256*80140786SRajendra Nayak scratchpad_contents.sdrc_block_offset, 257*80140786SRajendra Nayak &sdrc_block_contents, sizeof(sdrc_block_contents)); 258*80140786SRajendra Nayak /* 259*80140786SRajendra Nayak * Copies the address of the location in SDRAM where ARM 260*80140786SRajendra Nayak * registers get saved during a MPU OFF transition. 261*80140786SRajendra Nayak */ 262*80140786SRajendra Nayak memcpy_toio(scratchpad_address + 263*80140786SRajendra Nayak scratchpad_contents.sdrc_block_offset + 264*80140786SRajendra Nayak sizeof(sdrc_block_contents), &arm_context_addr, 4); 265*80140786SRajendra Nayak } 266*80140786SRajendra Nayak 267*80140786SRajendra Nayak #endif /* CONFIG_ARCH_OMAP3 */ 268