From 849369d6c66d3054688672f97d31fceb8e8230fb Mon Sep 17 00:00:00 2001 From: root Date: Fri, 25 Dec 2015 04:40:36 +0000 Subject: initial_commit --- arch/arm/mach-omap2/sdrc.c | 183 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 arch/arm/mach-omap2/sdrc.c (limited to 'arch/arm/mach-omap2/sdrc.c') diff --git a/arch/arm/mach-omap2/sdrc.c b/arch/arm/mach-omap2/sdrc.c new file mode 100644 index 00000000..da6f3a63 --- /dev/null +++ b/arch/arm/mach-omap2/sdrc.c @@ -0,0 +1,183 @@ +/* + * SMS/SDRC (SDRAM controller) common code for OMAP2/3 + * + * Copyright (C) 2005, 2008 Texas Instruments Inc. + * Copyright (C) 2005, 2008 Nokia Corporation + * + * Tony Lindgren + * Paul Walmsley + * Richard Woodruff + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#undef DEBUG + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include "sdrc.h" + +static struct omap_sdrc_params *sdrc_init_params_cs0, *sdrc_init_params_cs1; + +void __iomem *omap2_sdrc_base; +void __iomem *omap2_sms_base; + +struct omap2_sms_regs { + u32 sms_sysconfig; +}; + +static struct omap2_sms_regs sms_context; + +/* SDRC_POWER register bits */ +#define SDRC_POWER_EXTCLKDIS_SHIFT 3 +#define SDRC_POWER_PWDENA_SHIFT 2 +#define SDRC_POWER_PAGEPOLICY_SHIFT 0 + +/** + * omap2_sms_save_context - Save SMS registers + * + * Save SMS registers that need to be restored after off mode. + */ +void omap2_sms_save_context(void) +{ + sms_context.sms_sysconfig = sms_read_reg(SMS_SYSCONFIG); +} + +/** + * omap2_sms_restore_context - Restore SMS registers + * + * Restore SMS registers that need to be Restored after off mode. + */ +void omap2_sms_restore_context(void) +{ + sms_write_reg(sms_context.sms_sysconfig, SMS_SYSCONFIG); +} + +/** + * omap2_sdrc_get_params - return SDRC register values for a given clock rate + * @r: SDRC clock rate (in Hz) + * @sdrc_cs0: chip select 0 ram timings ** + * @sdrc_cs1: chip select 1 ram timings ** + * + * Return pre-calculated values for the SDRC_ACTIM_CTRLA, + * SDRC_ACTIM_CTRLB, SDRC_RFR_CTRL and SDRC_MR registers in sdrc_cs[01] + * structs,for a given SDRC clock rate 'r'. + * These parameters control various timing delays in the SDRAM controller + * that are expressed in terms of the number of SDRC clock cycles to + * wait; hence the clock rate dependency. + * + * Supports 2 different timing parameters for both chip selects. + * + * Note 1: the sdrc_init_params_cs[01] must be sorted rate descending. + * Note 2: If sdrc_init_params_cs_1 is not NULL it must be of same size + * as sdrc_init_params_cs_0. + * + * Fills in the struct omap_sdrc_params * for each chip select. + * Returns 0 upon success or -1 upon failure. + */ +int omap2_sdrc_get_params(unsigned long r, + struct omap_sdrc_params **sdrc_cs0, + struct omap_sdrc_params **sdrc_cs1) +{ + struct omap_sdrc_params *sp0, *sp1; + + if (!sdrc_init_params_cs0) + return -1; + + sp0 = sdrc_init_params_cs0; + sp1 = sdrc_init_params_cs1; + + while (sp0->rate && sp0->rate != r) { + sp0++; + if (sdrc_init_params_cs1) + sp1++; + } + + if (!sp0->rate) + return -1; + + *sdrc_cs0 = sp0; + *sdrc_cs1 = sp1; + return 0; +} + + +void __init omap2_set_globals_sdrc(struct omap_globals *omap2_globals) +{ + /* Static mapping, never released */ + if (omap2_globals->sdrc) { + omap2_sdrc_base = ioremap(omap2_globals->sdrc, SZ_64K); + WARN_ON(!omap2_sdrc_base); + } + if (omap2_globals->sms) { + omap2_sms_base = ioremap(omap2_globals->sms, SZ_64K); + WARN_ON(!omap2_sms_base); + } +} + +/** + * omap2_sdrc_init - initialize SMS, SDRC devices on boot + * @sdrc_cs[01]: pointers to a null-terminated list of struct omap_sdrc_params + * Support for 2 chip selects timings + * + * Turn on smart idle modes for SDRAM scheduler and controller. + * Program a known-good configuration for the SDRC to deal with buggy + * bootloaders. + */ +void __init omap2_sdrc_init(struct omap_sdrc_params *sdrc_cs0, + struct omap_sdrc_params *sdrc_cs1) +{ + u32 l; + + l = sms_read_reg(SMS_SYSCONFIG); + l &= ~(0x3 << 3); + l |= (0x2 << 3); + sms_write_reg(l, SMS_SYSCONFIG); + + l = sdrc_read_reg(SDRC_SYSCONFIG); + l &= ~(0x3 << 3); + l |= (0x2 << 3); + sdrc_write_reg(l, SDRC_SYSCONFIG); + + sdrc_init_params_cs0 = sdrc_cs0; + sdrc_init_params_cs1 = sdrc_cs1; + + /* XXX Enable SRFRONIDLEREQ here also? */ + /* + * PWDENA should not be set due to 34xx erratum 1.150 - PWDENA + * can cause random memory corruption + */ + l = (1 << SDRC_POWER_EXTCLKDIS_SHIFT) | + (1 << SDRC_POWER_PAGEPOLICY_SHIFT); + sdrc_write_reg(l, SDRC_POWER); + omap2_sms_save_context(); +} + +void omap2_sms_write_rot_control(u32 val, unsigned ctx) +{ + sms_write_reg(val, SMS_ROT_CONTROL(ctx)); +} + +void omap2_sms_write_rot_size(u32 val, unsigned ctx) +{ + sms_write_reg(val, SMS_ROT_SIZE(ctx)); +} + +void omap2_sms_write_rot_physical_ba(u32 val, unsigned ctx) +{ + sms_write_reg(val, SMS_ROT_PHYSICAL_BA(ctx)); +} + -- cgit v1.2.3