1 /* 2 * linux/arch/arm/mach-omap2/sdrc2xxx.c 3 * 4 * SDRAM timing related functions for OMAP2xxx 5 * 6 * Copyright (C) 2005, 2008 Texas Instruments Inc. 7 * Copyright (C) 2005, 2008 Nokia Corporation 8 * 9 * Tony Lindgren <tony@atomide.com> 10 * Paul Walmsley 11 * Richard Woodruff <r-woodruff2@ti.com> 12 * 13 * This program is free software; you can redistribute it and/or modify 14 * it under the terms of the GNU General Public License version 2 as 15 * published by the Free Software Foundation. 16 */ 17 18 #include <linux/module.h> 19 #include <linux/kernel.h> 20 #include <linux/device.h> 21 #include <linux/list.h> 22 #include <linux/errno.h> 23 #include <linux/delay.h> 24 #include <linux/clk.h> 25 #include <linux/io.h> 26 27 #include <plat/clock.h> 28 #include <plat/sram.h> 29 30 #include "soc.h" 31 #include "iomap.h" 32 #include "common.h" 33 #include "prm2xxx_3xxx.h" 34 #include "clock.h" 35 #include "sdrc.h" 36 37 /* Memory timing, DLL mode flags */ 38 #define M_DDR 1 39 #define M_LOCK_CTRL (1 << 2) 40 #define M_UNLOCK 0 41 #define M_LOCK 1 42 43 44 static struct memory_timings mem_timings; 45 static u32 curr_perf_level = CORE_CLK_SRC_DPLL_X2; 46 47 static u32 omap2xxx_sdrc_get_slow_dll_ctrl(void) 48 { 49 return mem_timings.slow_dll_ctrl; 50 } 51 52 static u32 omap2xxx_sdrc_get_fast_dll_ctrl(void) 53 { 54 return mem_timings.fast_dll_ctrl; 55 } 56 57 static u32 omap2xxx_sdrc_get_type(void) 58 { 59 return mem_timings.m_type; 60 } 61 62 /* 63 * Check the DLL lock state, and return tue if running in unlock mode. 64 * This is needed to compensate for the shifted DLL value in unlock mode. 65 */ 66 u32 omap2xxx_sdrc_dll_is_unlocked(void) 67 { 68 /* dlla and dllb are a set */ 69 u32 dll_state = sdrc_read_reg(SDRC_DLLA_CTRL); 70 71 if ((dll_state & (1 << 2)) == (1 << 2)) 72 return 1; 73 else 74 return 0; 75 } 76 77 /* 78 * 'level' is the value to store to CM_CLKSEL2_PLL.CORE_CLK_SRC. 79 * Practical values are CORE_CLK_SRC_DPLL (for CORE_CLK = DPLL_CLK) or 80 * CORE_CLK_SRC_DPLL_X2 (for CORE_CLK = * DPLL_CLK * 2) 81 * 82 * Used by the clock framework during CORE DPLL changes 83 */ 84 u32 omap2xxx_sdrc_reprogram(u32 level, u32 force) 85 { 86 u32 dll_ctrl, m_type; 87 u32 prev = curr_perf_level; 88 unsigned long flags; 89 90 if ((curr_perf_level == level) && !force) 91 return prev; 92 93 if (level == CORE_CLK_SRC_DPLL) 94 dll_ctrl = omap2xxx_sdrc_get_slow_dll_ctrl(); 95 else if (level == CORE_CLK_SRC_DPLL_X2) 96 dll_ctrl = omap2xxx_sdrc_get_fast_dll_ctrl(); 97 else 98 return prev; 99 100 m_type = omap2xxx_sdrc_get_type(); 101 102 local_irq_save(flags); 103 /* 104 * XXX These calls should be abstracted out through a 105 * prm2xxx.c function 106 */ 107 if (cpu_is_omap2420()) 108 __raw_writel(0xffff, OMAP2420_PRCM_VOLTSETUP); 109 else 110 __raw_writel(0xffff, OMAP2430_PRCM_VOLTSETUP); 111 omap2_sram_reprogram_sdrc(level, dll_ctrl, m_type); 112 curr_perf_level = level; 113 local_irq_restore(flags); 114 115 return prev; 116 } 117 118 /* Used by the clock framework during CORE DPLL changes */ 119 void omap2xxx_sdrc_init_params(u32 force_lock_to_unlock_mode) 120 { 121 unsigned long dll_cnt; 122 u32 fast_dll = 0; 123 124 /* DDR = 1, SDR = 0 */ 125 mem_timings.m_type = !((sdrc_read_reg(SDRC_MR_0) & 0x3) == 0x1); 126 127 /* 2422 es2.05 and beyond has a single SIP DDR instead of 2 like others. 128 * In the case of 2422, its ok to use CS1 instead of CS0. 129 */ 130 if (cpu_is_omap2422()) 131 mem_timings.base_cs = 1; 132 else 133 mem_timings.base_cs = 0; 134 135 if (mem_timings.m_type != M_DDR) 136 return; 137 138 /* With DDR we need to determine the low frequency DLL value */ 139 if (((mem_timings.fast_dll_ctrl & (1 << 2)) == M_LOCK_CTRL)) 140 mem_timings.dll_mode = M_UNLOCK; 141 else 142 mem_timings.dll_mode = M_LOCK; 143 144 if (mem_timings.base_cs == 0) { 145 fast_dll = sdrc_read_reg(SDRC_DLLA_CTRL); 146 dll_cnt = sdrc_read_reg(SDRC_DLLA_STATUS) & 0xff00; 147 } else { 148 fast_dll = sdrc_read_reg(SDRC_DLLB_CTRL); 149 dll_cnt = sdrc_read_reg(SDRC_DLLB_STATUS) & 0xff00; 150 } 151 if (force_lock_to_unlock_mode) { 152 fast_dll &= ~0xff00; 153 fast_dll |= dll_cnt; /* Current lock mode */ 154 } 155 /* set fast timings with DLL filter disabled */ 156 mem_timings.fast_dll_ctrl = (fast_dll | (3 << 8)); 157 158 /* No disruptions, DDR will be offline & C-ABI not followed */ 159 omap2_sram_ddr_init(&mem_timings.slow_dll_ctrl, 160 mem_timings.fast_dll_ctrl, 161 mem_timings.base_cs, 162 force_lock_to_unlock_mode); 163 mem_timings.slow_dll_ctrl &= 0xff00; /* Keep lock value */ 164 165 /* Turn status into unlock ctrl */ 166 mem_timings.slow_dll_ctrl |= 167 ((mem_timings.fast_dll_ctrl & 0xF) | (1 << 2)); 168 169 /* 90 degree phase for anything below 133Mhz + disable DLL filter */ 170 mem_timings.slow_dll_ctrl |= ((1 << 1) | (3 << 8)); 171 } 172