linux/drivers/memory/emif.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * EMIF driver
 *
 * Copyright (C) 2012 Texas Instruments, Inc.
 *
 * Aneesh V <[email protected]>
 * Santosh Shilimkar <[email protected]>
 */
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/reboot.h>
#include <linux/platform_data/emif_plat.h>
#include <linux/io.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/module.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/pm.h>

#include "emif.h"
#include "jedec_ddr.h"
#include "of_memory.h"

/**
 * struct emif_data - Per device static data for driver's use
 * @duplicate:			Whether the DDR devices attached to this EMIF
 *				instance are exactly same as that on EMIF1. In
 *				this case we can save some memory and processing
 * @temperature_level:		Maximum temperature of LPDDR2 devices attached
 *				to this EMIF - read from MR4 register. If there
 *				are two devices attached to this EMIF, this
 *				value is the maximum of the two temperature
 *				levels.
 * @node:			node in the device list
 * @base:			base address of memory-mapped IO registers.
 * @dev:			device pointer.
 * @regs_cache:			An array of 'struct emif_regs' that stores
 *				calculated register values for different
 *				frequencies, to avoid re-calculating them on
 *				each DVFS transition.
 * @curr_regs:			The set of register values used in the last
 *				frequency change (i.e. corresponding to the
 *				frequency in effect at the moment)
 * @plat_data:			Pointer to saved platform data.
 * @debugfs_root:		dentry to the root folder for EMIF in debugfs
 * @np_ddr:			Pointer to ddr device tree node
 */
struct emif_data {};

static struct emif_data *emif1;
static DEFINE_SPINLOCK(emif_lock);
static unsigned long	irq_state;
static LIST_HEAD(device_list);

static void do_emif_regdump_show(struct seq_file *s, struct emif_data *emif,
	struct emif_regs *regs)
{}

static int emif_regdump_show(struct seq_file *s, void *unused)
{}

DEFINE_SHOW_ATTRIBUTE();

static int emif_mr4_show(struct seq_file *s, void *unused)
{}

DEFINE_SHOW_ATTRIBUTE();

static void emif_debugfs_init(struct emif_data *emif)
{}

static void emif_debugfs_exit(struct emif_data *emif)
{}

/*
 * Get bus width used by EMIF. Note that this may be different from the
 * bus width of the DDR devices used. For instance two 16-bit DDR devices
 * may be connected to a given CS of EMIF. In this case bus width as far
 * as EMIF is concerned is 32, where as the DDR bus width is 16 bits.
 */
static u32 get_emif_bus_width(struct emif_data *emif)
{}

static void set_lpmode(struct emif_data *emif, u8 lpmode)
{}

static void do_freq_update(void)
{}

/* Find addressing table entry based on the device's type and density */
static const struct lpddr2_addressing *get_addressing_table(
	const struct ddr_device_info *device_info)
{}

static u32 get_zq_config_reg(const struct lpddr2_addressing *addressing,
		bool cs1_used, bool cal_resistors_per_cs)
{}

static u32 get_temp_alert_config(const struct lpddr2_addressing *addressing,
		const struct emif_custom_configs *custom_configs, bool cs1_used,
		u32 sdram_io_width, u32 emif_bus_width)
{}

static u32 get_pwr_mgmt_ctrl(u32 freq, struct emif_data *emif, u32 ip_rev)
{}

/*
 * Get the temperature level of the EMIF instance:
 * Reads the MR4 register of attached SDRAM parts to find out the temperature
 * level. If there are two parts attached(one on each CS), then the temperature
 * level for the EMIF instance is the higher of the two temperatures.
 */
static void get_temperature_level(struct emif_data *emif)
{}

/*
 * setup_temperature_sensitive_regs() - set the timings for temperature
 * sensitive registers. This happens once at initialisation time based
 * on the temperature at boot time and subsequently based on the temperature
 * alert interrupt. Temperature alert can happen when the temperature
 * increases or drops. So this function can have the effect of either
 * derating the timings or going back to nominal values.
 */
static void setup_temperature_sensitive_regs(struct emif_data *emif,
		struct emif_regs *regs)
{}

static irqreturn_t handle_temp_alert(void __iomem *base, struct emif_data *emif)
{}

static irqreturn_t emif_interrupt_handler(int irq, void *dev_id)
{}

static irqreturn_t emif_threaded_isr(int irq, void *dev_id)
{}

static void clear_all_interrupts(struct emif_data *emif)
{}

static void disable_and_clear_all_interrupts(struct emif_data *emif)
{}

static int setup_interrupts(struct emif_data *emif, u32 irq)
{}

static void emif_onetime_settings(struct emif_data *emif)
{}

static void get_default_timings(struct emif_data *emif)
{}

static int is_dev_data_valid(u32 type, u32 density, u32 io_width, u32 phy_type,
		u32 ip_rev, struct device *dev)
{}

static int is_custom_config_valid(struct emif_custom_configs *cust_cfgs,
		struct device *dev)
{}

static void of_get_custom_configs(struct device_node *np_emif,
		struct emif_data *emif)
{}

static void of_get_ddr_info(struct device_node *np_emif,
		struct device_node *np_ddr,
		struct ddr_device_info *dev_info)
{}

static struct emif_data *of_get_memory_device_details(
		struct device_node *np_emif, struct device *dev)
{}

static struct emif_data *get_device_details(
		struct platform_device *pdev)
{}

static int emif_probe(struct platform_device *pdev)
{}

static void emif_remove(struct platform_device *pdev)
{}

static void emif_shutdown(struct platform_device *pdev)
{}

#if defined(CONFIG_OF)
static const struct of_device_id emif_of_match[] =;
MODULE_DEVICE_TABLE(of, emif_of_match);
#endif

static struct platform_driver emif_driver =;

module_platform_driver();

MODULE_DESCRIPTION();
MODULE_LICENSE();
MODULE_ALIAS();
MODULE_AUTHOR();