cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sdrc.c (3918B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * SMS/SDRC (SDRAM controller) common code for OMAP2/3
      4 *
      5 * Copyright (C) 2005, 2008 Texas Instruments Inc.
      6 * Copyright (C) 2005, 2008 Nokia Corporation
      7 *
      8 * Tony Lindgren <tony@atomide.com>
      9 * Paul Walmsley
     10 * Richard Woodruff <r-woodruff2@ti.com>
     11 */
     12#undef DEBUG
     13
     14#include <linux/module.h>
     15#include <linux/kernel.h>
     16#include <linux/device.h>
     17#include <linux/list.h>
     18#include <linux/errno.h>
     19#include <linux/delay.h>
     20#include <linux/clk.h>
     21#include <linux/io.h>
     22
     23#include "common.h"
     24#include "clock.h"
     25#include "sdrc.h"
     26
     27static struct omap_sdrc_params *sdrc_init_params_cs0, *sdrc_init_params_cs1;
     28
     29void __iomem *omap2_sdrc_base;
     30void __iomem *omap2_sms_base;
     31
     32struct omap2_sms_regs {
     33	u32	sms_sysconfig;
     34};
     35
     36static struct omap2_sms_regs sms_context;
     37
     38/* SDRC_POWER register bits */
     39#define SDRC_POWER_EXTCLKDIS_SHIFT		3
     40#define SDRC_POWER_PWDENA_SHIFT			2
     41#define SDRC_POWER_PAGEPOLICY_SHIFT		0
     42
     43/**
     44 * omap2_sms_save_context - Save SMS registers
     45 *
     46 * Save SMS registers that need to be restored after off mode.
     47 */
     48void omap2_sms_save_context(void)
     49{
     50	sms_context.sms_sysconfig = sms_read_reg(SMS_SYSCONFIG);
     51}
     52
     53/**
     54 * omap2_sms_restore_context - Restore SMS registers
     55 *
     56 * Restore SMS registers that need to be Restored after off mode.
     57 */
     58void omap2_sms_restore_context(void)
     59{
     60	sms_write_reg(sms_context.sms_sysconfig, SMS_SYSCONFIG);
     61}
     62
     63/**
     64 * omap2_sdrc_get_params - return SDRC register values for a given clock rate
     65 * @r: SDRC clock rate (in Hz)
     66 * @sdrc_cs0: chip select 0 ram timings **
     67 * @sdrc_cs1: chip select 1 ram timings **
     68 *
     69 * Return pre-calculated values for the SDRC_ACTIM_CTRLA,
     70 *  SDRC_ACTIM_CTRLB, SDRC_RFR_CTRL and SDRC_MR registers in sdrc_cs[01]
     71 *  structs,for a given SDRC clock rate 'r'.
     72 * These parameters control various timing delays in the SDRAM controller
     73 *  that are expressed in terms of the number of SDRC clock cycles to
     74 *  wait; hence the clock rate dependency.
     75 *
     76 * Supports 2 different timing parameters for both chip selects.
     77 *
     78 * Note 1: the sdrc_init_params_cs[01] must be sorted rate descending.
     79 * Note 2: If sdrc_init_params_cs_1 is not NULL it must be of same size
     80 *  as sdrc_init_params_cs_0.
     81 *
     82 * Fills in the struct omap_sdrc_params * for each chip select.
     83 * Returns 0 upon success or -1 upon failure.
     84 */
     85int omap2_sdrc_get_params(unsigned long r,
     86			  struct omap_sdrc_params **sdrc_cs0,
     87			  struct omap_sdrc_params **sdrc_cs1)
     88{
     89	struct omap_sdrc_params *sp0, *sp1;
     90
     91	if (!sdrc_init_params_cs0)
     92		return -1;
     93
     94	sp0 = sdrc_init_params_cs0;
     95	sp1 = sdrc_init_params_cs1;
     96
     97	while (sp0->rate && sp0->rate != r) {
     98		sp0++;
     99		if (sdrc_init_params_cs1)
    100			sp1++;
    101	}
    102
    103	if (!sp0->rate)
    104		return -1;
    105
    106	*sdrc_cs0 = sp0;
    107	*sdrc_cs1 = sp1;
    108	return 0;
    109}
    110
    111
    112void __init omap2_set_globals_sdrc(void __iomem *sdrc, void __iomem *sms)
    113{
    114	omap2_sdrc_base = sdrc;
    115	omap2_sms_base = sms;
    116}
    117
    118/**
    119 * omap2_sdrc_init - initialize SMS, SDRC devices on boot
    120 * @sdrc_cs[01]: pointers to a null-terminated list of struct omap_sdrc_params
    121 *  Support for 2 chip selects timings
    122 *
    123 * Turn on smart idle modes for SDRAM scheduler and controller.
    124 * Program a known-good configuration for the SDRC to deal with buggy
    125 * bootloaders.
    126 */
    127void __init omap2_sdrc_init(struct omap_sdrc_params *sdrc_cs0,
    128			    struct omap_sdrc_params *sdrc_cs1)
    129{
    130	u32 l;
    131
    132	l = sms_read_reg(SMS_SYSCONFIG);
    133	l &= ~(0x3 << 3);
    134	l |= (0x2 << 3);
    135	sms_write_reg(l, SMS_SYSCONFIG);
    136
    137	l = sdrc_read_reg(SDRC_SYSCONFIG);
    138	l &= ~(0x3 << 3);
    139	l |= (0x2 << 3);
    140	sdrc_write_reg(l, SDRC_SYSCONFIG);
    141
    142	sdrc_init_params_cs0 = sdrc_cs0;
    143	sdrc_init_params_cs1 = sdrc_cs1;
    144
    145	/* XXX Enable SRFRONIDLEREQ here also? */
    146	/*
    147	 * PWDENA should not be set due to 34xx erratum 1.150 - PWDENA
    148	 * can cause random memory corruption
    149	 */
    150	l = (1 << SDRC_POWER_EXTCLKDIS_SHIFT) |
    151		(1 << SDRC_POWER_PAGEPOLICY_SHIFT);
    152	sdrc_write_reg(l, SDRC_POWER);
    153	omap2_sms_save_context();
    154}