1f2ab9977SPaul Walmsley /* 2f2ab9977SPaul Walmsley * SMS/SDRC (SDRAM controller) common code for OMAP2/3 3f2ab9977SPaul Walmsley * 4f2ab9977SPaul Walmsley * Copyright (C) 2005, 2008 Texas Instruments Inc. 5f2ab9977SPaul Walmsley * Copyright (C) 2005, 2008 Nokia Corporation 6f2ab9977SPaul Walmsley * 7f2ab9977SPaul Walmsley * Tony Lindgren <tony@atomide.com> 8f2ab9977SPaul Walmsley * Paul Walmsley 9f2ab9977SPaul Walmsley * Richard Woodruff <r-woodruff2@ti.com> 10f2ab9977SPaul Walmsley * 11f2ab9977SPaul Walmsley * This program is free software; you can redistribute it and/or modify 12f2ab9977SPaul Walmsley * it under the terms of the GNU General Public License version 2 as 13f2ab9977SPaul Walmsley * published by the Free Software Foundation. 14f2ab9977SPaul Walmsley */ 1587246b75SPaul Walmsley #undef DEBUG 16f2ab9977SPaul Walmsley 17f2ab9977SPaul Walmsley #include <linux/module.h> 18f2ab9977SPaul Walmsley #include <linux/kernel.h> 19f2ab9977SPaul Walmsley #include <linux/device.h> 20f2ab9977SPaul Walmsley #include <linux/list.h> 21f2ab9977SPaul Walmsley #include <linux/errno.h> 22f2ab9977SPaul Walmsley #include <linux/delay.h> 23f2ab9977SPaul Walmsley #include <linux/clk.h> 24f2ab9977SPaul Walmsley #include <linux/io.h> 25f2ab9977SPaul Walmsley 26ce491cf8STony Lindgren #include <plat/common.h> 27ce491cf8STony Lindgren #include <plat/clock.h> 28ce491cf8STony Lindgren #include <plat/sram.h> 29f2ab9977SPaul Walmsley 30ce491cf8STony Lindgren #include <plat/sdrc.h> 31f2ab9977SPaul Walmsley #include "sdrc.h" 32f2ab9977SPaul Walmsley 3358cda884SJean Pihet static struct omap_sdrc_params *sdrc_init_params_cs0, *sdrc_init_params_cs1; 3487246b75SPaul Walmsley 35f2ab9977SPaul Walmsley void __iomem *omap2_sdrc_base; 36f2ab9977SPaul Walmsley void __iomem *omap2_sms_base; 37f2ab9977SPaul Walmsley 388a917d2fSKalle Jokiniemi struct omap2_sms_regs { 398a917d2fSKalle Jokiniemi u32 sms_sysconfig; 408a917d2fSKalle Jokiniemi }; 418a917d2fSKalle Jokiniemi 428a917d2fSKalle Jokiniemi static struct omap2_sms_regs sms_context; 438a917d2fSKalle Jokiniemi 4498cfe5abSPaul Walmsley /* SDRC_POWER register bits */ 4598cfe5abSPaul Walmsley #define SDRC_POWER_EXTCLKDIS_SHIFT 3 4698cfe5abSPaul Walmsley #define SDRC_POWER_PWDENA_SHIFT 2 4798cfe5abSPaul Walmsley #define SDRC_POWER_PAGEPOLICY_SHIFT 0 4887246b75SPaul Walmsley 4987246b75SPaul Walmsley /** 508a917d2fSKalle Jokiniemi * omap2_sms_save_context - Save SMS registers 518a917d2fSKalle Jokiniemi * 528a917d2fSKalle Jokiniemi * Save SMS registers that need to be restored after off mode. 538a917d2fSKalle Jokiniemi */ 548a917d2fSKalle Jokiniemi void omap2_sms_save_context(void) 558a917d2fSKalle Jokiniemi { 568a917d2fSKalle Jokiniemi sms_context.sms_sysconfig = sms_read_reg(SMS_SYSCONFIG); 578a917d2fSKalle Jokiniemi } 588a917d2fSKalle Jokiniemi 598a917d2fSKalle Jokiniemi /** 608a917d2fSKalle Jokiniemi * omap2_sms_restore_context - Restore SMS registers 618a917d2fSKalle Jokiniemi * 628a917d2fSKalle Jokiniemi * Restore SMS registers that need to be Restored after off mode. 638a917d2fSKalle Jokiniemi */ 648a917d2fSKalle Jokiniemi void omap2_sms_restore_context(void) 658a917d2fSKalle Jokiniemi { 668a917d2fSKalle Jokiniemi sms_write_reg(sms_context.sms_sysconfig, SMS_SYSCONFIG); 678a917d2fSKalle Jokiniemi } 688a917d2fSKalle Jokiniemi 698a917d2fSKalle Jokiniemi /** 7087246b75SPaul Walmsley * omap2_sdrc_get_params - return SDRC register values for a given clock rate 7187246b75SPaul Walmsley * @r: SDRC clock rate (in Hz) 7258cda884SJean Pihet * @sdrc_cs0: chip select 0 ram timings ** 7358cda884SJean Pihet * @sdrc_cs1: chip select 1 ram timings ** 7487246b75SPaul Walmsley * 7587246b75SPaul Walmsley * Return pre-calculated values for the SDRC_ACTIM_CTRLA, 7658cda884SJean Pihet * SDRC_ACTIM_CTRLB, SDRC_RFR_CTRL and SDRC_MR registers in sdrc_cs[01] 7758cda884SJean Pihet * structs,for a given SDRC clock rate 'r'. 7858cda884SJean Pihet * These parameters control various timing delays in the SDRAM controller 7958cda884SJean Pihet * that are expressed in terms of the number of SDRC clock cycles to 8058cda884SJean Pihet * wait; hence the clock rate dependency. 8158cda884SJean Pihet * 8258cda884SJean Pihet * Supports 2 different timing parameters for both chip selects. 8358cda884SJean Pihet * 8458cda884SJean Pihet * Note 1: the sdrc_init_params_cs[01] must be sorted rate descending. 8558cda884SJean Pihet * Note 2: If sdrc_init_params_cs_1 is not NULL it must be of same size 8658cda884SJean Pihet * as sdrc_init_params_cs_0. 8758cda884SJean Pihet * 8858cda884SJean Pihet * Fills in the struct omap_sdrc_params * for each chip select. 8958cda884SJean Pihet * Returns 0 upon success or -1 upon failure. 9087246b75SPaul Walmsley */ 9158cda884SJean Pihet int omap2_sdrc_get_params(unsigned long r, 9258cda884SJean Pihet struct omap_sdrc_params **sdrc_cs0, 9358cda884SJean Pihet struct omap_sdrc_params **sdrc_cs1) 9487246b75SPaul Walmsley { 9558cda884SJean Pihet struct omap_sdrc_params *sp0, *sp1; 9687246b75SPaul Walmsley 9758cda884SJean Pihet if (!sdrc_init_params_cs0) 9858cda884SJean Pihet return -1; 998bd22949SKevin Hilman 10058cda884SJean Pihet sp0 = sdrc_init_params_cs0; 10158cda884SJean Pihet sp1 = sdrc_init_params_cs1; 10287246b75SPaul Walmsley 10358cda884SJean Pihet while (sp0->rate && sp0->rate != r) { 10458cda884SJean Pihet sp0++; 10558cda884SJean Pihet if (sdrc_init_params_cs1) 10658cda884SJean Pihet sp1++; 10758cda884SJean Pihet } 10887246b75SPaul Walmsley 10958cda884SJean Pihet if (!sp0->rate) 11058cda884SJean Pihet return -1; 11187246b75SPaul Walmsley 11258cda884SJean Pihet *sdrc_cs0 = sp0; 11358cda884SJean Pihet *sdrc_cs1 = sp1; 11458cda884SJean Pihet return 0; 11587246b75SPaul Walmsley } 11687246b75SPaul Walmsley 11787246b75SPaul Walmsley 118f2ab9977SPaul Walmsley void __init omap2_set_globals_sdrc(struct omap_globals *omap2_globals) 119f2ab9977SPaul Walmsley { 1204c3cf901STony Lindgren if (omap2_globals->sdrc) 1214c3cf901STony Lindgren omap2_sdrc_base = omap2_globals->sdrc; 1224c3cf901STony Lindgren if (omap2_globals->sms) 1234c3cf901STony Lindgren omap2_sms_base = omap2_globals->sms; 124f2ab9977SPaul Walmsley } 125f2ab9977SPaul Walmsley 12698cfe5abSPaul Walmsley /** 12798cfe5abSPaul Walmsley * omap2_sdrc_init - initialize SMS, SDRC devices on boot 12858cda884SJean Pihet * @sdrc_cs[01]: pointers to a null-terminated list of struct omap_sdrc_params 12958cda884SJean Pihet * Support for 2 chip selects timings 13098cfe5abSPaul Walmsley * 13198cfe5abSPaul Walmsley * Turn on smart idle modes for SDRAM scheduler and controller. 13298cfe5abSPaul Walmsley * Program a known-good configuration for the SDRC to deal with buggy 13398cfe5abSPaul Walmsley * bootloaders. 13498cfe5abSPaul Walmsley */ 13558cda884SJean Pihet void __init omap2_sdrc_init(struct omap_sdrc_params *sdrc_cs0, 13658cda884SJean Pihet struct omap_sdrc_params *sdrc_cs1) 137f2ab9977SPaul Walmsley { 138f2ab9977SPaul Walmsley u32 l; 139f2ab9977SPaul Walmsley 140f2ab9977SPaul Walmsley l = sms_read_reg(SMS_SYSCONFIG); 141f2ab9977SPaul Walmsley l &= ~(0x3 << 3); 142f2ab9977SPaul Walmsley l |= (0x2 << 3); 143f2ab9977SPaul Walmsley sms_write_reg(l, SMS_SYSCONFIG); 144f2ab9977SPaul Walmsley 145f2ab9977SPaul Walmsley l = sdrc_read_reg(SDRC_SYSCONFIG); 146f2ab9977SPaul Walmsley l &= ~(0x3 << 3); 147f2ab9977SPaul Walmsley l |= (0x2 << 3); 148f2ab9977SPaul Walmsley sdrc_write_reg(l, SDRC_SYSCONFIG); 14987246b75SPaul Walmsley 15058cda884SJean Pihet sdrc_init_params_cs0 = sdrc_cs0; 15158cda884SJean Pihet sdrc_init_params_cs1 = sdrc_cs1; 15298cfe5abSPaul Walmsley 15398cfe5abSPaul Walmsley /* XXX Enable SRFRONIDLEREQ here also? */ 15475f251e3SPaul Walmsley /* 15575f251e3SPaul Walmsley * PWDENA should not be set due to 34xx erratum 1.150 - PWDENA 15675f251e3SPaul Walmsley * can cause random memory corruption 15775f251e3SPaul Walmsley */ 15898cfe5abSPaul Walmsley l = (1 << SDRC_POWER_EXTCLKDIS_SHIFT) | 15998cfe5abSPaul Walmsley (1 << SDRC_POWER_PAGEPOLICY_SHIFT); 16098cfe5abSPaul Walmsley sdrc_write_reg(l, SDRC_POWER); 1618a917d2fSKalle Jokiniemi omap2_sms_save_context(); 162f2ab9977SPaul Walmsley } 163b90f8e72STomi Valkeinen 164b90f8e72STomi Valkeinen void omap2_sms_write_rot_control(u32 val, unsigned ctx) 165b90f8e72STomi Valkeinen { 166b90f8e72STomi Valkeinen sms_write_reg(val, SMS_ROT_CONTROL(ctx)); 167b90f8e72STomi Valkeinen } 168b90f8e72STomi Valkeinen 169b90f8e72STomi Valkeinen void omap2_sms_write_rot_size(u32 val, unsigned ctx) 170b90f8e72STomi Valkeinen { 171b90f8e72STomi Valkeinen sms_write_reg(val, SMS_ROT_SIZE(ctx)); 172b90f8e72STomi Valkeinen } 173b90f8e72STomi Valkeinen 174b90f8e72STomi Valkeinen void omap2_sms_write_rot_physical_ba(u32 val, unsigned ctx) 175b90f8e72STomi Valkeinen { 176b90f8e72STomi Valkeinen sms_write_reg(val, SMS_ROT_PHYSICAL_BA(ctx)); 177b90f8e72STomi Valkeinen } 178b90f8e72STomi Valkeinen 179