sdrc.c (3918B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * SMS/SDRC (SDRAM controller) common code for OMAP2/3 4 * 5 * Copyright (C) 2005, 2008 Texas Instruments Inc. 6 * Copyright (C) 2005, 2008 Nokia Corporation 7 * 8 * Tony Lindgren <tony@atomide.com> 9 * Paul Walmsley 10 * Richard Woodruff <r-woodruff2@ti.com> 11 */ 12#undef DEBUG 13 14#include <linux/module.h> 15#include <linux/kernel.h> 16#include <linux/device.h> 17#include <linux/list.h> 18#include <linux/errno.h> 19#include <linux/delay.h> 20#include <linux/clk.h> 21#include <linux/io.h> 22 23#include "common.h" 24#include "clock.h" 25#include "sdrc.h" 26 27static struct omap_sdrc_params *sdrc_init_params_cs0, *sdrc_init_params_cs1; 28 29void __iomem *omap2_sdrc_base; 30void __iomem *omap2_sms_base; 31 32struct omap2_sms_regs { 33 u32 sms_sysconfig; 34}; 35 36static struct omap2_sms_regs sms_context; 37 38/* SDRC_POWER register bits */ 39#define SDRC_POWER_EXTCLKDIS_SHIFT 3 40#define SDRC_POWER_PWDENA_SHIFT 2 41#define SDRC_POWER_PAGEPOLICY_SHIFT 0 42 43/** 44 * omap2_sms_save_context - Save SMS registers 45 * 46 * Save SMS registers that need to be restored after off mode. 47 */ 48void omap2_sms_save_context(void) 49{ 50 sms_context.sms_sysconfig = sms_read_reg(SMS_SYSCONFIG); 51} 52 53/** 54 * omap2_sms_restore_context - Restore SMS registers 55 * 56 * Restore SMS registers that need to be Restored after off mode. 57 */ 58void omap2_sms_restore_context(void) 59{ 60 sms_write_reg(sms_context.sms_sysconfig, SMS_SYSCONFIG); 61} 62 63/** 64 * omap2_sdrc_get_params - return SDRC register values for a given clock rate 65 * @r: SDRC clock rate (in Hz) 66 * @sdrc_cs0: chip select 0 ram timings ** 67 * @sdrc_cs1: chip select 1 ram timings ** 68 * 69 * Return pre-calculated values for the SDRC_ACTIM_CTRLA, 70 * SDRC_ACTIM_CTRLB, SDRC_RFR_CTRL and SDRC_MR registers in sdrc_cs[01] 71 * structs,for a given SDRC clock rate 'r'. 72 * These parameters control various timing delays in the SDRAM controller 73 * that are expressed in terms of the number of SDRC clock cycles to 74 * wait; hence the clock rate dependency. 75 * 76 * Supports 2 different timing parameters for both chip selects. 77 * 78 * Note 1: the sdrc_init_params_cs[01] must be sorted rate descending. 79 * Note 2: If sdrc_init_params_cs_1 is not NULL it must be of same size 80 * as sdrc_init_params_cs_0. 81 * 82 * Fills in the struct omap_sdrc_params * for each chip select. 83 * Returns 0 upon success or -1 upon failure. 84 */ 85int omap2_sdrc_get_params(unsigned long r, 86 struct omap_sdrc_params **sdrc_cs0, 87 struct omap_sdrc_params **sdrc_cs1) 88{ 89 struct omap_sdrc_params *sp0, *sp1; 90 91 if (!sdrc_init_params_cs0) 92 return -1; 93 94 sp0 = sdrc_init_params_cs0; 95 sp1 = sdrc_init_params_cs1; 96 97 while (sp0->rate && sp0->rate != r) { 98 sp0++; 99 if (sdrc_init_params_cs1) 100 sp1++; 101 } 102 103 if (!sp0->rate) 104 return -1; 105 106 *sdrc_cs0 = sp0; 107 *sdrc_cs1 = sp1; 108 return 0; 109} 110 111 112void __init omap2_set_globals_sdrc(void __iomem *sdrc, void __iomem *sms) 113{ 114 omap2_sdrc_base = sdrc; 115 omap2_sms_base = sms; 116} 117 118/** 119 * omap2_sdrc_init - initialize SMS, SDRC devices on boot 120 * @sdrc_cs[01]: pointers to a null-terminated list of struct omap_sdrc_params 121 * Support for 2 chip selects timings 122 * 123 * Turn on smart idle modes for SDRAM scheduler and controller. 124 * Program a known-good configuration for the SDRC to deal with buggy 125 * bootloaders. 126 */ 127void __init omap2_sdrc_init(struct omap_sdrc_params *sdrc_cs0, 128 struct omap_sdrc_params *sdrc_cs1) 129{ 130 u32 l; 131 132 l = sms_read_reg(SMS_SYSCONFIG); 133 l &= ~(0x3 << 3); 134 l |= (0x2 << 3); 135 sms_write_reg(l, SMS_SYSCONFIG); 136 137 l = sdrc_read_reg(SDRC_SYSCONFIG); 138 l &= ~(0x3 << 3); 139 l |= (0x2 << 3); 140 sdrc_write_reg(l, SDRC_SYSCONFIG); 141 142 sdrc_init_params_cs0 = sdrc_cs0; 143 sdrc_init_params_cs1 = sdrc_cs1; 144 145 /* XXX Enable SRFRONIDLEREQ here also? */ 146 /* 147 * PWDENA should not be set due to 34xx erratum 1.150 - PWDENA 148 * can cause random memory corruption 149 */ 150 l = (1 << SDRC_POWER_EXTCLKDIS_SHIFT) | 151 (1 << SDRC_POWER_PAGEPOLICY_SHIFT); 152 sdrc_write_reg(l, SDRC_POWER); 153 omap2_sms_save_context(); 154}