Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * linux/arch/arm/mach-omap2/sdrc2xxx.c
0004  *
0005  * SDRAM timing related functions for OMAP2xxx
0006  *
0007  * Copyright (C) 2005, 2008 Texas Instruments Inc.
0008  * Copyright (C) 2005, 2008 Nokia Corporation
0009  *
0010  * Tony Lindgren <tony@atomide.com>
0011  * Paul Walmsley
0012  * Richard Woodruff <r-woodruff2@ti.com>
0013  */
0014 
0015 #include <linux/module.h>
0016 #include <linux/kernel.h>
0017 #include <linux/device.h>
0018 #include <linux/list.h>
0019 #include <linux/errno.h>
0020 #include <linux/delay.h>
0021 #include <linux/clk.h>
0022 #include <linux/io.h>
0023 
0024 #include "soc.h"
0025 #include "iomap.h"
0026 #include "common.h"
0027 #include "prm2xxx.h"
0028 #include "clock.h"
0029 #include "sdrc.h"
0030 #include "sram.h"
0031 
0032 /* Memory timing, DLL mode flags */
0033 #define M_DDR       1
0034 #define M_LOCK_CTRL (1 << 2)
0035 #define M_UNLOCK    0
0036 #define M_LOCK      1
0037 
0038 
0039 static struct memory_timings mem_timings;
0040 static u32 curr_perf_level = CORE_CLK_SRC_DPLL_X2;
0041 
0042 static u32 omap2xxx_sdrc_get_slow_dll_ctrl(void)
0043 {
0044     return mem_timings.slow_dll_ctrl;
0045 }
0046 
0047 static u32 omap2xxx_sdrc_get_fast_dll_ctrl(void)
0048 {
0049     return mem_timings.fast_dll_ctrl;
0050 }
0051 
0052 static u32 omap2xxx_sdrc_get_type(void)
0053 {
0054     return mem_timings.m_type;
0055 }
0056 
0057 /*
0058  * Check the DLL lock state, and return tue if running in unlock mode.
0059  * This is needed to compensate for the shifted DLL value in unlock mode.
0060  */
0061 u32 omap2xxx_sdrc_dll_is_unlocked(void)
0062 {
0063     /* dlla and dllb are a set */
0064     u32 dll_state = sdrc_read_reg(SDRC_DLLA_CTRL);
0065 
0066     if ((dll_state & (1 << 2)) == (1 << 2))
0067         return 1;
0068     else
0069         return 0;
0070 }
0071 
0072 /*
0073  * 'level' is the value to store to CM_CLKSEL2_PLL.CORE_CLK_SRC.
0074  * Practical values are CORE_CLK_SRC_DPLL (for CORE_CLK = DPLL_CLK) or
0075  * CORE_CLK_SRC_DPLL_X2 (for CORE_CLK = * DPLL_CLK * 2)
0076  *
0077  * Used by the clock framework during CORE DPLL changes
0078  */
0079 u32 omap2xxx_sdrc_reprogram(u32 level, u32 force)
0080 {
0081     u32 dll_ctrl, m_type;
0082     u32 prev = curr_perf_level;
0083     unsigned long flags;
0084 
0085     if ((curr_perf_level == level) && !force)
0086         return prev;
0087 
0088     if (level == CORE_CLK_SRC_DPLL)
0089         dll_ctrl = omap2xxx_sdrc_get_slow_dll_ctrl();
0090     else if (level == CORE_CLK_SRC_DPLL_X2)
0091         dll_ctrl = omap2xxx_sdrc_get_fast_dll_ctrl();
0092     else
0093         return prev;
0094 
0095     m_type = omap2xxx_sdrc_get_type();
0096 
0097     local_irq_save(flags);
0098     /*
0099      * XXX These calls should be abstracted out through a
0100      * prm2xxx.c function
0101      */
0102     if (cpu_is_omap2420())
0103         writel_relaxed(0xffff, OMAP2420_PRCM_VOLTSETUP);
0104     else
0105         writel_relaxed(0xffff, OMAP2430_PRCM_VOLTSETUP);
0106     omap2_sram_reprogram_sdrc(level, dll_ctrl, m_type);
0107     curr_perf_level = level;
0108     local_irq_restore(flags);
0109 
0110     return prev;
0111 }
0112 
0113 /* Used by the clock framework during CORE DPLL changes */
0114 void omap2xxx_sdrc_init_params(u32 force_lock_to_unlock_mode)
0115 {
0116     unsigned long dll_cnt;
0117     u32 fast_dll = 0;
0118 
0119     /* DDR = 1, SDR = 0 */
0120     mem_timings.m_type = !((sdrc_read_reg(SDRC_MR_0) & 0x3) == 0x1);
0121 
0122     /* 2422 es2.05 and beyond has a single SIP DDR instead of 2 like others.
0123      * In the case of 2422, its ok to use CS1 instead of CS0.
0124      */
0125     if (cpu_is_omap2422())
0126         mem_timings.base_cs = 1;
0127     else
0128         mem_timings.base_cs = 0;
0129 
0130     if (mem_timings.m_type != M_DDR)
0131         return;
0132 
0133     /* With DDR we need to determine the low frequency DLL value */
0134     if (((mem_timings.fast_dll_ctrl & (1 << 2)) == M_LOCK_CTRL))
0135         mem_timings.dll_mode = M_UNLOCK;
0136     else
0137         mem_timings.dll_mode = M_LOCK;
0138 
0139     if (mem_timings.base_cs == 0) {
0140         fast_dll = sdrc_read_reg(SDRC_DLLA_CTRL);
0141         dll_cnt = sdrc_read_reg(SDRC_DLLA_STATUS) & 0xff00;
0142     } else {
0143         fast_dll = sdrc_read_reg(SDRC_DLLB_CTRL);
0144         dll_cnt = sdrc_read_reg(SDRC_DLLB_STATUS) & 0xff00;
0145     }
0146     if (force_lock_to_unlock_mode) {
0147         fast_dll &= ~0xff00;
0148         fast_dll |= dll_cnt;        /* Current lock mode */
0149     }
0150     /* set fast timings with DLL filter disabled */
0151     mem_timings.fast_dll_ctrl = (fast_dll | (3 << 8));
0152 
0153     /* No disruptions, DDR will be offline & C-ABI not followed */
0154     omap2_sram_ddr_init(&mem_timings.slow_dll_ctrl,
0155                 mem_timings.fast_dll_ctrl,
0156                 mem_timings.base_cs,
0157                 force_lock_to_unlock_mode);
0158     mem_timings.slow_dll_ctrl &= 0xff00;    /* Keep lock value */
0159 
0160     /* Turn status into unlock ctrl */
0161     mem_timings.slow_dll_ctrl |=
0162         ((mem_timings.fast_dll_ctrl & 0xF) | (1 << 2));
0163 
0164     /* 90 degree phase for anything below 133MHz + disable DLL filter */
0165     mem_timings.slow_dll_ctrl |= ((1 << 1) | (3 << 8));
0166 }