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 26f2ab9977SPaul Walmsley #include <mach/common.h> 27f2ab9977SPaul Walmsley #include <mach/clock.h> 28f2ab9977SPaul Walmsley #include <mach/sram.h> 29f2ab9977SPaul Walmsley 30f2ab9977SPaul Walmsley #include "prm.h" 31f2ab9977SPaul Walmsley 32f2ab9977SPaul Walmsley #include <mach/sdrc.h> 33f2ab9977SPaul Walmsley #include "sdrc.h" 34f2ab9977SPaul Walmsley 3558cda884SJean Pihet static struct omap_sdrc_params *sdrc_init_params_cs0, *sdrc_init_params_cs1; 3687246b75SPaul Walmsley 37f2ab9977SPaul Walmsley void __iomem *omap2_sdrc_base; 38f2ab9977SPaul Walmsley void __iomem *omap2_sms_base; 39f2ab9977SPaul Walmsley 4098cfe5abSPaul Walmsley /* SDRC_POWER register bits */ 4198cfe5abSPaul Walmsley #define SDRC_POWER_EXTCLKDIS_SHIFT 3 4298cfe5abSPaul Walmsley #define SDRC_POWER_PWDENA_SHIFT 2 4398cfe5abSPaul Walmsley #define SDRC_POWER_PAGEPOLICY_SHIFT 0 4487246b75SPaul Walmsley 4587246b75SPaul Walmsley /** 4687246b75SPaul Walmsley * omap2_sdrc_get_params - return SDRC register values for a given clock rate 4787246b75SPaul Walmsley * @r: SDRC clock rate (in Hz) 4858cda884SJean Pihet * @sdrc_cs0: chip select 0 ram timings ** 4958cda884SJean Pihet * @sdrc_cs1: chip select 1 ram timings ** 5087246b75SPaul Walmsley * 5187246b75SPaul Walmsley * Return pre-calculated values for the SDRC_ACTIM_CTRLA, 5258cda884SJean Pihet * SDRC_ACTIM_CTRLB, SDRC_RFR_CTRL and SDRC_MR registers in sdrc_cs[01] 5358cda884SJean Pihet * structs,for a given SDRC clock rate 'r'. 5458cda884SJean Pihet * These parameters control various timing delays in the SDRAM controller 5558cda884SJean Pihet * that are expressed in terms of the number of SDRC clock cycles to 5658cda884SJean Pihet * wait; hence the clock rate dependency. 5758cda884SJean Pihet * 5858cda884SJean Pihet * Supports 2 different timing parameters for both chip selects. 5958cda884SJean Pihet * 6058cda884SJean Pihet * Note 1: the sdrc_init_params_cs[01] must be sorted rate descending. 6158cda884SJean Pihet * Note 2: If sdrc_init_params_cs_1 is not NULL it must be of same size 6258cda884SJean Pihet * as sdrc_init_params_cs_0. 6358cda884SJean Pihet * 6458cda884SJean Pihet * Fills in the struct omap_sdrc_params * for each chip select. 6558cda884SJean Pihet * Returns 0 upon success or -1 upon failure. 6687246b75SPaul Walmsley */ 6758cda884SJean Pihet int omap2_sdrc_get_params(unsigned long r, 6858cda884SJean Pihet struct omap_sdrc_params **sdrc_cs0, 6958cda884SJean Pihet struct omap_sdrc_params **sdrc_cs1) 7087246b75SPaul Walmsley { 7158cda884SJean Pihet struct omap_sdrc_params *sp0, *sp1; 7287246b75SPaul Walmsley 7358cda884SJean Pihet if (!sdrc_init_params_cs0) 7458cda884SJean Pihet return -1; 758bd22949SKevin Hilman 7658cda884SJean Pihet sp0 = sdrc_init_params_cs0; 7758cda884SJean Pihet sp1 = sdrc_init_params_cs1; 7887246b75SPaul Walmsley 7958cda884SJean Pihet while (sp0->rate && sp0->rate != r) { 8058cda884SJean Pihet sp0++; 8158cda884SJean Pihet if (sdrc_init_params_cs1) 8258cda884SJean Pihet sp1++; 8358cda884SJean Pihet } 8487246b75SPaul Walmsley 8558cda884SJean Pihet if (!sp0->rate) 8658cda884SJean Pihet return -1; 8787246b75SPaul Walmsley 8858cda884SJean Pihet *sdrc_cs0 = sp0; 8958cda884SJean Pihet *sdrc_cs1 = sp1; 9058cda884SJean Pihet return 0; 9187246b75SPaul Walmsley } 9287246b75SPaul Walmsley 9387246b75SPaul Walmsley 94f2ab9977SPaul Walmsley void __init omap2_set_globals_sdrc(struct omap_globals *omap2_globals) 95f2ab9977SPaul Walmsley { 96f2ab9977SPaul Walmsley omap2_sdrc_base = omap2_globals->sdrc; 97f2ab9977SPaul Walmsley omap2_sms_base = omap2_globals->sms; 98f2ab9977SPaul Walmsley } 99f2ab9977SPaul Walmsley 10098cfe5abSPaul Walmsley /** 10198cfe5abSPaul Walmsley * omap2_sdrc_init - initialize SMS, SDRC devices on boot 10258cda884SJean Pihet * @sdrc_cs[01]: pointers to a null-terminated list of struct omap_sdrc_params 10358cda884SJean Pihet * Support for 2 chip selects timings 10498cfe5abSPaul Walmsley * 10598cfe5abSPaul Walmsley * Turn on smart idle modes for SDRAM scheduler and controller. 10698cfe5abSPaul Walmsley * Program a known-good configuration for the SDRC to deal with buggy 10798cfe5abSPaul Walmsley * bootloaders. 10898cfe5abSPaul Walmsley */ 10958cda884SJean Pihet void __init omap2_sdrc_init(struct omap_sdrc_params *sdrc_cs0, 11058cda884SJean Pihet struct omap_sdrc_params *sdrc_cs1) 111f2ab9977SPaul Walmsley { 112f2ab9977SPaul Walmsley u32 l; 113f2ab9977SPaul Walmsley 114f2ab9977SPaul Walmsley l = sms_read_reg(SMS_SYSCONFIG); 115f2ab9977SPaul Walmsley l &= ~(0x3 << 3); 116f2ab9977SPaul Walmsley l |= (0x2 << 3); 117f2ab9977SPaul Walmsley sms_write_reg(l, SMS_SYSCONFIG); 118f2ab9977SPaul Walmsley 119f2ab9977SPaul Walmsley l = sdrc_read_reg(SDRC_SYSCONFIG); 120f2ab9977SPaul Walmsley l &= ~(0x3 << 3); 121f2ab9977SPaul Walmsley l |= (0x2 << 3); 122f2ab9977SPaul Walmsley sdrc_write_reg(l, SDRC_SYSCONFIG); 12387246b75SPaul Walmsley 12458cda884SJean Pihet sdrc_init_params_cs0 = sdrc_cs0; 12558cda884SJean Pihet sdrc_init_params_cs1 = sdrc_cs1; 12698cfe5abSPaul Walmsley 12798cfe5abSPaul Walmsley /* XXX Enable SRFRONIDLEREQ here also? */ 12898cfe5abSPaul Walmsley l = (1 << SDRC_POWER_EXTCLKDIS_SHIFT) | 12998cfe5abSPaul Walmsley (1 << SDRC_POWER_PWDENA_SHIFT) | 13098cfe5abSPaul Walmsley (1 << SDRC_POWER_PAGEPOLICY_SHIFT); 13198cfe5abSPaul Walmsley sdrc_write_reg(l, SDRC_POWER); 132f2ab9977SPaul Walmsley } 133