162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * SMS/SDRC (SDRAM controller) common code for OMAP2/3 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2005, 2008 Texas Instruments Inc. 662306a36Sopenharmony_ci * Copyright (C) 2005, 2008 Nokia Corporation 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * Tony Lindgren <tony@atomide.com> 962306a36Sopenharmony_ci * Paul Walmsley 1062306a36Sopenharmony_ci * Richard Woodruff <r-woodruff2@ti.com> 1162306a36Sopenharmony_ci */ 1262306a36Sopenharmony_ci#undef DEBUG 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#include <linux/module.h> 1562306a36Sopenharmony_ci#include <linux/kernel.h> 1662306a36Sopenharmony_ci#include <linux/device.h> 1762306a36Sopenharmony_ci#include <linux/list.h> 1862306a36Sopenharmony_ci#include <linux/errno.h> 1962306a36Sopenharmony_ci#include <linux/delay.h> 2062306a36Sopenharmony_ci#include <linux/clk.h> 2162306a36Sopenharmony_ci#include <linux/io.h> 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci#include "common.h" 2462306a36Sopenharmony_ci#include "clock.h" 2562306a36Sopenharmony_ci#include "sdrc.h" 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_cistatic struct omap_sdrc_params *sdrc_init_params_cs0, *sdrc_init_params_cs1; 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_civoid __iomem *omap2_sdrc_base; 3062306a36Sopenharmony_civoid __iomem *omap2_sms_base; 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_cistruct omap2_sms_regs { 3362306a36Sopenharmony_ci u32 sms_sysconfig; 3462306a36Sopenharmony_ci}; 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_cistatic struct omap2_sms_regs sms_context; 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci/* SDRC_POWER register bits */ 3962306a36Sopenharmony_ci#define SDRC_POWER_EXTCLKDIS_SHIFT 3 4062306a36Sopenharmony_ci#define SDRC_POWER_PWDENA_SHIFT 2 4162306a36Sopenharmony_ci#define SDRC_POWER_PAGEPOLICY_SHIFT 0 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci/** 4462306a36Sopenharmony_ci * omap2_sms_save_context - Save SMS registers 4562306a36Sopenharmony_ci * 4662306a36Sopenharmony_ci * Save SMS registers that need to be restored after off mode. 4762306a36Sopenharmony_ci */ 4862306a36Sopenharmony_cistatic void omap2_sms_save_context(void) 4962306a36Sopenharmony_ci{ 5062306a36Sopenharmony_ci sms_context.sms_sysconfig = sms_read_reg(SMS_SYSCONFIG); 5162306a36Sopenharmony_ci} 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci/** 5462306a36Sopenharmony_ci * omap2_sms_restore_context - Restore SMS registers 5562306a36Sopenharmony_ci * 5662306a36Sopenharmony_ci * Restore SMS registers that need to be Restored after off mode. 5762306a36Sopenharmony_ci */ 5862306a36Sopenharmony_civoid omap2_sms_restore_context(void) 5962306a36Sopenharmony_ci{ 6062306a36Sopenharmony_ci sms_write_reg(sms_context.sms_sysconfig, SMS_SYSCONFIG); 6162306a36Sopenharmony_ci} 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_civoid __init omap2_set_globals_sdrc(void __iomem *sdrc, void __iomem *sms) 6462306a36Sopenharmony_ci{ 6562306a36Sopenharmony_ci omap2_sdrc_base = sdrc; 6662306a36Sopenharmony_ci omap2_sms_base = sms; 6762306a36Sopenharmony_ci} 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci/** 7062306a36Sopenharmony_ci * omap2_sdrc_init - initialize SMS, SDRC devices on boot 7162306a36Sopenharmony_ci * @sdrc_cs[01]: pointers to a null-terminated list of struct omap_sdrc_params 7262306a36Sopenharmony_ci * Support for 2 chip selects timings 7362306a36Sopenharmony_ci * 7462306a36Sopenharmony_ci * Turn on smart idle modes for SDRAM scheduler and controller. 7562306a36Sopenharmony_ci * Program a known-good configuration for the SDRC to deal with buggy 7662306a36Sopenharmony_ci * bootloaders. 7762306a36Sopenharmony_ci */ 7862306a36Sopenharmony_civoid __init omap2_sdrc_init(struct omap_sdrc_params *sdrc_cs0, 7962306a36Sopenharmony_ci struct omap_sdrc_params *sdrc_cs1) 8062306a36Sopenharmony_ci{ 8162306a36Sopenharmony_ci u32 l; 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci l = sms_read_reg(SMS_SYSCONFIG); 8462306a36Sopenharmony_ci l &= ~(0x3 << 3); 8562306a36Sopenharmony_ci l |= (0x2 << 3); 8662306a36Sopenharmony_ci sms_write_reg(l, SMS_SYSCONFIG); 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci l = sdrc_read_reg(SDRC_SYSCONFIG); 8962306a36Sopenharmony_ci l &= ~(0x3 << 3); 9062306a36Sopenharmony_ci l |= (0x2 << 3); 9162306a36Sopenharmony_ci sdrc_write_reg(l, SDRC_SYSCONFIG); 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci sdrc_init_params_cs0 = sdrc_cs0; 9462306a36Sopenharmony_ci sdrc_init_params_cs1 = sdrc_cs1; 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci /* XXX Enable SRFRONIDLEREQ here also? */ 9762306a36Sopenharmony_ci /* 9862306a36Sopenharmony_ci * PWDENA should not be set due to 34xx erratum 1.150 - PWDENA 9962306a36Sopenharmony_ci * can cause random memory corruption 10062306a36Sopenharmony_ci */ 10162306a36Sopenharmony_ci l = (1 << SDRC_POWER_EXTCLKDIS_SHIFT) | 10262306a36Sopenharmony_ci (1 << SDRC_POWER_PAGEPOLICY_SHIFT); 10362306a36Sopenharmony_ci sdrc_write_reg(l, SDRC_POWER); 10462306a36Sopenharmony_ci omap2_sms_save_context(); 10562306a36Sopenharmony_ci} 106