1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2f2ab9977SPaul Walmsley /* 3f2ab9977SPaul Walmsley * SMS/SDRC (SDRAM controller) common code for OMAP2/3 4f2ab9977SPaul Walmsley * 5f2ab9977SPaul Walmsley * Copyright (C) 2005, 2008 Texas Instruments Inc. 6f2ab9977SPaul Walmsley * Copyright (C) 2005, 2008 Nokia Corporation 7f2ab9977SPaul Walmsley * 8f2ab9977SPaul Walmsley * Tony Lindgren <tony@atomide.com> 9f2ab9977SPaul Walmsley * Paul Walmsley 10f2ab9977SPaul Walmsley * Richard Woodruff <r-woodruff2@ti.com> 11f2ab9977SPaul Walmsley */ 1287246b75SPaul Walmsley #undef DEBUG 13f2ab9977SPaul Walmsley 14f2ab9977SPaul Walmsley #include <linux/module.h> 15f2ab9977SPaul Walmsley #include <linux/kernel.h> 16f2ab9977SPaul Walmsley #include <linux/device.h> 17f2ab9977SPaul Walmsley #include <linux/list.h> 18f2ab9977SPaul Walmsley #include <linux/errno.h> 19f2ab9977SPaul Walmsley #include <linux/delay.h> 20f2ab9977SPaul Walmsley #include <linux/clk.h> 21f2ab9977SPaul Walmsley #include <linux/io.h> 22f2ab9977SPaul Walmsley 23a135eaaeSPaul Walmsley #include "common.h" 24a135eaaeSPaul Walmsley #include "clock.h" 25f2ab9977SPaul Walmsley #include "sdrc.h" 26f2ab9977SPaul Walmsley 2758cda884SJean Pihet static struct omap_sdrc_params *sdrc_init_params_cs0, *sdrc_init_params_cs1; 2887246b75SPaul Walmsley 29f2ab9977SPaul Walmsley void __iomem *omap2_sdrc_base; 30f2ab9977SPaul Walmsley void __iomem *omap2_sms_base; 31f2ab9977SPaul Walmsley 328a917d2fSKalle Jokiniemi struct omap2_sms_regs { 338a917d2fSKalle Jokiniemi u32 sms_sysconfig; 348a917d2fSKalle Jokiniemi }; 358a917d2fSKalle Jokiniemi 368a917d2fSKalle Jokiniemi static struct omap2_sms_regs sms_context; 378a917d2fSKalle Jokiniemi 3898cfe5abSPaul Walmsley /* SDRC_POWER register bits */ 3998cfe5abSPaul Walmsley #define SDRC_POWER_EXTCLKDIS_SHIFT 3 4098cfe5abSPaul Walmsley #define SDRC_POWER_PWDENA_SHIFT 2 4198cfe5abSPaul Walmsley #define SDRC_POWER_PAGEPOLICY_SHIFT 0 4287246b75SPaul Walmsley 4387246b75SPaul Walmsley /** 448a917d2fSKalle Jokiniemi * omap2_sms_save_context - Save SMS registers 458a917d2fSKalle Jokiniemi * 468a917d2fSKalle Jokiniemi * Save SMS registers that need to be restored after off mode. 478a917d2fSKalle Jokiniemi */ 488a917d2fSKalle Jokiniemi void omap2_sms_save_context(void) 498a917d2fSKalle Jokiniemi { 508a917d2fSKalle Jokiniemi sms_context.sms_sysconfig = sms_read_reg(SMS_SYSCONFIG); 518a917d2fSKalle Jokiniemi } 528a917d2fSKalle Jokiniemi 538a917d2fSKalle Jokiniemi /** 548a917d2fSKalle Jokiniemi * omap2_sms_restore_context - Restore SMS registers 558a917d2fSKalle Jokiniemi * 568a917d2fSKalle Jokiniemi * Restore SMS registers that need to be Restored after off mode. 578a917d2fSKalle Jokiniemi */ 588a917d2fSKalle Jokiniemi void omap2_sms_restore_context(void) 598a917d2fSKalle Jokiniemi { 608a917d2fSKalle Jokiniemi sms_write_reg(sms_context.sms_sysconfig, SMS_SYSCONFIG); 618a917d2fSKalle Jokiniemi } 628a917d2fSKalle Jokiniemi 638a917d2fSKalle Jokiniemi /** 6487246b75SPaul Walmsley * omap2_sdrc_get_params - return SDRC register values for a given clock rate 6587246b75SPaul Walmsley * @r: SDRC clock rate (in Hz) 6658cda884SJean Pihet * @sdrc_cs0: chip select 0 ram timings ** 6758cda884SJean Pihet * @sdrc_cs1: chip select 1 ram timings ** 6887246b75SPaul Walmsley * 6987246b75SPaul Walmsley * Return pre-calculated values for the SDRC_ACTIM_CTRLA, 7058cda884SJean Pihet * SDRC_ACTIM_CTRLB, SDRC_RFR_CTRL and SDRC_MR registers in sdrc_cs[01] 7158cda884SJean Pihet * structs,for a given SDRC clock rate 'r'. 7258cda884SJean Pihet * These parameters control various timing delays in the SDRAM controller 7358cda884SJean Pihet * that are expressed in terms of the number of SDRC clock cycles to 7458cda884SJean Pihet * wait; hence the clock rate dependency. 7558cda884SJean Pihet * 7658cda884SJean Pihet * Supports 2 different timing parameters for both chip selects. 7758cda884SJean Pihet * 7858cda884SJean Pihet * Note 1: the sdrc_init_params_cs[01] must be sorted rate descending. 7958cda884SJean Pihet * Note 2: If sdrc_init_params_cs_1 is not NULL it must be of same size 8058cda884SJean Pihet * as sdrc_init_params_cs_0. 8158cda884SJean Pihet * 8258cda884SJean Pihet * Fills in the struct omap_sdrc_params * for each chip select. 8358cda884SJean Pihet * Returns 0 upon success or -1 upon failure. 8487246b75SPaul Walmsley */ 8558cda884SJean Pihet int omap2_sdrc_get_params(unsigned long r, 8658cda884SJean Pihet struct omap_sdrc_params **sdrc_cs0, 8758cda884SJean Pihet struct omap_sdrc_params **sdrc_cs1) 8887246b75SPaul Walmsley { 8958cda884SJean Pihet struct omap_sdrc_params *sp0, *sp1; 9087246b75SPaul Walmsley 9158cda884SJean Pihet if (!sdrc_init_params_cs0) 9258cda884SJean Pihet return -1; 938bd22949SKevin Hilman 9458cda884SJean Pihet sp0 = sdrc_init_params_cs0; 9558cda884SJean Pihet sp1 = sdrc_init_params_cs1; 9687246b75SPaul Walmsley 9758cda884SJean Pihet while (sp0->rate && sp0->rate != r) { 9858cda884SJean Pihet sp0++; 9958cda884SJean Pihet if (sdrc_init_params_cs1) 10058cda884SJean Pihet sp1++; 10158cda884SJean Pihet } 10287246b75SPaul Walmsley 10358cda884SJean Pihet if (!sp0->rate) 10458cda884SJean Pihet return -1; 10587246b75SPaul Walmsley 10658cda884SJean Pihet *sdrc_cs0 = sp0; 10758cda884SJean Pihet *sdrc_cs1 = sp1; 10858cda884SJean Pihet return 0; 10987246b75SPaul Walmsley } 11087246b75SPaul Walmsley 11187246b75SPaul Walmsley 112b6a4226cSPaul Walmsley void __init omap2_set_globals_sdrc(void __iomem *sdrc, void __iomem *sms) 113f2ab9977SPaul Walmsley { 114b6a4226cSPaul Walmsley omap2_sdrc_base = sdrc; 115b6a4226cSPaul Walmsley omap2_sms_base = sms; 116f2ab9977SPaul Walmsley } 117f2ab9977SPaul Walmsley 11898cfe5abSPaul Walmsley /** 11998cfe5abSPaul Walmsley * omap2_sdrc_init - initialize SMS, SDRC devices on boot 12058cda884SJean Pihet * @sdrc_cs[01]: pointers to a null-terminated list of struct omap_sdrc_params 12158cda884SJean Pihet * Support for 2 chip selects timings 12298cfe5abSPaul Walmsley * 12398cfe5abSPaul Walmsley * Turn on smart idle modes for SDRAM scheduler and controller. 12498cfe5abSPaul Walmsley * Program a known-good configuration for the SDRC to deal with buggy 12598cfe5abSPaul Walmsley * bootloaders. 12698cfe5abSPaul Walmsley */ 12758cda884SJean Pihet void __init omap2_sdrc_init(struct omap_sdrc_params *sdrc_cs0, 12858cda884SJean Pihet struct omap_sdrc_params *sdrc_cs1) 129f2ab9977SPaul Walmsley { 130f2ab9977SPaul Walmsley u32 l; 131f2ab9977SPaul Walmsley 132f2ab9977SPaul Walmsley l = sms_read_reg(SMS_SYSCONFIG); 133f2ab9977SPaul Walmsley l &= ~(0x3 << 3); 134f2ab9977SPaul Walmsley l |= (0x2 << 3); 135f2ab9977SPaul Walmsley sms_write_reg(l, SMS_SYSCONFIG); 136f2ab9977SPaul Walmsley 137f2ab9977SPaul Walmsley l = sdrc_read_reg(SDRC_SYSCONFIG); 138f2ab9977SPaul Walmsley l &= ~(0x3 << 3); 139f2ab9977SPaul Walmsley l |= (0x2 << 3); 140f2ab9977SPaul Walmsley sdrc_write_reg(l, SDRC_SYSCONFIG); 14187246b75SPaul Walmsley 14258cda884SJean Pihet sdrc_init_params_cs0 = sdrc_cs0; 14358cda884SJean Pihet sdrc_init_params_cs1 = sdrc_cs1; 14498cfe5abSPaul Walmsley 14598cfe5abSPaul Walmsley /* XXX Enable SRFRONIDLEREQ here also? */ 14675f251e3SPaul Walmsley /* 14775f251e3SPaul Walmsley * PWDENA should not be set due to 34xx erratum 1.150 - PWDENA 14875f251e3SPaul Walmsley * can cause random memory corruption 14975f251e3SPaul Walmsley */ 15098cfe5abSPaul Walmsley l = (1 << SDRC_POWER_EXTCLKDIS_SHIFT) | 15198cfe5abSPaul Walmsley (1 << SDRC_POWER_PAGEPOLICY_SHIFT); 15298cfe5abSPaul Walmsley sdrc_write_reg(l, SDRC_POWER); 1538a917d2fSKalle Jokiniemi omap2_sms_save_context(); 154f2ab9977SPaul Walmsley } 155