Initial commit; kernel source import

This commit is contained in:
Nathan
2025-04-06 23:50:55 -05:00
commit 25c6d769f4
45093 changed files with 18199410 additions and 0 deletions

76
drivers/memory/Kconfig Normal file
View File

@@ -0,0 +1,76 @@
#
# Memory devices
#
menuconfig MEMORY
bool "Memory Controller drivers"
if MEMORY
config TI_EMIF
tristate "Texas Instruments EMIF driver"
depends on ARCH_OMAP2PLUS
select DDR
help
This driver is for the EMIF module available in Texas Instruments
SoCs. EMIF is an SDRAM controller that, based on its revision,
supports one or more of DDR2, DDR3, and LPDDR2 SDRAM protocols.
This driver takes care of only LPDDR2 memories presently. The
functions of the driver includes re-configuring AC timing
parameters and other settings during frequency, voltage and
temperature changes
config TEGRA20_MC
bool "Tegra20 Memory Controller(MC) driver"
default y
depends on ARCH_TEGRA_2x_SOC
help
This driver is for the Memory Controller(MC) module available
in Tegra20 SoCs, mainly for a address translation fault
analysis, especially for IOMMU/GART(Graphics Address
Relocation Table) module.
config TEGRA30_MC
bool "Tegra30 Memory Controller(MC) driver"
default y
depends on ARCH_TEGRA_3x_SOC
help
This driver is for the Memory Controller(MC) module available
in Tegra30 SoCs, mainly for a address translation fault
analysis, especially for IOMMU/SMMU(System Memory Management
Unit) module.
config TEGRA114_MC
bool "Tegra114 Memory Controller(MC) driver"
default y
depends on ARCH_TEGRA_114_SOC
help
This driver is for the Memory Controller(MC) module available
in Tegra114 SoCs.
config TEGRA114_EMC
bool "Tegra114 External Memory Controller(EMC) driver"
default y
depends on TEGRA114_MC
help
This driver is for the External Memory Controller(EMC) module
available in Tegra114 SoCs.
config TEGRA124_MC
bool "Tegra124 Memory Controller(MC) driver"
default y
depends on ARCH_TEGRA_124_SOC
help
This driver is for the Memory Controller(MC) module available
in Tegra124 SoCs.
config TEGRA124_EMC
bool "Tegra124 External Memory Controller(EMC) driver"
default y
depends on TEGRA124_MC && MFD_SYSCON
help
This driver is for the External Memory Controller(EMC) module
available in Tegra124 SoCs.
endif

14
drivers/memory/Makefile Normal file
View File

@@ -0,0 +1,14 @@
#
# Makefile for memory devices
#
ifeq ($(CONFIG_DDR),y)
obj-$(CONFIG_OF) += of_memory.o
endif
obj-$(CONFIG_TI_EMIF) += emif.o
obj-$(CONFIG_TEGRA20_MC) += tegra20-mc.o
obj-$(CONFIG_TEGRA30_MC) += tegra30-mc.o
obj-$(CONFIG_TEGRA114_MC) += tegra114-mc.o
obj-$(CONFIG_TEGRA114_EMC) += tegra114-emc.o
obj-$(CONFIG_TEGRA124_MC) += tegra124-mc.o
obj-$(CONFIG_TEGRA124_EMC) += tegra124-emc.o

1940
drivers/memory/emif.c Normal file

File diff suppressed because it is too large Load Diff

589
drivers/memory/emif.h Normal file
View File

@@ -0,0 +1,589 @@
/*
* Defines for the EMIF driver
*
* Copyright (C) 2012 Texas Instruments, Inc.
*
* Benoit Cousson (b-cousson@ti.com)
*
* 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.
*/
#ifndef __EMIF_H
#define __EMIF_H
/*
* Maximum number of different frequencies supported by EMIF driver
* Determines the number of entries in the pointer array for register
* cache
*/
#define EMIF_MAX_NUM_FREQUENCIES 6
/* State of the core voltage */
#define DDR_VOLTAGE_STABLE 0
#define DDR_VOLTAGE_RAMPING 1
/* Defines for timing De-rating */
#define EMIF_NORMAL_TIMINGS 0
#define EMIF_DERATED_TIMINGS 1
/* Length of the forced read idle period in terms of cycles */
#define EMIF_READ_IDLE_LEN_VAL 5
/*
* forced read idle interval to be used when voltage
* is changed as part of DVFS/DPS - 1ms
*/
#define READ_IDLE_INTERVAL_DVFS (1*1000000)
/*
* Forced read idle interval to be used when voltage is stable
* 50us - or maximum value will do
*/
#define READ_IDLE_INTERVAL_NORMAL (50*1000000)
/* DLL calibration interval when voltage is NOT stable - 1us */
#define DLL_CALIB_INTERVAL_DVFS (1*1000000)
#define DLL_CALIB_ACK_WAIT_VAL 5
/* Interval between ZQCS commands - hw team recommended value */
#define EMIF_ZQCS_INTERVAL_US (50*1000)
/* Enable ZQ Calibration on exiting Self-refresh */
#define ZQ_SFEXITEN_ENABLE 1
/*
* ZQ Calibration simultaneously on both chip-selects:
* Needs one calibration resistor per CS
*/
#define ZQ_DUALCALEN_DISABLE 0
#define ZQ_DUALCALEN_ENABLE 1
#define T_ZQCS_DEFAULT_NS 90
#define T_ZQCL_DEFAULT_NS 360
#define T_ZQINIT_DEFAULT_NS 1000
/* DPD_EN */
#define DPD_DISABLE 0
#define DPD_ENABLE 1
/*
* Default values for the low-power entry to be used if not provided by user.
* OMAP4/5 has a hw bug(i735) due to which this value can not be less than 512
* Timeout values are in DDR clock 'cycles' and frequency threshold in Hz
*/
#define EMIF_LP_MODE_TIMEOUT_PERFORMANCE 2048
#define EMIF_LP_MODE_TIMEOUT_POWER 512
#define EMIF_LP_MODE_FREQ_THRESHOLD 400000000
/* DDR_PHY_CTRL_1 values for EMIF4D - ATTILA PHY combination */
#define EMIF_DDR_PHY_CTRL_1_BASE_VAL_ATTILAPHY 0x049FF000
#define EMIF_DLL_SLAVE_DLY_CTRL_400_MHZ_ATTILAPHY 0x41
#define EMIF_DLL_SLAVE_DLY_CTRL_200_MHZ_ATTILAPHY 0x80
#define EMIF_DLL_SLAVE_DLY_CTRL_100_MHZ_AND_LESS_ATTILAPHY 0xFF
/* DDR_PHY_CTRL_1 values for EMIF4D5 INTELLIPHY combination */
#define EMIF_DDR_PHY_CTRL_1_BASE_VAL_INTELLIPHY 0x0E084200
#define EMIF_PHY_TOTAL_READ_LATENCY_INTELLIPHY_PS 10000
/* TEMP_ALERT_CONFIG - corresponding to temp gradient 5 C/s */
#define TEMP_ALERT_POLL_INTERVAL_DEFAULT_MS 360
#define EMIF_T_CSTA 3
#define EMIF_T_PDLL_UL 128
/* External PHY control registers magic values */
#define EMIF_EXT_PHY_CTRL_1_VAL 0x04020080
#define EMIF_EXT_PHY_CTRL_5_VAL 0x04010040
#define EMIF_EXT_PHY_CTRL_6_VAL 0x01004010
#define EMIF_EXT_PHY_CTRL_7_VAL 0x00001004
#define EMIF_EXT_PHY_CTRL_8_VAL 0x04010040
#define EMIF_EXT_PHY_CTRL_9_VAL 0x01004010
#define EMIF_EXT_PHY_CTRL_10_VAL 0x00001004
#define EMIF_EXT_PHY_CTRL_11_VAL 0x00000000
#define EMIF_EXT_PHY_CTRL_12_VAL 0x00000000
#define EMIF_EXT_PHY_CTRL_13_VAL 0x00000000
#define EMIF_EXT_PHY_CTRL_14_VAL 0x80080080
#define EMIF_EXT_PHY_CTRL_15_VAL 0x00800800
#define EMIF_EXT_PHY_CTRL_16_VAL 0x08102040
#define EMIF_EXT_PHY_CTRL_17_VAL 0x00000001
#define EMIF_EXT_PHY_CTRL_18_VAL 0x540A8150
#define EMIF_EXT_PHY_CTRL_19_VAL 0xA81502A0
#define EMIF_EXT_PHY_CTRL_20_VAL 0x002A0540
#define EMIF_EXT_PHY_CTRL_21_VAL 0x00000000
#define EMIF_EXT_PHY_CTRL_22_VAL 0x00000000
#define EMIF_EXT_PHY_CTRL_23_VAL 0x00000000
#define EMIF_EXT_PHY_CTRL_24_VAL 0x00000077
#define EMIF_INTELLI_PHY_DQS_GATE_OPENING_DELAY_PS 1200
/* Registers offset */
#define EMIF_MODULE_ID_AND_REVISION 0x0000
#define EMIF_STATUS 0x0004
#define EMIF_SDRAM_CONFIG 0x0008
#define EMIF_SDRAM_CONFIG_2 0x000c
#define EMIF_SDRAM_REFRESH_CONTROL 0x0010
#define EMIF_SDRAM_REFRESH_CTRL_SHDW 0x0014
#define EMIF_SDRAM_TIMING_1 0x0018
#define EMIF_SDRAM_TIMING_1_SHDW 0x001c
#define EMIF_SDRAM_TIMING_2 0x0020
#define EMIF_SDRAM_TIMING_2_SHDW 0x0024
#define EMIF_SDRAM_TIMING_3 0x0028
#define EMIF_SDRAM_TIMING_3_SHDW 0x002c
#define EMIF_LPDDR2_NVM_TIMING 0x0030
#define EMIF_LPDDR2_NVM_TIMING_SHDW 0x0034
#define EMIF_POWER_MANAGEMENT_CONTROL 0x0038
#define EMIF_POWER_MANAGEMENT_CTRL_SHDW 0x003c
#define EMIF_LPDDR2_MODE_REG_DATA 0x0040
#define EMIF_LPDDR2_MODE_REG_CONFIG 0x0050
#define EMIF_OCP_CONFIG 0x0054
#define EMIF_OCP_CONFIG_VALUE_1 0x0058
#define EMIF_OCP_CONFIG_VALUE_2 0x005c
#define EMIF_IODFT_TEST_LOGIC_GLOBAL_CONTROL 0x0060
#define EMIF_IODFT_TEST_LOGIC_CTRL_MISR_RESULT 0x0064
#define EMIF_IODFT_TEST_LOGIC_ADDRESS_MISR_RESULT 0x0068
#define EMIF_IODFT_TEST_LOGIC_DATA_MISR_RESULT_1 0x006c
#define EMIF_IODFT_TEST_LOGIC_DATA_MISR_RESULT_2 0x0070
#define EMIF_IODFT_TEST_LOGIC_DATA_MISR_RESULT_3 0x0074
#define EMIF_PERFORMANCE_COUNTER_1 0x0080
#define EMIF_PERFORMANCE_COUNTER_2 0x0084
#define EMIF_PERFORMANCE_COUNTER_CONFIG 0x0088
#define EMIF_PERFORMANCE_COUNTER_MASTER_REGION_SELECT 0x008c
#define EMIF_PERFORMANCE_COUNTER_TIME 0x0090
#define EMIF_MISC_REG 0x0094
#define EMIF_DLL_CALIB_CTRL 0x0098
#define EMIF_DLL_CALIB_CTRL_SHDW 0x009c
#define EMIF_END_OF_INTERRUPT 0x00a0
#define EMIF_SYSTEM_OCP_INTERRUPT_RAW_STATUS 0x00a4
#define EMIF_LL_OCP_INTERRUPT_RAW_STATUS 0x00a8
#define EMIF_SYSTEM_OCP_INTERRUPT_STATUS 0x00ac
#define EMIF_LL_OCP_INTERRUPT_STATUS 0x00b0
#define EMIF_SYSTEM_OCP_INTERRUPT_ENABLE_SET 0x00b4
#define EMIF_LL_OCP_INTERRUPT_ENABLE_SET 0x00b8
#define EMIF_SYSTEM_OCP_INTERRUPT_ENABLE_CLEAR 0x00bc
#define EMIF_LL_OCP_INTERRUPT_ENABLE_CLEAR 0x00c0
#define EMIF_SDRAM_OUTPUT_IMPEDANCE_CALIBRATION_CONFIG 0x00c8
#define EMIF_TEMPERATURE_ALERT_CONFIG 0x00cc
#define EMIF_OCP_ERROR_LOG 0x00d0
#define EMIF_READ_WRITE_LEVELING_RAMP_WINDOW 0x00d4
#define EMIF_READ_WRITE_LEVELING_RAMP_CONTROL 0x00d8
#define EMIF_READ_WRITE_LEVELING_CONTROL 0x00dc
#define EMIF_DDR_PHY_CTRL_1 0x00e4
#define EMIF_DDR_PHY_CTRL_1_SHDW 0x00e8
#define EMIF_DDR_PHY_CTRL_2 0x00ec
#define EMIF_PRIORITY_TO_CLASS_OF_SERVICE_MAPPING 0x0100
#define EMIF_CONNECTION_ID_TO_CLASS_OF_SERVICE_1_MAPPING 0x0104
#define EMIF_CONNECTION_ID_TO_CLASS_OF_SERVICE_2_MAPPING 0x0108
#define EMIF_READ_WRITE_EXECUTION_THRESHOLD 0x0120
#define EMIF_COS_CONFIG 0x0124
#define EMIF_PHY_STATUS_1 0x0140
#define EMIF_PHY_STATUS_2 0x0144
#define EMIF_PHY_STATUS_3 0x0148
#define EMIF_PHY_STATUS_4 0x014c
#define EMIF_PHY_STATUS_5 0x0150
#define EMIF_PHY_STATUS_6 0x0154
#define EMIF_PHY_STATUS_7 0x0158
#define EMIF_PHY_STATUS_8 0x015c
#define EMIF_PHY_STATUS_9 0x0160
#define EMIF_PHY_STATUS_10 0x0164
#define EMIF_PHY_STATUS_11 0x0168
#define EMIF_PHY_STATUS_12 0x016c
#define EMIF_PHY_STATUS_13 0x0170
#define EMIF_PHY_STATUS_14 0x0174
#define EMIF_PHY_STATUS_15 0x0178
#define EMIF_PHY_STATUS_16 0x017c
#define EMIF_PHY_STATUS_17 0x0180
#define EMIF_PHY_STATUS_18 0x0184
#define EMIF_PHY_STATUS_19 0x0188
#define EMIF_PHY_STATUS_20 0x018c
#define EMIF_PHY_STATUS_21 0x0190
#define EMIF_EXT_PHY_CTRL_1 0x0200
#define EMIF_EXT_PHY_CTRL_1_SHDW 0x0204
#define EMIF_EXT_PHY_CTRL_2 0x0208
#define EMIF_EXT_PHY_CTRL_2_SHDW 0x020c
#define EMIF_EXT_PHY_CTRL_3 0x0210
#define EMIF_EXT_PHY_CTRL_3_SHDW 0x0214
#define EMIF_EXT_PHY_CTRL_4 0x0218
#define EMIF_EXT_PHY_CTRL_4_SHDW 0x021c
#define EMIF_EXT_PHY_CTRL_5 0x0220
#define EMIF_EXT_PHY_CTRL_5_SHDW 0x0224
#define EMIF_EXT_PHY_CTRL_6 0x0228
#define EMIF_EXT_PHY_CTRL_6_SHDW 0x022c
#define EMIF_EXT_PHY_CTRL_7 0x0230
#define EMIF_EXT_PHY_CTRL_7_SHDW 0x0234
#define EMIF_EXT_PHY_CTRL_8 0x0238
#define EMIF_EXT_PHY_CTRL_8_SHDW 0x023c
#define EMIF_EXT_PHY_CTRL_9 0x0240
#define EMIF_EXT_PHY_CTRL_9_SHDW 0x0244
#define EMIF_EXT_PHY_CTRL_10 0x0248
#define EMIF_EXT_PHY_CTRL_10_SHDW 0x024c
#define EMIF_EXT_PHY_CTRL_11 0x0250
#define EMIF_EXT_PHY_CTRL_11_SHDW 0x0254
#define EMIF_EXT_PHY_CTRL_12 0x0258
#define EMIF_EXT_PHY_CTRL_12_SHDW 0x025c
#define EMIF_EXT_PHY_CTRL_13 0x0260
#define EMIF_EXT_PHY_CTRL_13_SHDW 0x0264
#define EMIF_EXT_PHY_CTRL_14 0x0268
#define EMIF_EXT_PHY_CTRL_14_SHDW 0x026c
#define EMIF_EXT_PHY_CTRL_15 0x0270
#define EMIF_EXT_PHY_CTRL_15_SHDW 0x0274
#define EMIF_EXT_PHY_CTRL_16 0x0278
#define EMIF_EXT_PHY_CTRL_16_SHDW 0x027c
#define EMIF_EXT_PHY_CTRL_17 0x0280
#define EMIF_EXT_PHY_CTRL_17_SHDW 0x0284
#define EMIF_EXT_PHY_CTRL_18 0x0288
#define EMIF_EXT_PHY_CTRL_18_SHDW 0x028c
#define EMIF_EXT_PHY_CTRL_19 0x0290
#define EMIF_EXT_PHY_CTRL_19_SHDW 0x0294
#define EMIF_EXT_PHY_CTRL_20 0x0298
#define EMIF_EXT_PHY_CTRL_20_SHDW 0x029c
#define EMIF_EXT_PHY_CTRL_21 0x02a0
#define EMIF_EXT_PHY_CTRL_21_SHDW 0x02a4
#define EMIF_EXT_PHY_CTRL_22 0x02a8
#define EMIF_EXT_PHY_CTRL_22_SHDW 0x02ac
#define EMIF_EXT_PHY_CTRL_23 0x02b0
#define EMIF_EXT_PHY_CTRL_23_SHDW 0x02b4
#define EMIF_EXT_PHY_CTRL_24 0x02b8
#define EMIF_EXT_PHY_CTRL_24_SHDW 0x02bc
#define EMIF_EXT_PHY_CTRL_25 0x02c0
#define EMIF_EXT_PHY_CTRL_25_SHDW 0x02c4
#define EMIF_EXT_PHY_CTRL_26 0x02c8
#define EMIF_EXT_PHY_CTRL_26_SHDW 0x02cc
#define EMIF_EXT_PHY_CTRL_27 0x02d0
#define EMIF_EXT_PHY_CTRL_27_SHDW 0x02d4
#define EMIF_EXT_PHY_CTRL_28 0x02d8
#define EMIF_EXT_PHY_CTRL_28_SHDW 0x02dc
#define EMIF_EXT_PHY_CTRL_29 0x02e0
#define EMIF_EXT_PHY_CTRL_29_SHDW 0x02e4
#define EMIF_EXT_PHY_CTRL_30 0x02e8
#define EMIF_EXT_PHY_CTRL_30_SHDW 0x02ec
/* Registers shifts and masks */
/* EMIF_MODULE_ID_AND_REVISION */
#define SCHEME_SHIFT 30
#define SCHEME_MASK (0x3 << 30)
#define MODULE_ID_SHIFT 16
#define MODULE_ID_MASK (0xfff << 16)
#define RTL_VERSION_SHIFT 11
#define RTL_VERSION_MASK (0x1f << 11)
#define MAJOR_REVISION_SHIFT 8
#define MAJOR_REVISION_MASK (0x7 << 8)
#define MINOR_REVISION_SHIFT 0
#define MINOR_REVISION_MASK (0x3f << 0)
/* STATUS */
#define BE_SHIFT 31
#define BE_MASK (1 << 31)
#define DUAL_CLK_MODE_SHIFT 30
#define DUAL_CLK_MODE_MASK (1 << 30)
#define FAST_INIT_SHIFT 29
#define FAST_INIT_MASK (1 << 29)
#define RDLVLGATETO_SHIFT 6
#define RDLVLGATETO_MASK (1 << 6)
#define RDLVLTO_SHIFT 5
#define RDLVLTO_MASK (1 << 5)
#define WRLVLTO_SHIFT 4
#define WRLVLTO_MASK (1 << 4)
#define PHY_DLL_READY_SHIFT 2
#define PHY_DLL_READY_MASK (1 << 2)
/* SDRAM_CONFIG */
#define SDRAM_TYPE_SHIFT 29
#define SDRAM_TYPE_MASK (0x7 << 29)
#define IBANK_POS_SHIFT 27
#define IBANK_POS_MASK (0x3 << 27)
#define DDR_TERM_SHIFT 24
#define DDR_TERM_MASK (0x7 << 24)
#define DDR2_DDQS_SHIFT 23
#define DDR2_DDQS_MASK (1 << 23)
#define DYN_ODT_SHIFT 21
#define DYN_ODT_MASK (0x3 << 21)
#define DDR_DISABLE_DLL_SHIFT 20
#define DDR_DISABLE_DLL_MASK (1 << 20)
#define SDRAM_DRIVE_SHIFT 18
#define SDRAM_DRIVE_MASK (0x3 << 18)
#define CWL_SHIFT 16
#define CWL_MASK (0x3 << 16)
#define NARROW_MODE_SHIFT 14
#define NARROW_MODE_MASK (0x3 << 14)
#define CL_SHIFT 10
#define CL_MASK (0xf << 10)
#define ROWSIZE_SHIFT 7
#define ROWSIZE_MASK (0x7 << 7)
#define IBANK_SHIFT 4
#define IBANK_MASK (0x7 << 4)
#define EBANK_SHIFT 3
#define EBANK_MASK (1 << 3)
#define PAGESIZE_SHIFT 0
#define PAGESIZE_MASK (0x7 << 0)
/* SDRAM_CONFIG_2 */
#define CS1NVMEN_SHIFT 30
#define CS1NVMEN_MASK (1 << 30)
#define EBANK_POS_SHIFT 27
#define EBANK_POS_MASK (1 << 27)
#define RDBNUM_SHIFT 4
#define RDBNUM_MASK (0x3 << 4)
#define RDBSIZE_SHIFT 0
#define RDBSIZE_MASK (0x7 << 0)
/* SDRAM_REFRESH_CONTROL */
#define INITREF_DIS_SHIFT 31
#define INITREF_DIS_MASK (1 << 31)
#define SRT_SHIFT 29
#define SRT_MASK (1 << 29)
#define ASR_SHIFT 28
#define ASR_MASK (1 << 28)
#define PASR_SHIFT 24
#define PASR_MASK (0x7 << 24)
#define REFRESH_RATE_SHIFT 0
#define REFRESH_RATE_MASK (0xffff << 0)
/* SDRAM_TIMING_1 */
#define T_RTW_SHIFT 29
#define T_RTW_MASK (0x7 << 29)
#define T_RP_SHIFT 25
#define T_RP_MASK (0xf << 25)
#define T_RCD_SHIFT 21
#define T_RCD_MASK (0xf << 21)
#define T_WR_SHIFT 17
#define T_WR_MASK (0xf << 17)
#define T_RAS_SHIFT 12
#define T_RAS_MASK (0x1f << 12)
#define T_RC_SHIFT 6
#define T_RC_MASK (0x3f << 6)
#define T_RRD_SHIFT 3
#define T_RRD_MASK (0x7 << 3)
#define T_WTR_SHIFT 0
#define T_WTR_MASK (0x7 << 0)
/* SDRAM_TIMING_2 */
#define T_XP_SHIFT 28
#define T_XP_MASK (0x7 << 28)
#define T_ODT_SHIFT 25
#define T_ODT_MASK (0x7 << 25)
#define T_XSNR_SHIFT 16
#define T_XSNR_MASK (0x1ff << 16)
#define T_XSRD_SHIFT 6
#define T_XSRD_MASK (0x3ff << 6)
#define T_RTP_SHIFT 3
#define T_RTP_MASK (0x7 << 3)
#define T_CKE_SHIFT 0
#define T_CKE_MASK (0x7 << 0)
/* SDRAM_TIMING_3 */
#define T_PDLL_UL_SHIFT 28
#define T_PDLL_UL_MASK (0xf << 28)
#define T_CSTA_SHIFT 24
#define T_CSTA_MASK (0xf << 24)
#define T_CKESR_SHIFT 21
#define T_CKESR_MASK (0x7 << 21)
#define ZQ_ZQCS_SHIFT 15
#define ZQ_ZQCS_MASK (0x3f << 15)
#define T_TDQSCKMAX_SHIFT 13
#define T_TDQSCKMAX_MASK (0x3 << 13)
#define T_RFC_SHIFT 4
#define T_RFC_MASK (0x1ff << 4)
#define T_RAS_MAX_SHIFT 0
#define T_RAS_MAX_MASK (0xf << 0)
/* POWER_MANAGEMENT_CONTROL */
#define PD_TIM_SHIFT 12
#define PD_TIM_MASK (0xf << 12)
#define DPD_EN_SHIFT 11
#define DPD_EN_MASK (1 << 11)
#define LP_MODE_SHIFT 8
#define LP_MODE_MASK (0x7 << 8)
#define SR_TIM_SHIFT 4
#define SR_TIM_MASK (0xf << 4)
#define CS_TIM_SHIFT 0
#define CS_TIM_MASK (0xf << 0)
/* LPDDR2_MODE_REG_DATA */
#define VALUE_0_SHIFT 0
#define VALUE_0_MASK (0x7f << 0)
/* LPDDR2_MODE_REG_CONFIG */
#define CS_SHIFT 31
#define CS_MASK (1 << 31)
#define REFRESH_EN_SHIFT 30
#define REFRESH_EN_MASK (1 << 30)
#define ADDRESS_SHIFT 0
#define ADDRESS_MASK (0xff << 0)
/* OCP_CONFIG */
#define SYS_THRESH_MAX_SHIFT 24
#define SYS_THRESH_MAX_MASK (0xf << 24)
#define MPU_THRESH_MAX_SHIFT 20
#define MPU_THRESH_MAX_MASK (0xf << 20)
#define LL_THRESH_MAX_SHIFT 16
#define LL_THRESH_MAX_MASK (0xf << 16)
/* PERFORMANCE_COUNTER_1 */
#define COUNTER1_SHIFT 0
#define COUNTER1_MASK (0xffffffff << 0)
/* PERFORMANCE_COUNTER_2 */
#define COUNTER2_SHIFT 0
#define COUNTER2_MASK (0xffffffff << 0)
/* PERFORMANCE_COUNTER_CONFIG */
#define CNTR2_MCONNID_EN_SHIFT 31
#define CNTR2_MCONNID_EN_MASK (1 << 31)
#define CNTR2_REGION_EN_SHIFT 30
#define CNTR2_REGION_EN_MASK (1 << 30)
#define CNTR2_CFG_SHIFT 16
#define CNTR2_CFG_MASK (0xf << 16)
#define CNTR1_MCONNID_EN_SHIFT 15
#define CNTR1_MCONNID_EN_MASK (1 << 15)
#define CNTR1_REGION_EN_SHIFT 14
#define CNTR1_REGION_EN_MASK (1 << 14)
#define CNTR1_CFG_SHIFT 0
#define CNTR1_CFG_MASK (0xf << 0)
/* PERFORMANCE_COUNTER_MASTER_REGION_SELECT */
#define MCONNID2_SHIFT 24
#define MCONNID2_MASK (0xff << 24)
#define REGION_SEL2_SHIFT 16
#define REGION_SEL2_MASK (0x3 << 16)
#define MCONNID1_SHIFT 8
#define MCONNID1_MASK (0xff << 8)
#define REGION_SEL1_SHIFT 0
#define REGION_SEL1_MASK (0x3 << 0)
/* PERFORMANCE_COUNTER_TIME */
#define TOTAL_TIME_SHIFT 0
#define TOTAL_TIME_MASK (0xffffffff << 0)
/* DLL_CALIB_CTRL */
#define ACK_WAIT_SHIFT 16
#define ACK_WAIT_MASK (0xf << 16)
#define DLL_CALIB_INTERVAL_SHIFT 0
#define DLL_CALIB_INTERVAL_MASK (0x1ff << 0)
/* END_OF_INTERRUPT */
#define EOI_SHIFT 0
#define EOI_MASK (1 << 0)
/* SYSTEM_OCP_INTERRUPT_RAW_STATUS */
#define DNV_SYS_SHIFT 2
#define DNV_SYS_MASK (1 << 2)
#define TA_SYS_SHIFT 1
#define TA_SYS_MASK (1 << 1)
#define ERR_SYS_SHIFT 0
#define ERR_SYS_MASK (1 << 0)
/* LOW_LATENCY_OCP_INTERRUPT_RAW_STATUS */
#define DNV_LL_SHIFT 2
#define DNV_LL_MASK (1 << 2)
#define TA_LL_SHIFT 1
#define TA_LL_MASK (1 << 1)
#define ERR_LL_SHIFT 0
#define ERR_LL_MASK (1 << 0)
/* SYSTEM_OCP_INTERRUPT_ENABLE_SET */
#define EN_DNV_SYS_SHIFT 2
#define EN_DNV_SYS_MASK (1 << 2)
#define EN_TA_SYS_SHIFT 1
#define EN_TA_SYS_MASK (1 << 1)
#define EN_ERR_SYS_SHIFT 0
#define EN_ERR_SYS_MASK (1 << 0)
/* LOW_LATENCY_OCP_INTERRUPT_ENABLE_SET */
#define EN_DNV_LL_SHIFT 2
#define EN_DNV_LL_MASK (1 << 2)
#define EN_TA_LL_SHIFT 1
#define EN_TA_LL_MASK (1 << 1)
#define EN_ERR_LL_SHIFT 0
#define EN_ERR_LL_MASK (1 << 0)
/* SDRAM_OUTPUT_IMPEDANCE_CALIBRATION_CONFIG */
#define ZQ_CS1EN_SHIFT 31
#define ZQ_CS1EN_MASK (1 << 31)
#define ZQ_CS0EN_SHIFT 30
#define ZQ_CS0EN_MASK (1 << 30)
#define ZQ_DUALCALEN_SHIFT 29
#define ZQ_DUALCALEN_MASK (1 << 29)
#define ZQ_SFEXITEN_SHIFT 28
#define ZQ_SFEXITEN_MASK (1 << 28)
#define ZQ_ZQINIT_MULT_SHIFT 18
#define ZQ_ZQINIT_MULT_MASK (0x3 << 18)
#define ZQ_ZQCL_MULT_SHIFT 16
#define ZQ_ZQCL_MULT_MASK (0x3 << 16)
#define ZQ_REFINTERVAL_SHIFT 0
#define ZQ_REFINTERVAL_MASK (0xffff << 0)
/* TEMPERATURE_ALERT_CONFIG */
#define TA_CS1EN_SHIFT 31
#define TA_CS1EN_MASK (1 << 31)
#define TA_CS0EN_SHIFT 30
#define TA_CS0EN_MASK (1 << 30)
#define TA_SFEXITEN_SHIFT 28
#define TA_SFEXITEN_MASK (1 << 28)
#define TA_DEVWDT_SHIFT 26
#define TA_DEVWDT_MASK (0x3 << 26)
#define TA_DEVCNT_SHIFT 24
#define TA_DEVCNT_MASK (0x3 << 24)
#define TA_REFINTERVAL_SHIFT 0
#define TA_REFINTERVAL_MASK (0x3fffff << 0)
/* OCP_ERROR_LOG */
#define MADDRSPACE_SHIFT 14
#define MADDRSPACE_MASK (0x3 << 14)
#define MBURSTSEQ_SHIFT 11
#define MBURSTSEQ_MASK (0x7 << 11)
#define MCMD_SHIFT 8
#define MCMD_MASK (0x7 << 8)
#define MCONNID_SHIFT 0
#define MCONNID_MASK (0xff << 0)
/* DDR_PHY_CTRL_1 - EMIF4D */
#define DLL_SLAVE_DLY_CTRL_SHIFT_4D 4
#define DLL_SLAVE_DLY_CTRL_MASK_4D (0xFF << 4)
#define READ_LATENCY_SHIFT_4D 0
#define READ_LATENCY_MASK_4D (0xf << 0)
/* DDR_PHY_CTRL_1 - EMIF4D5 */
#define DLL_HALF_DELAY_SHIFT_4D5 21
#define DLL_HALF_DELAY_MASK_4D5 (1 << 21)
#define READ_LATENCY_SHIFT_4D5 0
#define READ_LATENCY_MASK_4D5 (0x1f << 0)
/* DDR_PHY_CTRL_1_SHDW */
#define DDR_PHY_CTRL_1_SHDW_SHIFT 5
#define DDR_PHY_CTRL_1_SHDW_MASK (0x7ffffff << 5)
#define READ_LATENCY_SHDW_SHIFT 0
#define READ_LATENCY_SHDW_MASK (0x1f << 0)
#ifndef __ASSEMBLY__
/*
* Structure containing shadow of important registers in EMIF
* The calculation function fills in this structure to be later used for
* initialisation and DVFS
*/
struct emif_regs {
u32 freq;
u32 ref_ctrl_shdw;
u32 ref_ctrl_shdw_derated;
u32 sdram_tim1_shdw;
u32 sdram_tim1_shdw_derated;
u32 sdram_tim2_shdw;
u32 sdram_tim3_shdw;
u32 sdram_tim3_shdw_derated;
u32 pwr_mgmt_ctrl_shdw;
union {
u32 read_idle_ctrl_shdw_normal;
u32 dll_calib_ctrl_shdw_normal;
};
union {
u32 read_idle_ctrl_shdw_volt_ramp;
u32 dll_calib_ctrl_shdw_volt_ramp;
};
u32 phy_ctrl_1_shdw;
u32 ext_phy_ctrl_2_shdw;
u32 ext_phy_ctrl_3_shdw;
u32 ext_phy_ctrl_4_shdw;
};
#endif /* __ASSEMBLY__ */
#endif /* __EMIF_H */

153
drivers/memory/of_memory.c Normal file
View File

@@ -0,0 +1,153 @@
/*
* OpenFirmware helpers for memory drivers
*
* Copyright (C) 2012 Texas Instruments, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/list.h>
#include <linux/of.h>
#include <linux/gfp.h>
#include <memory/jedec_ddr.h>
#include <linux/export.h>
/**
* of_get_min_tck() - extract min timing values for ddr
* @np: pointer to ddr device tree node
* @device: device requesting for min timing values
*
* Populates the lpddr2_min_tck structure by extracting data
* from device tree node. Returns a pointer to the populated
* structure. If any error in populating the structure, returns
* default min timings provided by JEDEC.
*/
const struct lpddr2_min_tck *of_get_min_tck(struct device_node *np,
struct device *dev)
{
int ret = 0;
struct lpddr2_min_tck *min;
min = devm_kzalloc(dev, sizeof(*min), GFP_KERNEL);
if (!min)
goto default_min_tck;
ret |= of_property_read_u32(np, "tRPab-min-tck", &min->tRPab);
ret |= of_property_read_u32(np, "tRCD-min-tck", &min->tRCD);
ret |= of_property_read_u32(np, "tWR-min-tck", &min->tWR);
ret |= of_property_read_u32(np, "tRASmin-min-tck", &min->tRASmin);
ret |= of_property_read_u32(np, "tRRD-min-tck", &min->tRRD);
ret |= of_property_read_u32(np, "tWTR-min-tck", &min->tWTR);
ret |= of_property_read_u32(np, "tXP-min-tck", &min->tXP);
ret |= of_property_read_u32(np, "tRTP-min-tck", &min->tRTP);
ret |= of_property_read_u32(np, "tCKE-min-tck", &min->tCKE);
ret |= of_property_read_u32(np, "tCKESR-min-tck", &min->tCKESR);
ret |= of_property_read_u32(np, "tFAW-min-tck", &min->tFAW);
if (ret) {
devm_kfree(dev, min);
goto default_min_tck;
}
return min;
default_min_tck:
dev_warn(dev, "%s: using default min-tck values\n", __func__);
return &lpddr2_jedec_min_tck;
}
EXPORT_SYMBOL(of_get_min_tck);
static int of_do_get_timings(struct device_node *np,
struct lpddr2_timings *tim)
{
int ret;
ret = of_property_read_u32(np, "max-freq", &tim->max_freq);
ret |= of_property_read_u32(np, "min-freq", &tim->min_freq);
ret |= of_property_read_u32(np, "tRPab", &tim->tRPab);
ret |= of_property_read_u32(np, "tRCD", &tim->tRCD);
ret |= of_property_read_u32(np, "tWR", &tim->tWR);
ret |= of_property_read_u32(np, "tRAS-min", &tim->tRAS_min);
ret |= of_property_read_u32(np, "tRRD", &tim->tRRD);
ret |= of_property_read_u32(np, "tWTR", &tim->tWTR);
ret |= of_property_read_u32(np, "tXP", &tim->tXP);
ret |= of_property_read_u32(np, "tRTP", &tim->tRTP);
ret |= of_property_read_u32(np, "tCKESR", &tim->tCKESR);
ret |= of_property_read_u32(np, "tDQSCK-max", &tim->tDQSCK_max);
ret |= of_property_read_u32(np, "tFAW", &tim->tFAW);
ret |= of_property_read_u32(np, "tZQCS", &tim->tZQCS);
ret |= of_property_read_u32(np, "tZQCL", &tim->tZQCL);
ret |= of_property_read_u32(np, "tZQinit", &tim->tZQinit);
ret |= of_property_read_u32(np, "tRAS-max-ns", &tim->tRAS_max_ns);
ret |= of_property_read_u32(np, "tDQSCK-max-derated",
&tim->tDQSCK_max_derated);
return ret;
}
/**
* of_get_ddr_timings() - extracts the ddr timings and updates no of
* frequencies available.
* @np_ddr: Pointer to ddr device tree node
* @dev: Device requesting for ddr timings
* @device_type: Type of ddr(LPDDR2 S2/S4)
* @nr_frequencies: No of frequencies available for ddr
* (updated by this function)
*
* Populates lpddr2_timings structure by extracting data from device
* tree node. Returns pointer to populated structure. If any error
* while populating, returns default timings provided by JEDEC.
*/
const struct lpddr2_timings *of_get_ddr_timings(struct device_node *np_ddr,
struct device *dev, u32 device_type, u32 *nr_frequencies)
{
struct lpddr2_timings *timings = NULL;
u32 arr_sz = 0, i = 0;
struct device_node *np_tim;
char *tim_compat;
switch (device_type) {
case DDR_TYPE_LPDDR2_S2:
case DDR_TYPE_LPDDR2_S4:
tim_compat = "jedec,lpddr2-timings";
break;
default:
dev_warn(dev, "%s: un-supported memory type\n", __func__);
}
for_each_child_of_node(np_ddr, np_tim)
if (of_device_is_compatible(np_tim, tim_compat))
arr_sz++;
if (arr_sz)
timings = devm_kzalloc(dev, sizeof(*timings) * arr_sz,
GFP_KERNEL);
if (!timings)
goto default_timings;
for_each_child_of_node(np_ddr, np_tim) {
if (of_device_is_compatible(np_tim, tim_compat)) {
if (of_do_get_timings(np_tim, &timings[i])) {
devm_kfree(dev, timings);
goto default_timings;
}
i++;
}
}
*nr_frequencies = arr_sz;
return timings;
default_timings:
dev_warn(dev, "%s: using default timings\n", __func__);
*nr_frequencies = ARRAY_SIZE(lpddr2_jedec_timings);
return lpddr2_jedec_timings;
}
EXPORT_SYMBOL(of_get_ddr_timings);

View File

@@ -0,0 +1,36 @@
/*
* OpenFirmware helpers for memory drivers
*
* Copyright (C) 2012 Texas Instruments, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef __LINUX_MEMORY_OF_REG_H
#define __LINUX_MEMORY_OF_REG_H
#if defined(CONFIG_OF) && defined(CONFIG_DDR)
extern const struct lpddr2_min_tck *of_get_min_tck(struct device_node *np,
struct device *dev);
extern const struct lpddr2_timings
*of_get_ddr_timings(struct device_node *np_ddr, struct device *dev,
u32 device_type, u32 *nr_frequencies);
#else
static inline const struct lpddr2_min_tck
*of_get_min_tck(struct device_node *np, struct device *dev)
{
return NULL;
}
static inline const struct lpddr2_timings
*of_get_ddr_timings(struct device_node *np_ddr, struct device *dev,
u32 device_type, u32 *nr_frequencies)
{
return NULL;
}
#endif /* CONFIG_OF && CONFIG_DDR */
#endif /* __LINUX_MEMORY_OF_REG_ */

View File

@@ -0,0 +1,402 @@
/*
* Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _TEGRA114_EMC_REG_H
#define _TEGRA114_EMC_REG_H
enum {
DRAM_DEV_SEL_ALL = 0,
DRAM_DEV_SEL_0 = (2 << 30),
DRAM_DEV_SEL_1 = (1 << 30),
};
#define DRAM_BROADCAST(num) \
(((num) > 1) ? DRAM_DEV_SEL_ALL : DRAM_DEV_SEL_0)
#define EMC_INTSTATUS 0x0
#define EMC_INTSTATUS_CLKCHANGE_COMPLETE (0x1 << 4)
#define EMC_DBG 0x8
#define EMC_DBG_WRITE_MUX_ACTIVE (0x1 << 1)
#define EMC_CFG 0xc
#define EMC_CFG_DRAM_ACPD (0x1 << 29)
#define EMC_CFG_DYN_SREF_ENABLE (0x1 << 28)
#define EMC_CFG_PWR_MASK (0xF << 28)
#define EMC_CFG_PERIODIC_QRST (0x1 << 21)
#define EMC_CFG_EN_DYNAMIC_PUTERM (0x1 << 20)
#define EMC_CFG_DLY_WR_DQ_HALF_CLOCK (0x1 << 19)
#define EMC_CFG_DSR_VTTGEN_DRV_EN (0x1 << 18)
#define EMC_CFG_EMC2PMACRO_CFG_BYPASS_DATAPIPE2 (0x1 << 3)
#define EMC_CFG_EMC2PMACRO_CFG_BYPASS_DATAPIPE1 (0x1 << 2)
#define EMC_CFG_EMC2PMACRO_CFG_BYPASS_ADDRPIPE (0x1 << 1)
#define EMC_CFG_UPDATE_MASK \
(EMC_CFG_EMC2PMACRO_CFG_BYPASS_ADDRPIPE | \
EMC_CFG_EMC2PMACRO_CFG_BYPASS_DATAPIPE1 | \
EMC_CFG_EMC2PMACRO_CFG_BYPASS_DATAPIPE2 | \
EMC_CFG_DSR_VTTGEN_DRV_EN | \
EMC_CFG_DLY_WR_DQ_HALF_CLOCK | \
EMC_CFG_EN_DYNAMIC_PUTERM | \
EMC_CFG_PERIODIC_QRST | \
EMC_CFG_DRAM_ACPD)
#define EMC_REFCTRL 0x20
#define EMC_REFCTRL_DEV_SEL_SHIFT 0
#define EMC_REFCTRL_DEV_SEL_MASK \
(0x3 << EMC_REFCTRL_DEV_SEL_SHIFT)
#define EMC_REFCTRL_ENABLE (0x1 << 31)
#define EMC_REFCTRL_ENABLE_ALL(num) \
(((((num) > 1) ? 0 : 2) << EMC_REFCTRL_DEV_SEL_SHIFT) \
| EMC_REFCTRL_ENABLE)
#define EMC_REFCTRL_DISABLE_ALL(num) \
((((num) > 1) ? 0 : 2) << EMC_REFCTRL_DEV_SEL_SHIFT)
#define EMC_TIMING_CONTROL 0x28
#define EMC_RC 0x2c
#define EMC_RFC 0x30
#define EMC_RAS 0x34
#define EMC_RP 0x38
#define EMC_R2W 0x3c
#define EMC_W2R 0x40
#define EMC_R2P 0x44
#define EMC_W2P 0x48
#define EMC_RD_RCD 0x4c
#define EMC_WR_RCD 0x50
#define EMC_RRD 0x54
#define EMC_REXT 0x58
#define EMC_WDV 0x5c
#define EMC_QUSE 0x60
#define EMC_QRST 0x64
#define EMC_QSAFE 0x68
#define EMC_RDV 0x6c
#define EMC_REFRESH 0x70
#define EMC_BURST_REFRESH_NUM 0x74
#define EMC_PDEX2WR 0x78
#define EMC_PDEX2RD 0x7c
#define EMC_PCHG2PDEN 0x80
#define EMC_ACT2PDEN 0x84
#define EMC_AR2PDEN 0x88
#define EMC_RW2PDEN 0x8c
#define EMC_TXSR 0x90
#define EMC_TCKE 0x94
#define EMC_TFAW 0x98
#define EMC_TRPAB 0x9c
#define EMC_TCLKSTABLE 0xa0
#define EMC_TCLKSTOP 0xa4
#define EMC_TREFBW 0xa8
#define EMC_QUSE_EXTRA 0xac
#define EMC_ODT_WRITE 0xb0
#define EMC_ODT_READ 0xb4
#define EMC_WEXT 0xb8
#define EMC_CTT 0xbc
#define EMC_RFC_SLR 0xc0
#define EMC_MRS_WAIT_CNT2 0xc4
#define EMC_MRS_WAIT_CNT 0xc8
#define EMC_MRS_WAIT_CNT 0xc8
#define EMC_MRS_WAIT_CNT_SHORT_WAIT_SHIFT 0
#define EMC_MRS_WAIT_CNT_SHORT_WAIT_MASK \
(0x3FF << EMC_MRS_WAIT_CNT_SHORT_WAIT_SHIFT)
#define EMC_MRS_WAIT_CNT_LONG_WAIT_SHIFT 16
#define EMC_MRS_WAIT_CNT_LONG_WAIT_MASK \
(0x3FF << EMC_MRS_WAIT_CNT_LONG_WAIT_SHIFT)
#define EMC_MRS 0xcc
#define EMC_MODE_SET_DLL_RESET (0x1 << 8)
#define EMC_MODE_SET_LONG_CNT (0x1 << 26)
#define EMC_EMRS 0xd0
#define EMC_REF 0xd4
#define EMC_PRE 0xd8
#define EMC_NOP 0xdc
#define EMC_SELF_REF 0xe0
#define EMC_SELF_REF_CMD_ENABLED (0x1 << 0)
#define EMC_SELF_REF_DEV_SEL_SHIFT 30
#define EMC_SELF_REF_DEV_SEL_MASK \
(0x3 << EMC_SELF_REF_DEV_SEL_SHIFT)
#define EMC_DPD 0xe4
#define EMC_MRW 0xe8
#define EMC_MRR 0xec
#define EMC_MRR_DEV_SEL_SHIFT 30
#define EMC_MRR_DEV_SEL_MASK \
(0x3 << EMC_SELF_REF_DEV_SEL_SHIFT)
#define EMC_MRR_MA_SHIFT 16
#define EMC_MRR_MA_MASK (0xFF << EMC_MRR_MA_SHIFT)
#define EMC_MRR_DATA_MASK ((0x1 << EMC_MRR_MA_SHIFT) - 1)
#define LPDDR2_MR4_TEMP_SHIFT 0
#define LPDDR2_MR4_TEMP_MASK (0x7 << LPDDR2_MR4_TEMP_SHIFT)
#define EMC_CMDQ 0xf0
#define EMC_MC2EMCQ 0xf4
#define EMC_XM2DQSPADCTRL3 0xf8
#define EMC_XM2DQSPADCTRL3_VREF_ENABLE (0x1 << 5)
#define EMC_FBIO_SPARE 0x100
#define EMC_FBIO_CFG5 0x104
#define EMC_CFG5_TYPE_SHIFT 0x0
#define EMC_CFG5_TYPE_MASK (0x3 << EMC_CFG5_TYPE_SHIFT)
enum {
DRAM_TYPE_DDR3 = 0,
DRAM_TYPE_LPDDR2 = 2,
};
#define EMC_CFG5_QUSE_MODE_SHIFT 13
#define EMC_CFG5_QUSE_MODE_MASK \
(0x7 << EMC_CFG5_QUSE_MODE_SHIFT)
enum {
EMC_CFG5_QUSE_MODE_NORMAL = 0,
EMC_CFG5_QUSE_MODE_ALWAYS_ON,
EMC_CFG5_QUSE_MODE_INTERNAL_LPBK,
EMC_CFG5_QUSE_MODE_PULSE_INTERN,
EMC_CFG5_QUSE_MODE_PULSE_EXTERN,
EMC_CFG5_QUSE_MODE_DIRECT_QUSE,
};
#define EMC_FBIO_WRPTR_EQ_2 0x108
#define EMC_FBIO_CFG6 0x114
#define EMC_CFG_RSV 0x120
#define EMC_ACPD_CONTROL 0x124
#define EMC_EMRS2 0x12c
#define EMC_EMRS3 0x130
#define EMC_MRW2 0x134
#define EMC_MRW3 0x138
#define EMC_MRW4 0x13c
#define EMC_CLKEN_OVERRIDE 0x140
#define EMC_R2R 0x144
#define EMC_W2W 0x148
#define EMC_EINPUT 0x14c
#define EMC_EINPUT_DURATION 0x150
#define EMC_PUTERM_EXTRA 0x154
#define EMC_TCKESR 0x158
#define EMC_TPD 0x15c
#define EMC_AUTO_CAL_CONFIG 0x2a4
#define EMC_AUTO_CAL_INTERVAL 0x2a8
#define EMC_AUTO_CAL_STATUS 0x2ac
#define EMC_AUTO_CAL_STATUS_ACTIVE (0x1 << 31)
#define EMC_REQ_CTRL 0x2b0
#define EMC_STATUS 0x2b4
#define EMC_STATUS_TIMING_UPDATE_STALLED (0x1 << 23)
#define EMC_STATUS_MRR_DIVLD (0x1 << 20)
#define EMC_CFG_2 0x2b8
#define EMC_CFG_2_MODE_SHIFT 0
#define EMC_CFG_2_MODE_MASK (0x3 << EMC_CFG_2_MODE_SHIFT)
#define EMC_CFG_2_SREF_MODE 0x1
#define EMC_CFG_2_PD_MODE 0x3
#define EMC_CFG_DIG_DLL 0x2bc
#define EMC_CFG_DIG_DLL_PERIOD 0x2c0
#define EMC_DIG_DLL_STATUS 0x2c8
#define EMC_RDV_MASK 0x2cc
#define EMC_WDV_MASK 0x2d0
#define EMC_CTT_DURATION 0x2d8
#define EMC_CTT_TERM_CTRL 0x2dc
#define EMC_ZCAL_INTERVAL 0x2e0
#define EMC_ZCAL_WAIT_CNT 0x2e4
#define EMC_ZCAL_MRW_CMD 0x2e8
#define EMC_ZQ_CAL 0x2ec
#define EMC_ZQ_CAL_DEV_SEL_SHIFT 30
#define EMC_ZQ_CAL_DEV_SEL_MASK \
(0x3 << EMC_SELF_REF_DEV_SEL_SHIFT)
#define EMC_ZQ_CAL_CMD (0x1 << 0)
#define EMC_ZQ_CAL_LONG (0x1 << 4)
#define EMC_ZQ_CAL_LONG_CMD_DEV0 \
(DRAM_DEV_SEL_0 | EMC_ZQ_CAL_LONG | EMC_ZQ_CAL_CMD)
#define EMC_ZQ_CAL_LONG_CMD_DEV1 \
(DRAM_DEV_SEL_1 | EMC_ZQ_CAL_LONG | EMC_ZQ_CAL_CMD)
#define EMC_XM2CMDPADCTRL 0x2f0
#define EMC_XM2CMDPADCTRL2 0x2f4
#define EMC_XM2DQSPADCTRL 0x2f8
#define EMC_XM2DQSPADCTRL2 0x2fc
#define EMC_XM2DQSPADCTRL2_VREF_ENABLE (0x1 << 5)
#define EMC_XM2DQPADCTRL 0x300
#define EMC_XM2DQPADCTRL2 0x304
#define EMC_XM2CLKPADCTRL 0x308
#define EMC_XM2COMPPADCTRL 0x30c
#define EMC_XM2COMPPADCTRL_VREF_CAL_ENABLE (0x1 << 10)
#define EMC_XM2VTTGENPADCTRL 0x310
#define EMC_XM2VTTGENPADCTRL2 0x314
#define EMC_EMCPADEN 0x31c
#define EMC_XM2DQSPADCTRL4 0x320
#define EMC_SCRATCH0 0x324
#define EMC_DLL_XFORM_DQS0 0x328
#define EMC_DLL_XFORM_DQS1 0x32c
#define EMC_DLL_XFORM_DQS2 0x330
#define EMC_DLL_XFORM_DQS3 0x334
#define EMC_DLL_XFORM_DQS4 0x338
#define EMC_DLL_XFORM_DQS5 0x33c
#define EMC_DLL_XFORM_DQS6 0x340
#define EMC_DLL_XFORM_DQS7 0x344
#define EMC_DLL_XFORM_QUSE0 0x348
#define EMC_DLL_XFORM_QUSE1 0x34c
#define EMC_DLL_XFORM_QUSE2 0x350
#define EMC_DLL_XFORM_QUSE3 0x354
#define EMC_DLL_XFORM_QUSE4 0x358
#define EMC_DLL_XFORM_QUSE5 0x35c
#define EMC_DLL_XFORM_QUSE6 0x360
#define EMC_DLL_XFORM_QUSE7 0x364
#define EMC_DLL_XFORM_DQ0 0x368
#define EMC_DLL_XFORM_DQ1 0x36c
#define EMC_DLL_XFORM_DQ2 0x370
#define EMC_DLL_XFORM_DQ3 0x374
#define EMC_DLI_RX_TRIM0 0x378
#define EMC_DLI_RX_TRIM1 0x37c
#define EMC_DLI_RX_TRIM2 0x380
#define EMC_DLI_RX_TRIM3 0x384
#define EMC_DLI_RX_TRIM4 0x388
#define EMC_DLI_RX_TRIM5 0x38c
#define EMC_DLI_RX_TRIM6 0x390
#define EMC_DLI_RX_TRIM7 0x394
#define EMC_DLI_TX_TRIM0 0x398
#define EMC_DLI_TX_TRIM1 0x39c
#define EMC_DLI_TX_TRIM2 0x3a0
#define EMC_DLI_TX_TRIM3 0x3a4
#define EMC_DLI_TRIM_TXDQS0 0x3a8
#define EMC_DLI_TRIM_TXDQS1 0x3ac
#define EMC_DLI_TRIM_TXDQS2 0x3b0
#define EMC_DLI_TRIM_TXDQS3 0x3b4
#define EMC_DLI_TRIM_TXDQS4 0x3b8
#define EMC_DLI_TRIM_TXDQS5 0x3bc
#define EMC_DLI_TRIM_TXDQS6 0x3c0
#define EMC_DLI_TRIM_TXDQS7 0x3c4
#define EMC_STALL_THEN_EXE_AFTER_CLKCHANGE 0x3cc
#define EMC_AUTO_CAL_CLK_STATUS 0x3d4
#define EMC_SEL_DPD_CTRL 0x3d8
#define EMC_SEL_DPD_CTRL_QUSE_DPD_ENABLE (0x1 << 9)
#define EMC_PRE_REFRESH_REQ_CNT 0x3dc
#define EMC_DYN_SELF_REF_CONTROL 0x3e0
#define EMC_TXSRDLL 0x3e4
#define EMC_CCFIFO_ADDR 0x3e8
#define EMC_CCFIFO_DATA 0x3ec
#define EMC_CCFIFO_STATUS 0x3f0
#define EMC_CDB_CNTL_1 0x3f4
#define EMC_CDB_CNTL_2 0x3f8
#define EMC_XM2CLKPADCTRL2 0x3fc
#define EMC_SWIZZLE_RANK0_BYTE_CFG 0x400
#define EMC_SWIZZLE_RANK0_BYTE0 0x404
#define EMC_SWIZZLE_RANK0_BYTE1 0x408
#define EMC_SWIZZLE_RANK0_BYTE2 0x40c
#define EMC_SWIZZLE_RANK0_BYTE3 0x410
#define EMC_SWIZZLE_RANK1_BYTE_CFG 0x414
#define EMC_SWIZZLE_RANK1_BYTE0 0x418
#define EMC_SWIZZLE_RANK1_BYTE1 0x41c
#define EMC_SWIZZLE_RANK1_BYTE2 0x420
#define EMC_SWIZZLE_RANK1_BYTE3 0x424
#define EMC_CA_TRAINING_START 0x428
#define EMC_CA_TRAINING_BUSY 0x42c
#define EMC_CA_TRAINING_CFG 0x430
#define EMC_CA_TRAINING_TIMING_CNTL1 0x434
#define EMC_CA_TRAINING_TIMING_CNTL2 0x438
#define EMC_CA_TRAINING_CA_LEAD_IN 0x43c
#define EMC_CA_TRAINING_CA 0x440
#define EMC_CA_TRAINING_CA_LEAD_OUT 0x444
#define EMC_CA_TRAINING_RESULT1 0x448
#define EMC_CA_TRAINING_RESULT2 0x44c
#define EMC_CA_TRAINING_RESULT3 0x450
#define EMC_CA_TRAINING_RESULT4 0x454
#define EMC_AUTO_CAL_CONFIG2 0x458
#define EMC_AUTO_CAL_CONFIG3 0x45c
#define EMC_AUTO_CAL_STATUS2 0x460
#define EMC_XM2CMDPADCTRL3 0x464
#define EMC_IBDLY 0x468
#define EMC_DLL_XFORM_ADDR0 0x46c
#define EMC_DLL_XFORM_ADDR1 0x470
#define EMC_DLL_XFORM_ADDR2 0x474
#define EMC_DLI_ADDR_TRIM 0x478
#define EMC_DSR_VTTGEN_DRV 0x47c
#define EMC_TXDSRVTTGEN 0x480
#define EMC_XM2CMDPADCTRL4 0x484
#define EMC_ADDR_SWIZZLE_STACK1A 0x488
#define EMC_ADDR_SWIZZLE_STACK1B 0x48c
#define EMC_ADDR_SWIZZLE_STACK2A 0x490
#define EMC_ADDR_SWIZZLE_STACK2B 0x494
#define EMC_ADDR_SWIZZLE_STACK3 0x498
#define MC_EMEM_ADR_CFG 0x54
#define MC_EMEM_ARB_CFG 0x90
#define MC_EMEM_ARB_OUTSTANDING_REQ 0x94
#define MC_EMEM_ARB_TIMING_RCD 0x98
#define MC_EMEM_ARB_TIMING_RP 0x9c
#define MC_EMEM_ARB_TIMING_RC 0xa0
#define MC_EMEM_ARB_TIMING_RAS 0xa4
#define MC_EMEM_ARB_TIMING_FAW 0xa8
#define MC_EMEM_ARB_TIMING_RRD 0xac
#define MC_EMEM_ARB_TIMING_RAP2PRE 0xb0
#define MC_EMEM_ARB_TIMING_WAP2PRE 0xb4
#define MC_EMEM_ARB_TIMING_R2R 0xb8
#define MC_EMEM_ARB_TIMING_W2W 0xbc
#define MC_EMEM_ARB_TIMING_R2W 0xc0
#define MC_EMEM_ARB_TIMING_W2R 0xc4
#define MC_EMEM_ARB_DA_TURNS 0xd0
#define MC_EMEM_ARB_DA_COVERS 0xd4
#define MC_EMEM_ARB_MISC0 0xd8
#define MC_EMEM_ARB_MISC0_EMC_SAME_FREQ (0x1 << 27)
#define MC_EMEM_ARB_MISC1 0xdc
#define MC_EMEM_ARB_RING1_THROTTLE 0xe0
#define MC_EMEM_ARB_RING3_THROTTLE 0xe4
#define MC_EMEM_ARB_OVERRIDE 0xe8
#define MC_EMEM_ARB_RSV 0xec
#define MC_TIMING_CONTROL 0xfc
#define MC_LATENCY_ALLOWANCE_AVPC_0 0x2e4
#define MC_LATENCY_ALLOWANCE_DC_0 0x2e8
#define MC_LATENCY_ALLOWANCE_DC_1 0x2ec
#define MC_LATENCY_ALLOWANCE_DC_2 0x2f0
#define MC_LATENCY_ALLOWANCE_DCB_0 0x2f4
#define MC_LATENCY_ALLOWANCE_DCB_1 0x2f8
#define MC_LATENCY_ALLOWANCE_DCB_2 0x2fc
#define MC_LATENCY_ALLOWANCE_EPP_0 0x300
#define MC_LATENCY_ALLOWANCE_EPP_1 0x304
#define MC_LATENCY_ALLOWANCE_G2_0 0x308
#define MC_LATENCY_ALLOWANCE_G2_1 0x30c
#define MC_LATENCY_ALLOWANCE_HC_0 0x310
#define MC_LATENCY_ALLOWANCE_HC_1 0x314
#define MC_LATENCY_ALLOWANCE_HDA_0 0x318
#define MC_LATENCY_ALLOWANCE_ISP_0 0x31c
#define MC_LATENCY_ALLOWANCE_MPCORE_0 0x320
#define MC_LATENCY_ALLOWANCE_MPCORELP_0 0x324
#define MC_LATENCY_ALLOWANCE_MSENC_0 0x328
#define MC_LATENCY_ALLOWANCE_NV_0 0x334
#define MC_LATENCY_ALLOWANCE_NV_1 0x338
#define MC_LATENCY_ALLOWANCE_NV2_0 0x33c
#define MC_LATENCY_ALLOWANCE_NV2_1 0x340
#define MC_LATENCY_ALLOWANCE_PPCS_0 0x344
#define MC_LATENCY_ALLOWANCE_PPCS_1 0x348
#define MC_LATENCY_ALLOWANCE_PTC_0 0x34c
#define MC_LATENCY_ALLOWANCE_VDE_0 0x354
#define MC_LATENCY_ALLOWANCE_VDE_1 0x358
#define MC_LATENCY_ALLOWANCE_VDE_2 0x35c
#define MC_LATENCY_ALLOWANCE_VDE_3 0x360
#define MC_LATENCY_ALLOWANCE_VI_0 0x364
#define MC_LATENCY_ALLOWANCE_VI_1 0x368
#define MC_LATENCY_ALLOWANCE_VI_2 0x36c
#define MC_LATENCY_ALLOWANCE_XUSB_0 0x37c
#define MC_LATENCY_ALLOWANCE_XUSB_1 0x380
#define MC_LATENCY_ALLOWANCE_NV_2 0x384
#define MC_LATENCY_ALLOWANCE_NV_3 0x388
#define MC_LATENCY_ALLOWANCE_EMUCIF_0 0x38c
#define MC_LATENCY_ALLOWANCE_TSEC_0 0x390
#define MC_RESERVED_RSV 0x3fc
#define MC_PTSA_GRANT_DECREMENT 0x960
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,69 @@
/*
* Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/of_address.h>
#include <linux/platform_data/tegra_mc.h>
#define DRV_NAME "tegra114-mc"
static void __iomem *tegra_mc_base;
static void __iomem *tegra_mc0_base;
static void __iomem *tegra_mc1_base;
u32 tegra114_mc_readl(u32 offs)
{
return readl(tegra_mc_base + offs);
}
EXPORT_SYMBOL(tegra114_mc_readl);
void tegra114_mc_writel(u32 val, u32 offs)
{
writel(val, tegra_mc_base + offs);
}
EXPORT_SYMBOL(tegra114_mc_writel);
static int tegra114_mc_probe(struct platform_device *pdev)
{
tegra_mc0_base = of_iomap(pdev->dev.of_node, 0);
tegra_mc_base = of_iomap(pdev->dev.of_node, 1);
tegra_mc1_base = of_iomap(pdev->dev.of_node, 2);
return 0;
}
static const struct of_device_id tegra114_mc_of_match[] = {
{ .compatible = "nvidia,tegra114-mc", },
{},
};
static struct platform_driver tegra114_mc_driver = {
.probe = tegra114_mc_probe,
.driver = {
.name = DRV_NAME,
.owner = THIS_MODULE,
.of_match_table = tegra114_mc_of_match,
},
};
module_platform_driver(tegra114_mc_driver);
MODULE_DESCRIPTION("Tegra114 MC driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:" DRV_NAME);

View File

@@ -0,0 +1,485 @@
/*
* Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _TEGRA124_EMC_REG_H
#define _TEGRA124_EMC_REG_H
enum {
DRAM_DEV_SEL_ALL = 0,
DRAM_DEV_SEL_0 = (2 << 30),
DRAM_DEV_SEL_1 = (1 << 30),
};
#define DRAM_BROADCAST(num) \
(((num) > 1) ? DRAM_DEV_SEL_ALL : DRAM_DEV_SEL_0)
#define EMC_INTSTATUS 0x0
#define EMC_INTSTATUS_CLKCHANGE_COMPLETE (0x1 << 4)
#define EMC_DBG 0x8
#define EMC_DBG_WRITE_MUX_ACTIVE (0x1 << 1)
#define EMC_CFG 0xc
#define EMC_CFG_DRAM_CLKSTOP_PD (0x1 << 31)
#define EMC_CFG_DRAM_CLKSTOP_SR (0x1 << 30)
#define EMC_CFG_DRAM_ACPD (0x1 << 29)
#define EMC_CFG_DYN_SREF (0x1 << 28)
#define EMC_CFG_PWR_MASK (0xF << 28)
#define EMC_CFG_PERIODIC_QRST (0x1 << 21)
#define EMC_CFG_EN_DYNAMIC_PUTERM (0x1 << 20)
#define EMC_CFG_DLY_WR_DQ_HALF_CLOCK (0x1 << 19)
#define EMC_CFG_DSR_VTTGEN_DRV_EN (0x1 << 18)
#define EMC_CFG_EMC2MC_CLK_RATIO (0x3 << 16)
#define EMC_CFG_EMC2PMACRO_CFG_BYPASS_DATAPIPE2 (0x1 << 3)
#define EMC_CFG_EMC2PMACRO_CFG_BYPASS_DATAPIPE1 (0x1 << 2)
#define EMC_CFG_EMC2PMACRO_CFG_BYPASS_ADDRPIPE (0x1 << 1)
#define EMC_CFG_UPDATE_MASK \
(EMC_CFG_EMC2PMACRO_CFG_BYPASS_ADDRPIPE | \
EMC_CFG_EMC2PMACRO_CFG_BYPASS_DATAPIPE1 | \
EMC_CFG_EMC2PMACRO_CFG_BYPASS_DATAPIPE2 | \
EMC_CFG_EMC2MC_CLK_RATIO | \
EMC_CFG_DSR_VTTGEN_DRV_EN | \
EMC_CFG_DLY_WR_DQ_HALF_CLOCK | \
EMC_CFG_EN_DYNAMIC_PUTERM | \
EMC_CFG_PERIODIC_QRST | \
EMC_CFG_DRAM_ACPD)
#define EMC_ADR_CFG 0x10
#define EMC_REFCTRL 0x20
#define EMC_REFCTRL_DEV_SEL_SHIFT 0
#define EMC_REFCTRL_DEV_SEL_MASK \
(0x3 << EMC_REFCTRL_DEV_SEL_SHIFT)
#define EMC_REFCTRL_ENABLE (0x1 << 31)
#define EMC_REFCTRL_ENABLE_ALL(num) \
(((((num) > 1) ? 0 : 2) << EMC_REFCTRL_DEV_SEL_SHIFT) \
| EMC_REFCTRL_ENABLE)
#define EMC_REFCTRL_DISABLE_ALL(num) \
((((num) > 1) ? 0 : 2) << EMC_REFCTRL_DEV_SEL_SHIFT)
#define EMC_TIMING_CONTROL 0x28
#define EMC_RC 0x2c
#define EMC_RFC 0x30
#define EMC_RAS 0x34
#define EMC_RP 0x38
#define EMC_R2W 0x3c
#define EMC_W2R 0x40
#define EMC_R2P 0x44
#define EMC_W2P 0x48
#define EMC_RD_RCD 0x4c
#define EMC_WR_RCD 0x50
#define EMC_RRD 0x54
#define EMC_REXT 0x58
#define EMC_WDV 0x5c
#define EMC_QUSE 0x60
#define EMC_QRST 0x64
#define EMC_QSAFE 0x68
#define EMC_RDV 0x6c
#define EMC_REFRESH 0x70
#define EMC_BURST_REFRESH_NUM 0x74
#define EMC_PDEX2WR 0x78
#define EMC_PDEX2RD 0x7c
#define EMC_PCHG2PDEN 0x80
#define EMC_ACT2PDEN 0x84
#define EMC_AR2PDEN 0x88
#define EMC_RW2PDEN 0x8c
#define EMC_TXSR 0x90
#define EMC_TCKE 0x94
#define EMC_TFAW 0x98
#define EMC_TRPAB 0x9c
#define EMC_TCLKSTABLE 0xa0
#define EMC_TCLKSTOP 0xa4
#define EMC_TREFBW 0xa8
#define EMC_ODT_WRITE 0xb0
#define EMC_ODT_READ 0xb4
#define EMC_WEXT 0xb8
#define EMC_CTT 0xbc
#define EMC_RFC_SLR 0xc0
#define EMC_MRS_WAIT_CNT2 0xc4
#define EMC_MRS_WAIT_CNT 0xc8
#define EMC_MRS_WAIT_CNT_SHORT_WAIT_SHIFT 0
#define EMC_MRS_WAIT_CNT_SHORT_WAIT_MASK \
(0x3FF << EMC_MRS_WAIT_CNT_SHORT_WAIT_SHIFT)
#define EMC_MRS_WAIT_CNT_LONG_WAIT_SHIFT 16
#define EMC_MRS_WAIT_CNT_LONG_WAIT_MASK \
(0x3FF << EMC_MRS_WAIT_CNT_LONG_WAIT_SHIFT)
#define EMC_MRS 0xcc
#define EMC_MODE_SET_DLL_RESET (0x1 << 8)
#define EMC_MODE_SET_LONG_CNT (0x1 << 26)
#define EMC_EMRS 0xd0
#define EMC_REF 0xd4
#define EMC_PRE 0xd8
#define EMC_NOP 0xdc
#define EMC_SELF_REF 0xe0
#define EMC_SELF_REF_CMD_ENABLED (0x1 << 0)
#define EMC_SELF_REF_DEV_SEL_SHIFT 30
#define EMC_SELF_REF_DEV_SEL_MASK \
(0x3 << EMC_SELF_REF_DEV_SEL_SHIFT)
#define EMC_DPD 0xe4
#define EMC_MRW 0xe8
#define EMC_MRR 0xec
#define EMC_MRR_DEV_SEL_SHIFT 30
#define EMC_MRR_DEV_SEL_MASK \
(0x3 << EMC_SELF_REF_DEV_SEL_SHIFT)
#define EMC_MRR_MA_SHIFT 16
#define EMC_MRR_MA_MASK (0xFF << EMC_MRR_MA_SHIFT)
#define EMC_MRR_DATA_MASK ((0x1 << EMC_MRR_MA_SHIFT) - 1)
#define LPDDR2_MR4_TEMP_SHIFT 0
#define LPDDR2_MR4_TEMP_MASK (0x7 << LPDDR2_MR4_TEMP_SHIFT)
#define EMC_CMDQ 0xf0
#define EMC_MC2EMCQ 0xf4
#define EMC_XM2DQSPADCTRL3 0xf8
#define EMC_XM2DQSPADCTRL3_VREF_ENABLE (0x1 << 5)
#define EMC_FBIO_SPARE 0x100
#define EMC_FBIO_CFG5 0x104
#define EMC_CFG5_TYPE_SHIFT 0x0
#define EMC_CFG5_TYPE_MASK (0x3 << EMC_CFG5_TYPE_SHIFT)
enum {
DRAM_TYPE_DDR3 = 0,
DRAM_TYPE_LPDDR2 = 2,
};
#define EMC_CFG5_QUSE_MODE_SHIFT 13
#define EMC_CFG5_QUSE_MODE_MASK \
(0x7 << EMC_CFG5_QUSE_MODE_SHIFT)
enum {
EMC_CFG5_QUSE_MODE_NORMAL = 0,
EMC_CFG5_QUSE_MODE_ALWAYS_ON,
EMC_CFG5_QUSE_MODE_INTERNAL_LPBK,
EMC_CFG5_QUSE_MODE_PULSE_INTERN,
EMC_CFG5_QUSE_MODE_PULSE_EXTERN,
EMC_CFG5_QUSE_MODE_DIRECT_QUSE,
};
#define EMC_FBIO_WRPTR_EQ_2 0x108
#define EMC_FBIO_CFG6 0x114
#define EMC_CFG_RSV 0x120
#define EMC_ACPD_CONTROL 0x124
#define EMC_EMRS2 0x12c
#define EMC_EMRS3 0x130
#define EMC_MRW2 0x134
#define EMC_MRW3 0x138
#define EMC_MRW4 0x13c
#define EMC_CLKEN_OVERRIDE 0x140
#define EMC_R2R 0x144
#define EMC_W2W 0x148
#define EMC_EINPUT 0x14c
#define EMC_EINPUT_DURATION 0x150
#define EMC_PUTERM_EXTRA 0x154
#define EMC_TCKESR 0x158
#define EMC_TPD 0x15c
#define EMC_AUTO_CAL_CONFIG 0x2a4
#define EMC_AUTO_CAL_CONFIG_AUTO_CAL_START (0x1 << 31)
#define EMC_AUTO_CAL_INTERVAL 0x2a8
#define EMC_AUTO_CAL_STATUS 0x2ac
#define EMC_AUTO_CAL_STATUS_ACTIVE (0x1 << 31)
#define EMC_REQ_CTRL 0x2b0
#define EMC_STATUS 0x2b4
#define EMC_STATUS_TIMING_UPDATE_STALLED (0x1 << 23)
#define EMC_STATUS_MRR_DIVLD (0x1 << 20)
#define EMC_CFG_2 0x2b8
#define EMC_CFG_2_MODE_SHIFT 0
#define EMC_CFG_2_MODE_MASK (0x3 << EMC_CFG_2_MODE_SHIFT)
#define EMC_CFG_2_SREF_MODE 0x1
#define EMC_CFG_2_PD_MODE 0x3
#define EMC_CFG_2_DIS_STP_OB_CLK_DURING_NON_WR (0x1 << 6)
#define EMC_CFG_DIG_DLL 0x2bc
#define EMC_CFG_DIG_DLL_PERIOD 0x2c0
#define EMC_DIG_DLL_STATUS 0x2c8
#define EMC_RDV_MASK 0x2cc
#define EMC_WDV_MASK 0x2d0
#define EMC_CTT_DURATION 0x2d8
#define EMC_CTT_TERM_CTRL 0x2dc
#define EMC_ZCAL_INTERVAL 0x2e0
#define EMC_ZCAL_WAIT_CNT 0x2e4
#define EMC_ZCAL_MRW_CMD 0x2e8
#define EMC_ZQ_CAL 0x2ec
#define EMC_ZQ_CAL_DEV_SEL_SHIFT 30
#define EMC_ZQ_CAL_DEV_SEL_MASK \
(0x3 << EMC_SELF_REF_DEV_SEL_SHIFT)
#define EMC_ZQ_CAL_CMD (0x1 << 0)
#define EMC_ZQ_CAL_LONG (0x1 << 4)
#define EMC_ZQ_CAL_LONG_CMD_DEV0 \
(DRAM_DEV_SEL_0 | EMC_ZQ_CAL_LONG | EMC_ZQ_CAL_CMD)
#define EMC_ZQ_CAL_LONG_CMD_DEV1 \
(DRAM_DEV_SEL_1 | EMC_ZQ_CAL_LONG | EMC_ZQ_CAL_CMD)
#define EMC_XM2CMDPADCTRL 0x2f0
#define EMC_XM2CMDPADCTRL2 0x2f4
#define EMC_XM2DQSPADCTRL 0x2f8
#define EMC_XM2DQSPADCTRL2 0x2fc
#define EMC_XM2DQSPADCTRL2_RX_FT_REC_ENABLE (0x1 << 0)
#define EMC_XM2DQSPADCTRL2_VREF_ENABLE (0x1 << 5)
#define EMC_XM2DQPADCTRL 0x300
#define EMC_XM2DQPADCTRL2 0x304
#define EMC_XM2CLKPADCTRL 0x308
#define EMC_XM2COMPPADCTRL 0x30c
#define EMC_XM2COMPPADCTRL_VREF_CAL_ENABLE (0x1 << 10)
#define EMC_XM2VTTGENPADCTRL 0x310
#define EMC_XM2VTTGENPADCTRL2 0x314
#define EMC_XM2VTTGENPADCTRL3 0x318
#define EMC_EMCPADEN 0x31c
#define EMC_XM2DQSPADCTRL4 0x320
#define EMC_SCRATCH0 0x324
#define EMC_DLL_XFORM_DQS0 0x328
#define EMC_DLL_XFORM_DQS1 0x32c
#define EMC_DLL_XFORM_DQS2 0x330
#define EMC_DLL_XFORM_DQS3 0x334
#define EMC_DLL_XFORM_DQS4 0x338
#define EMC_DLL_XFORM_DQS5 0x33c
#define EMC_DLL_XFORM_DQS6 0x340
#define EMC_DLL_XFORM_DQS7 0x344
#define EMC_DLL_XFORM_QUSE0 0x348
#define EMC_DLL_XFORM_QUSE1 0x34c
#define EMC_DLL_XFORM_QUSE2 0x350
#define EMC_DLL_XFORM_QUSE3 0x354
#define EMC_DLL_XFORM_QUSE4 0x358
#define EMC_DLL_XFORM_QUSE5 0x35c
#define EMC_DLL_XFORM_QUSE6 0x360
#define EMC_DLL_XFORM_QUSE7 0x364
#define EMC_DLL_XFORM_DQ0 0x368
#define EMC_DLL_XFORM_DQ1 0x36c
#define EMC_DLL_XFORM_DQ2 0x370
#define EMC_DLL_XFORM_DQ3 0x374
#define EMC_DLI_RX_TRIM0 0x378
#define EMC_DLI_RX_TRIM1 0x37c
#define EMC_DLI_RX_TRIM2 0x380
#define EMC_DLI_RX_TRIM3 0x384
#define EMC_DLI_RX_TRIM4 0x388
#define EMC_DLI_RX_TRIM5 0x38c
#define EMC_DLI_RX_TRIM6 0x390
#define EMC_DLI_RX_TRIM7 0x394
#define EMC_DLI_TX_TRIM0 0x398
#define EMC_DLI_TX_TRIM1 0x39c
#define EMC_DLI_TX_TRIM2 0x3a0
#define EMC_DLI_TX_TRIM3 0x3a4
#define EMC_DLI_TRIM_TXDQS0 0x3a8
#define EMC_DLI_TRIM_TXDQS1 0x3ac
#define EMC_DLI_TRIM_TXDQS2 0x3b0
#define EMC_DLI_TRIM_TXDQS3 0x3b4
#define EMC_DLI_TRIM_TXDQS4 0x3b8
#define EMC_DLI_TRIM_TXDQS5 0x3bc
#define EMC_DLI_TRIM_TXDQS6 0x3c0
#define EMC_DLI_TRIM_TXDQS7 0x3c4
#define EMC_STALL_THEN_EXE_AFTER_CLKCHANGE 0x3cc
#define EMC_AUTO_CAL_CLK_STATUS 0x3d4
#define EMC_SEL_DPD_CTRL 0x3d8
#define EMC_SEL_DPD_CTRL_DATA_SEL_DPD (0x1 << 8)
#define EMC_SEL_DPD_CTRL_ODT_SEL_DPD (0x1 << 5)
#define EMC_SEL_DPD_CTRL_RESET_SEL_DPD (0x1 << 4)
#define EMC_SEL_DPD_CTRL_CA_SEL_DPD (0x1 << 3)
#define EMC_SEL_DPD_CTRL_CLK_SEL_DPD (0x1 << 2)
#define EMC_SEL_DPD_CTRL_DDR3_MASK ((0xf << 2) | (0x1 << 8))
#define EMC_SEL_DPD_CTRL_MASK \
((0x3 << 2) | (0x1 << 5) | (0x1 << 8))
#define EMC_PRE_REFRESH_REQ_CNT 0x3dc
#define EMC_DYN_SELF_REF_CONTROL 0x3e0
#define EMC_TXSRDLL 0x3e4
#define EMC_CCFIFO_ADDR 0x3e8
#define EMC_CCFIFO_DATA 0x3ec
#define EMC_CCFIFO_STATUS 0x3f0
#define EMC_CDB_CNTL_1 0x3f4
#define EMC_CDB_CNTL_2 0x3f8
#define EMC_XM2CLKPADCTRL2 0x3fc
#define EMC_SWIZZLE_RANK0_BYTE_CFG 0x400
#define EMC_SWIZZLE_RANK0_BYTE0 0x404
#define EMC_SWIZZLE_RANK0_BYTE1 0x408
#define EMC_SWIZZLE_RANK0_BYTE2 0x40c
#define EMC_SWIZZLE_RANK0_BYTE3 0x410
#define EMC_SWIZZLE_RANK1_BYTE_CFG 0x414
#define EMC_SWIZZLE_RANK1_BYTE0 0x418
#define EMC_SWIZZLE_RANK1_BYTE1 0x41c
#define EMC_SWIZZLE_RANK1_BYTE2 0x420
#define EMC_SWIZZLE_RANK1_BYTE3 0x424
#define EMC_CA_TRAINING_START 0x428
#define EMC_CA_TRAINING_BUSY 0x42c
#define EMC_CA_TRAINING_CFG 0x430
#define EMC_CA_TRAINING_TIMING_CNTL1 0x434
#define EMC_CA_TRAINING_TIMING_CNTL2 0x438
#define EMC_CA_TRAINING_CA_LEAD_IN 0x43c
#define EMC_CA_TRAINING_CA 0x440
#define EMC_CA_TRAINING_CA_LEAD_OUT 0x444
#define EMC_CA_TRAINING_RESULT1 0x448
#define EMC_CA_TRAINING_RESULT2 0x44c
#define EMC_CA_TRAINING_RESULT3 0x450
#define EMC_CA_TRAINING_RESULT4 0x454
#define EMC_AUTO_CAL_CONFIG2 0x458
#define EMC_AUTO_CAL_CONFIG3 0x45c
#define EMC_AUTO_CAL_STATUS2 0x460
#define EMC_XM2CMDPADCTRL3 0x464
#define EMC_IBDLY 0x468
#define EMC_DLL_XFORM_ADDR0 0x46c
#define EMC_DLL_XFORM_ADDR1 0x470
#define EMC_DLL_XFORM_ADDR2 0x474
#define EMC_DLI_ADDR_TRIM 0x478
#define EMC_DSR_VTTGEN_DRV 0x47c
#define EMC_TXDSRVTTGEN 0x480
#define EMC_XM2CMDPADCTRL4 0x484
#define EMC_XM2CMDPADCTRL5 0x488
#define EMC_DLL_XFORM_DQS8 0x4a0
#define EMC_DLL_XFORM_DQS9 0x4a4
#define EMC_DLL_XFORM_DQS10 0x4a8
#define EMC_DLL_XFORM_DQS11 0x4ac
#define EMC_DLL_XFORM_DQS12 0x4b0
#define EMC_DLL_XFORM_DQS13 0x4b4
#define EMC_DLL_XFORM_DQS14 0x4b8
#define EMC_DLL_XFORM_DQS15 0x4bc
#define EMC_DLL_XFORM_QUSE8 0x4c0
#define EMC_DLL_XFORM_QUSE9 0x4c4
#define EMC_DLL_XFORM_QUSE10 0x4c8
#define EMC_DLL_XFORM_QUSE11 0x4cc
#define EMC_DLL_XFORM_QUSE12 0x4d0
#define EMC_DLL_XFORM_QUSE13 0x4d4
#define EMC_DLL_XFORM_QUSE14 0x4d8
#define EMC_DLL_XFORM_QUSE15 0x4dc
#define EMC_DLL_XFORM_DQ4 0x4e0
#define EMC_DLL_XFORM_DQ5 0x4e4
#define EMC_DLL_XFORM_DQ6 0x4e8
#define EMC_DLL_XFORM_DQ7 0x4ec
#define EMC_DLI_TRIM_TXDQS8 0x520
#define EMC_DLI_TRIM_TXDQS9 0x524
#define EMC_DLI_TRIM_TXDQS10 0x528
#define EMC_DLI_TRIM_TXDQS11 0x52c
#define EMC_DLI_TRIM_TXDQS12 0x530
#define EMC_DLI_TRIM_TXDQS13 0x534
#define EMC_DLI_TRIM_TXDQS14 0x538
#define EMC_DLI_TRIM_TXDQS15 0x53c
#define EMC_CDB_CNTL_3 0x540
#define EMC_XM2DQSPADCTRL5 0x544
#define EMC_XM2DQSPADCTRL6 0x548
#define EMC_XM2DQPADCTRL3 0x54c
#define EMC_DLL_XFORM_ADDR3 0x550
#define EMC_DLL_XFORM_ADDR4 0x554
#define EMC_DLL_XFORM_ADDR5 0x558
#define EMC_CFG_PIPE 0x560
#define EMC_QPOP 0x564
#define EMC_QUSE_WIDTH 0x568
#define EMC_PUTERM_WIDTH 0x56c
#define EMC_BGBIAS_CTL0 0x570
#define EMC_BGBIAS_CTL0_BIAS0_DSC_E_PWRD_IBIAS_RX (0x1 << 3)
#define EMC_BGBIAS_CTL0_BIAS0_DSC_E_PWRD_IBIAS_VTTGEN (0x1 << 2)
#define EMC_BGBIAS_CTL0_BIAS0_DSC_E_PWRD (0x1 << 1)
#define EMC_PUTERM_ADJ 0x574
#define MC_EMEM_CFG 0x50
#define MC_EMEM_ADR_CFG 0x54
#define MC_EMEM_ADR_CFG_DEV0 0x58
#define MC_EMEM_ADR_CFG_DEV1 0x5c
#define MC_EMEM_ADR_CFG_BANK_MASK_0 0x64
#define MC_EMEM_ADR_CFG_BANK_MASK_1 0x68
#define MC_EMEM_ADR_CFG_BANK_MASK_2 0x6c
#define MC_EMEM_ARB_CFG 0x90
#define MC_EMEM_ARB_OUTSTANDING_REQ 0x94
#define MC_EMEM_ARB_TIMING_RCD 0x98
#define MC_EMEM_ARB_TIMING_RP 0x9c
#define MC_EMEM_ARB_TIMING_RC 0xa0
#define MC_EMEM_ARB_TIMING_RAS 0xa4
#define MC_EMEM_ARB_TIMING_FAW 0xa8
#define MC_EMEM_ARB_TIMING_RRD 0xac
#define MC_EMEM_ARB_TIMING_RAP2PRE 0xb0
#define MC_EMEM_ARB_TIMING_WAP2PRE 0xb4
#define MC_EMEM_ARB_TIMING_R2R 0xb8
#define MC_EMEM_ARB_TIMING_W2W 0xbc
#define MC_EMEM_ARB_TIMING_R2W 0xc0
#define MC_EMEM_ARB_TIMING_W2R 0xc4
#define MC_EMEM_ARB_DA_TURNS 0xd0
#define MC_EMEM_ARB_DA_COVERS 0xd4
#define MC_EMEM_ARB_MISC0 0xd8
#define MC_EMEM_ARB_MISC0_EMC_SAME_FREQ (0x1 << 27)
#define MC_EMEM_ARB_MISC1 0xdc
#define MC_EMEM_ARB_RING1_THROTTLE 0xe0
#define MC_EMEM_ARB_RING3_THROTTLE 0xe4
#define MC_EMEM_ARB_OVERRIDE 0xe8
#define MC_EMEM_ARB_RSV 0xec
#define MC_CLKEN_OVERRIDE 0xf4
#define MC_TIMING_CONTROL_DBG 0xf8
#define MC_TIMING_CONTROL 0xfc
#define MC_EMEM_ARB_ISOCHRONOUS_0 0x208
#define MC_EMEM_ARB_ISOCHRONOUS_1 0x20c
#define MC_EMEM_ARB_ISOCHRONOUS_2 0x210
#define MC_DIS_EXTRA_SNAP_LEVELS 0x2ac
#define MC_LATENCY_ALLOWANCE_AFI_0 0x2e0
#define MC_LATENCY_ALLOWANCE_AVPC_0 0x2e4
#define MC_LATENCY_ALLOWANCE_DC_0 0x2e8
#define MC_LATENCY_ALLOWANCE_DC_1 0x2ec
#define MC_LATENCY_ALLOWANCE_DC_2 0x2f0
#define MC_LATENCY_ALLOWANCE_DCB_0 0x2f4
#define MC_LATENCY_ALLOWANCE_DCB_1 0x2f8
#define MC_LATENCY_ALLOWANCE_DCB_2 0x2fc
#define MC_LATENCY_ALLOWANCE_HC_0 0x310
#define MC_LATENCY_ALLOWANCE_HC_1 0x314
#define MC_LATENCY_ALLOWANCE_HDA_0 0x318
#define MC_LATENCY_ALLOWANCE_MPCORE_0 0x320
#define MC_LATENCY_ALLOWANCE_MPCORELP_0 0x324
#define MC_LATENCY_ALLOWANCE_MSENC_0 0x328
#define MC_LATENCY_ALLOWANCE_PPCS_0 0x344
#define MC_LATENCY_ALLOWANCE_PPCS_1 0x348
#define MC_LATENCY_ALLOWANCE_PTC_0 0x34c
#define MC_LATENCY_ALLOWANCE_SATA_0 0x350
#define MC_LATENCY_ALLOWANCE_VDE_0 0x354
#define MC_LATENCY_ALLOWANCE_VDE_1 0x358
#define MC_LATENCY_ALLOWANCE_VDE_2 0x35c
#define MC_LATENCY_ALLOWANCE_VDE_3 0x360
#define MC_LATENCY_ALLOWANCE_ISP2_0 0x370
#define MC_LATENCY_ALLOWANCE_ISP2_1 0x374
#define MC_LATENCY_ALLOWANCE_XUSB_0 0x37c
#define MC_LATENCY_ALLOWANCE_XUSB_1 0x380
#define MC_LATENCY_ALLOWANCE_ISP2B_0 0x384
#define MC_LATENCY_ALLOWANCE_ISP2B_1 0x388
#define MC_LATENCY_ALLOWANCE_TSEC_0 0x390
#define MC_LATENCY_ALLOWANCE_VIC_0 0x394
#define MC_LATENCY_ALLOWANCE_VI2_0 0x398
#define MC_LATENCY_ALLOWANCE_A9AVP_0 0x3a4
#define MC_LATENCY_ALLOWANCE_GPU_0 0x3ac
#define MC_LATENCY_ALLOWANCE_SDMMCA_0 0x3b8
#define MC_LATENCY_ALLOWANCE_SDMMCAA_0 0x3bc
#define MC_LATENCY_ALLOWANCE_SDMMC_0 0x3c0
#define MC_LATENCY_ALLOWANCE_SDMMCAB_0 0x3c4
#define MC_LATENCY_ALLOWANCE_DC_3 0x3c8
/* NOTE: this must match the # of MC_LATENCY_XXX above */
#define T12X_MC_LATENCY_ALLOWANCE_NUM_REGS 38
#define MC_VIDEO_PROTECT_VPR_OVERRIDE 0x418
#define MC_MLL_MPCORER_PTSA_RATE 0x44c
#define MC_VIDEO_PROTECT_BOM 0x648
#define MC_VIDEO_PROTECT_SIZE_MB 0x64c
#define MC_VIDEO_PROTECT_REG_CTRL 0x650
#define MC_SEC_CARVEOUT_BOM 0x670
#define MC_SEC_CARVEOUT_SIZE_MB 0x674
#define MC_SEC_CARVEOUT_REG_CTRL 0x678
#define MC_PTSA_GRANT_DECREMENT 0x960
#define MC_RESERVED_RSV 0x3fc
#define MC_RESERVED_RSV_1 0x958
#define MC_EMEM_ARB_OUTSTANDING_REQ_RING3 0x66c
#define MC_EMEM_ARB_OVERRIDE_1 0x968
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,198 @@
/*
* Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/of_address.h>
#include <linux/delay.h>
#include <linux/platform_data/tegra_mc.h>
#define DRV_NAME "tegra124-mc"
static void __iomem *tegra_mc_base;
static bool tegra_mc_init_done;
static BLOCKING_NOTIFIER_HEAD(tegra124_mc_notify_list);
#define MC_CLIENT_HOTRESET_CTRL 0x200
#define MC_CLIENT_HOTRESET_STAT 0x204
#define MC_CLIENT_HOTRESET_CTRL_1 0x970
#define MC_CLIENT_HOTRESET_STAT_1 0x974
#define MC_VIDEO_PROTECT_REG_CTRL 0x650
#define VIDEO_PROTECT_WRITE_ACCESS BIT(0)
static DEFINE_SPINLOCK(tegra_mc_lock);
u32 tegra124_mc_readl(u32 offs)
{
return readl(tegra_mc_base + offs);
}
EXPORT_SYMBOL(tegra124_mc_readl);
void tegra124_mc_writel(u32 val, u32 offs)
{
writel(val, tegra_mc_base + offs);
}
EXPORT_SYMBOL(tegra124_mc_writel);
int tegra124_mc_check_vpr(void)
{
u32 val;
val = readl(tegra_mc_base + MC_VIDEO_PROTECT_REG_CTRL);
if ((val & VIDEO_PROTECT_WRITE_ACCESS) == 0) {
WARN(1, "VPR configuration not locked down\n");
return -EINVAL;
}
return 0;
}
EXPORT_SYMBOL(tegra124_mc_check_vpr);
int tegra124_mc_register_notify(struct notifier_block *nb)
{
return blocking_notifier_chain_register(&tegra124_mc_notify_list, nb);
}
#define HOTRESET_READ_COUNT 5
static bool tegra_stable_hotreset_check(u32 stat_reg, u32 *stat)
{
int i;
u32 cur_stat;
u32 prv_stat;
unsigned long flags;
spin_lock_irqsave(&tegra_mc_lock, flags);
prv_stat = tegra124_mc_readl(stat_reg);
for (i = 0; i < HOTRESET_READ_COUNT; i++) {
cur_stat = tegra124_mc_readl(stat_reg);
if (cur_stat != prv_stat) {
spin_unlock_irqrestore(&tegra_mc_lock, flags);
return false;
}
}
*stat = cur_stat;
spin_unlock_irqrestore(&tegra_mc_lock, flags);
return true;
}
int tegra_mc_flush(int id)
{
u32 rst_ctrl, rst_stat;
u32 rst_ctrl_reg, rst_stat_reg;
unsigned long flags;
bool ret;
if (id < 32) {
rst_ctrl_reg = MC_CLIENT_HOTRESET_CTRL;
rst_stat_reg = MC_CLIENT_HOTRESET_STAT;
} else {
id %= 32;
rst_ctrl_reg = MC_CLIENT_HOTRESET_CTRL_1;
rst_stat_reg = MC_CLIENT_HOTRESET_STAT_1;
}
spin_lock_irqsave(&tegra_mc_lock, flags);
rst_ctrl = tegra124_mc_readl(rst_ctrl_reg);
rst_ctrl |= (1 << id);
tegra124_mc_writel(rst_ctrl, rst_ctrl_reg);
spin_unlock_irqrestore(&tegra_mc_lock, flags);
do {
udelay(10);
rst_stat = 0;
ret = tegra_stable_hotreset_check(rst_stat_reg, &rst_stat);
if (!ret)
continue;
} while (!(rst_stat & (1 << id)));
return 0;
}
EXPORT_SYMBOL(tegra_mc_flush);
int tegra_mc_flush_done(int id)
{
u32 rst_ctrl;
u32 rst_ctrl_reg, rst_stat_reg;
unsigned long flags;
if (id < 32) {
rst_ctrl_reg = MC_CLIENT_HOTRESET_CTRL;
rst_stat_reg = MC_CLIENT_HOTRESET_STAT;
} else {
id %= 32;
rst_ctrl_reg = MC_CLIENT_HOTRESET_CTRL_1;
rst_stat_reg = MC_CLIENT_HOTRESET_STAT_1;
}
spin_lock_irqsave(&tegra_mc_lock, flags);
rst_ctrl = tegra124_mc_readl(rst_ctrl_reg);
rst_ctrl &= ~(1 << id);
tegra124_mc_writel(rst_ctrl, rst_ctrl_reg);
spin_unlock_irqrestore(&tegra_mc_lock, flags);
return 0;
}
EXPORT_SYMBOL(tegra_mc_flush_done);
static int tegra124_mc_probe(struct platform_device *pdev)
{
tegra_mc_base = of_iomap(pdev->dev.of_node, 0);
if (tegra_mc_base)
tegra_mc_init_done = true;
/* Notify MC is ready. */
blocking_notifier_call_chain(&tegra124_mc_notify_list, 0, NULL);
return 0;
}
static const struct of_device_id tegra124_mc_of_match[] = {
{ .compatible = "nvidia,tegra124-mc", },
{},
};
static struct platform_driver tegra124_mc_driver = {
.probe = tegra124_mc_probe,
.driver = {
.name = DRV_NAME,
.owner = THIS_MODULE,
.of_match_table = tegra124_mc_of_match,
},
};
static int __init tegra124_mc_init(void)
{
return platform_driver_register(&tegra124_mc_driver);
}
arch_initcall(tegra124_mc_init);
static void __exit tegra124_mc_exit(void)
{
platform_driver_unregister(&tegra124_mc_driver);
}
module_exit(tegra124_mc_exit);
MODULE_DESCRIPTION("Tegra124 MC driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:" DRV_NAME);

254
drivers/memory/tegra20-mc.c Normal file
View File

@@ -0,0 +1,254 @@
/*
* Tegra20 Memory Controller
*
* Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/ratelimit.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#define DRV_NAME "tegra20-mc"
#define MC_INTSTATUS 0x0
#define MC_INTMASK 0x4
#define MC_INT_ERR_SHIFT 6
#define MC_INT_ERR_MASK (0x1f << MC_INT_ERR_SHIFT)
#define MC_INT_DECERR_EMEM BIT(MC_INT_ERR_SHIFT)
#define MC_INT_INVALID_GART_PAGE BIT(MC_INT_ERR_SHIFT + 1)
#define MC_INT_SECURITY_VIOLATION BIT(MC_INT_ERR_SHIFT + 2)
#define MC_INT_ARBITRATION_EMEM BIT(MC_INT_ERR_SHIFT + 3)
#define MC_GART_ERROR_REQ 0x30
#define MC_DECERR_EMEM_OTHERS_STATUS 0x58
#define MC_SECURITY_VIOLATION_STATUS 0x74
#define SECURITY_VIOLATION_TYPE BIT(30) /* 0=TRUSTZONE, 1=CARVEOUT */
#define MC_CLIENT_ID_MASK 0x3f
#define NUM_MC_REG_BANKS 2
struct tegra20_mc {
void __iomem *regs[NUM_MC_REG_BANKS];
struct device *dev;
};
static inline u32 mc_readl(struct tegra20_mc *mc, u32 offs)
{
u32 val = 0;
if (offs < 0x24)
val = readl(mc->regs[0] + offs);
else if (offs < 0x400)
val = readl(mc->regs[1] + offs - 0x3c);
return val;
}
static inline void mc_writel(struct tegra20_mc *mc, u32 val, u32 offs)
{
if (offs < 0x24)
writel(val, mc->regs[0] + offs);
else if (offs < 0x400)
writel(val, mc->regs[1] + offs - 0x3c);
}
static const char * const tegra20_mc_client[] = {
"cbr_display0a",
"cbr_display0ab",
"cbr_display0b",
"cbr_display0bb",
"cbr_display0c",
"cbr_display0cb",
"cbr_display1b",
"cbr_display1bb",
"cbr_eppup",
"cbr_g2pr",
"cbr_g2sr",
"cbr_mpeunifbr",
"cbr_viruv",
"csr_avpcarm7r",
"csr_displayhc",
"csr_displayhcb",
"csr_fdcdrd",
"csr_g2dr",
"csr_host1xdmar",
"csr_host1xr",
"csr_idxsrd",
"csr_mpcorer",
"csr_mpe_ipred",
"csr_mpeamemrd",
"csr_mpecsrd",
"csr_ppcsahbdmar",
"csr_ppcsahbslvr",
"csr_texsrd",
"csr_vdebsevr",
"csr_vdember",
"csr_vdemcer",
"csr_vdetper",
"cbw_eppu",
"cbw_eppv",
"cbw_eppy",
"cbw_mpeunifbw",
"cbw_viwsb",
"cbw_viwu",
"cbw_viwv",
"cbw_viwy",
"ccw_g2dw",
"csw_avpcarm7w",
"csw_fdcdwr",
"csw_host1xw",
"csw_ispw",
"csw_mpcorew",
"csw_mpecswr",
"csw_ppcsahbdmaw",
"csw_ppcsahbslvw",
"csw_vdebsevw",
"csw_vdembew",
"csw_vdetpmw",
};
static void tegra20_mc_decode(struct tegra20_mc *mc, int n)
{
u32 addr, req;
const char *client = "Unknown";
int idx, cid;
const struct reg_info {
u32 offset;
u32 write_bit; /* 0=READ, 1=WRITE */
int cid_shift;
char *message;
} reg[] = {
{
.offset = MC_DECERR_EMEM_OTHERS_STATUS,
.write_bit = 31,
.message = "MC_DECERR",
},
{
.offset = MC_GART_ERROR_REQ,
.cid_shift = 1,
.message = "MC_GART_ERR",
},
{
.offset = MC_SECURITY_VIOLATION_STATUS,
.write_bit = 31,
.message = "MC_SECURITY_ERR",
},
};
idx = n - MC_INT_ERR_SHIFT;
if ((idx < 0) || (idx >= ARRAY_SIZE(reg))) {
dev_err_ratelimited(mc->dev, "Unknown interrupt status %08lx\n",
BIT(n));
return;
}
req = mc_readl(mc, reg[idx].offset);
cid = (req >> reg[idx].cid_shift) & MC_CLIENT_ID_MASK;
if (cid < ARRAY_SIZE(tegra20_mc_client))
client = tegra20_mc_client[cid];
addr = mc_readl(mc, reg[idx].offset + sizeof(u32));
dev_err_ratelimited(mc->dev, "%s (0x%08x): 0x%08x %s (%s %s)\n",
reg[idx].message, req, addr, client,
(req & BIT(reg[idx].write_bit)) ? "write" : "read",
(reg[idx].offset == MC_SECURITY_VIOLATION_STATUS) ?
((req & SECURITY_VIOLATION_TYPE) ?
"carveout" : "trustzone") : "");
}
static const struct of_device_id tegra20_mc_of_match[] = {
{ .compatible = "nvidia,tegra20-mc", },
{},
};
static irqreturn_t tegra20_mc_isr(int irq, void *data)
{
u32 stat, mask, bit;
struct tegra20_mc *mc = data;
stat = mc_readl(mc, MC_INTSTATUS);
mask = mc_readl(mc, MC_INTMASK);
mask &= stat;
if (!mask)
return IRQ_NONE;
while ((bit = ffs(mask)) != 0)
tegra20_mc_decode(mc, bit - 1);
mc_writel(mc, stat, MC_INTSTATUS);
return IRQ_HANDLED;
}
static int tegra20_mc_probe(struct platform_device *pdev)
{
struct resource *irq;
struct tegra20_mc *mc;
int i, err;
u32 intmask;
mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL);
if (!mc)
return -ENOMEM;
mc->dev = &pdev->dev;
for (i = 0; i < ARRAY_SIZE(mc->regs); i++) {
struct resource *res;
res = platform_get_resource(pdev, IORESOURCE_MEM, i);
if (!res)
return -ENODEV;
mc->regs[i] = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(mc->regs[i]))
return PTR_ERR(mc->regs[i]);
}
irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!irq)
return -ENODEV;
err = devm_request_irq(&pdev->dev, irq->start, tegra20_mc_isr,
IRQF_SHARED, dev_name(&pdev->dev), mc);
if (err)
return -ENODEV;
platform_set_drvdata(pdev, mc);
intmask = MC_INT_INVALID_GART_PAGE |
MC_INT_DECERR_EMEM | MC_INT_SECURITY_VIOLATION;
mc_writel(mc, intmask, MC_INTMASK);
return 0;
}
static struct platform_driver tegra20_mc_driver = {
.probe = tegra20_mc_probe,
.driver = {
.name = DRV_NAME,
.owner = THIS_MODULE,
.of_match_table = tegra20_mc_of_match,
},
};
module_platform_driver(tegra20_mc_driver);
MODULE_AUTHOR("Hiroshi DOYU <hdoyu@nvidia.com>");
MODULE_DESCRIPTION("Tegra20 MC driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:" DRV_NAME);

377
drivers/memory/tegra30-mc.c Normal file
View File

@@ -0,0 +1,377 @@
/*
* Tegra30 Memory Controller
*
* Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/ratelimit.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#define DRV_NAME "tegra30-mc"
#define MC_INTSTATUS 0x0
#define MC_INTMASK 0x4
#define MC_INT_ERR_SHIFT 6
#define MC_INT_ERR_MASK (0x1f << MC_INT_ERR_SHIFT)
#define MC_INT_DECERR_EMEM BIT(MC_INT_ERR_SHIFT)
#define MC_INT_SECURITY_VIOLATION BIT(MC_INT_ERR_SHIFT + 2)
#define MC_INT_ARBITRATION_EMEM BIT(MC_INT_ERR_SHIFT + 3)
#define MC_INT_INVALID_SMMU_PAGE BIT(MC_INT_ERR_SHIFT + 4)
#define MC_ERR_STATUS 0x8
#define MC_ERR_ADR 0xc
#define MC_ERR_TYPE_SHIFT 28
#define MC_ERR_TYPE_MASK (7 << MC_ERR_TYPE_SHIFT)
#define MC_ERR_TYPE_DECERR_EMEM 2
#define MC_ERR_TYPE_SECURITY_TRUSTZONE 3
#define MC_ERR_TYPE_SECURITY_CARVEOUT 4
#define MC_ERR_TYPE_INVALID_SMMU_PAGE 6
#define MC_ERR_INVALID_SMMU_PAGE_SHIFT 25
#define MC_ERR_INVALID_SMMU_PAGE_MASK (7 << MC_ERR_INVALID_SMMU_PAGE_SHIFT)
#define MC_ERR_RW_SHIFT 16
#define MC_ERR_RW BIT(MC_ERR_RW_SHIFT)
#define MC_ERR_SECURITY BIT(MC_ERR_RW_SHIFT + 1)
#define SECURITY_VIOLATION_TYPE BIT(30) /* 0=TRUSTZONE, 1=CARVEOUT */
#define MC_EMEM_ARB_CFG 0x90
#define MC_EMEM_ARB_OUTSTANDING_REQ 0x94
#define MC_EMEM_ARB_TIMING_RCD 0x98
#define MC_EMEM_ARB_TIMING_RP 0x9c
#define MC_EMEM_ARB_TIMING_RC 0xa0
#define MC_EMEM_ARB_TIMING_RAS 0xa4
#define MC_EMEM_ARB_TIMING_FAW 0xa8
#define MC_EMEM_ARB_TIMING_RRD 0xac
#define MC_EMEM_ARB_TIMING_RAP2PRE 0xb0
#define MC_EMEM_ARB_TIMING_WAP2PRE 0xb4
#define MC_EMEM_ARB_TIMING_R2R 0xb8
#define MC_EMEM_ARB_TIMING_W2W 0xbc
#define MC_EMEM_ARB_TIMING_R2W 0xc0
#define MC_EMEM_ARB_TIMING_W2R 0xc4
#define MC_EMEM_ARB_DA_TURNS 0xd0
#define MC_EMEM_ARB_DA_COVERS 0xd4
#define MC_EMEM_ARB_MISC0 0xd8
#define MC_EMEM_ARB_MISC1 0xdc
#define MC_EMEM_ARB_RING3_THROTTLE 0xe4
#define MC_EMEM_ARB_OVERRIDE 0xe8
#define MC_TIMING_CONTROL 0xfc
#define MC_CLIENT_ID_MASK 0x7f
#define NUM_MC_REG_BANKS 4
struct tegra30_mc {
void __iomem *regs[NUM_MC_REG_BANKS];
struct device *dev;
u32 ctx[0];
};
static inline u32 mc_readl(struct tegra30_mc *mc, u32 offs)
{
u32 val = 0;
if (offs < 0x10)
val = readl(mc->regs[0] + offs);
else if (offs < 0x1f0)
val = readl(mc->regs[1] + offs - 0x3c);
else if (offs < 0x228)
val = readl(mc->regs[2] + offs - 0x200);
else if (offs < 0x400)
val = readl(mc->regs[3] + offs - 0x284);
return val;
}
static inline void mc_writel(struct tegra30_mc *mc, u32 val, u32 offs)
{
if (offs < 0x10)
writel(val, mc->regs[0] + offs);
else if (offs < 0x1f0)
writel(val, mc->regs[1] + offs - 0x3c);
else if (offs < 0x228)
writel(val, mc->regs[2] + offs - 0x200);
else if (offs < 0x400)
writel(val, mc->regs[3] + offs - 0x284);
}
static const char * const tegra30_mc_client[] = {
"csr_ptcr",
"cbr_display0a",
"cbr_display0ab",
"cbr_display0b",
"cbr_display0bb",
"cbr_display0c",
"cbr_display0cb",
"cbr_display1b",
"cbr_display1bb",
"cbr_eppup",
"cbr_g2pr",
"cbr_g2sr",
"cbr_mpeunifbr",
"cbr_viruv",
"csr_afir",
"csr_avpcarm7r",
"csr_displayhc",
"csr_displayhcb",
"csr_fdcdrd",
"csr_fdcdrd2",
"csr_g2dr",
"csr_hdar",
"csr_host1xdmar",
"csr_host1xr",
"csr_idxsrd",
"csr_idxsrd2",
"csr_mpe_ipred",
"csr_mpeamemrd",
"csr_mpecsrd",
"csr_ppcsahbdmar",
"csr_ppcsahbslvr",
"csr_satar",
"csr_texsrd",
"csr_texsrd2",
"csr_vdebsevr",
"csr_vdember",
"csr_vdemcer",
"csr_vdetper",
"csr_mpcorelpr",
"csr_mpcorer",
"cbw_eppu",
"cbw_eppv",
"cbw_eppy",
"cbw_mpeunifbw",
"cbw_viwsb",
"cbw_viwu",
"cbw_viwv",
"cbw_viwy",
"ccw_g2dw",
"csw_afiw",
"csw_avpcarm7w",
"csw_fdcdwr",
"csw_fdcdwr2",
"csw_hdaw",
"csw_host1xw",
"csw_ispw",
"csw_mpcorelpw",
"csw_mpcorew",
"csw_mpecswr",
"csw_ppcsahbdmaw",
"csw_ppcsahbslvw",
"csw_sataw",
"csw_vdebsevw",
"csw_vdedbgw",
"csw_vdembew",
"csw_vdetpmw",
};
static void tegra30_mc_decode(struct tegra30_mc *mc, int n)
{
u32 err, addr;
const char * const mc_int_err[] = {
"MC_DECERR",
"Unknown",
"MC_SECURITY_ERR",
"MC_ARBITRATION_EMEM",
"MC_SMMU_ERR",
};
const char * const err_type[] = {
"Unknown",
"Unknown",
"DECERR_EMEM",
"SECURITY_TRUSTZONE",
"SECURITY_CARVEOUT",
"Unknown",
"INVALID_SMMU_PAGE",
"Unknown",
};
char attr[6];
int cid, perm, type, idx;
const char *client = "Unknown";
idx = n - MC_INT_ERR_SHIFT;
if ((idx < 0) || (idx >= ARRAY_SIZE(mc_int_err)) || (idx == 1)) {
dev_err_ratelimited(mc->dev, "Unknown interrupt status %08lx\n",
BIT(n));
return;
}
err = readl(mc + MC_ERR_STATUS);
type = (err & MC_ERR_TYPE_MASK) >> MC_ERR_TYPE_SHIFT;
perm = (err & MC_ERR_INVALID_SMMU_PAGE_MASK) >>
MC_ERR_INVALID_SMMU_PAGE_SHIFT;
if (type == MC_ERR_TYPE_INVALID_SMMU_PAGE)
sprintf(attr, "%c-%c-%c",
(perm & BIT(2)) ? 'R' : '-',
(perm & BIT(1)) ? 'W' : '-',
(perm & BIT(0)) ? 'S' : '-');
else
attr[0] = '\0';
cid = err & MC_CLIENT_ID_MASK;
if (cid < ARRAY_SIZE(tegra30_mc_client))
client = tegra30_mc_client[cid];
addr = readl(mc + MC_ERR_ADR);
dev_err_ratelimited(mc->dev, "%s (0x%08x): 0x%08x %s (%s %s %s %s)\n",
mc_int_err[idx], err, addr, client,
(err & MC_ERR_SECURITY) ? "secure" : "non-secure",
(err & MC_ERR_RW) ? "write" : "read",
err_type[type], attr);
}
static const u32 tegra30_mc_ctx[] = {
MC_EMEM_ARB_CFG,
MC_EMEM_ARB_OUTSTANDING_REQ,
MC_EMEM_ARB_TIMING_RCD,
MC_EMEM_ARB_TIMING_RP,
MC_EMEM_ARB_TIMING_RC,
MC_EMEM_ARB_TIMING_RAS,
MC_EMEM_ARB_TIMING_FAW,
MC_EMEM_ARB_TIMING_RRD,
MC_EMEM_ARB_TIMING_RAP2PRE,
MC_EMEM_ARB_TIMING_WAP2PRE,
MC_EMEM_ARB_TIMING_R2R,
MC_EMEM_ARB_TIMING_W2W,
MC_EMEM_ARB_TIMING_R2W,
MC_EMEM_ARB_TIMING_W2R,
MC_EMEM_ARB_DA_TURNS,
MC_EMEM_ARB_DA_COVERS,
MC_EMEM_ARB_MISC0,
MC_EMEM_ARB_MISC1,
MC_EMEM_ARB_RING3_THROTTLE,
MC_EMEM_ARB_OVERRIDE,
MC_INTMASK,
};
#ifdef CONFIG_PM
static int tegra30_mc_suspend(struct device *dev)
{
int i;
struct tegra30_mc *mc = dev_get_drvdata(dev);
for (i = 0; i < ARRAY_SIZE(tegra30_mc_ctx); i++)
mc->ctx[i] = mc_readl(mc, tegra30_mc_ctx[i]);
return 0;
}
static int tegra30_mc_resume(struct device *dev)
{
int i;
struct tegra30_mc *mc = dev_get_drvdata(dev);
for (i = 0; i < ARRAY_SIZE(tegra30_mc_ctx); i++)
mc_writel(mc, mc->ctx[i], tegra30_mc_ctx[i]);
mc_writel(mc, 1, MC_TIMING_CONTROL);
/* Read-back to ensure that write reached */
mc_readl(mc, MC_TIMING_CONTROL);
return 0;
}
#endif
static UNIVERSAL_DEV_PM_OPS(tegra30_mc_pm,
tegra30_mc_suspend,
tegra30_mc_resume, NULL);
static const struct of_device_id tegra30_mc_of_match[] = {
{ .compatible = "nvidia,tegra30-mc", },
{},
};
static irqreturn_t tegra30_mc_isr(int irq, void *data)
{
u32 stat, mask, bit;
struct tegra30_mc *mc = data;
stat = mc_readl(mc, MC_INTSTATUS);
mask = mc_readl(mc, MC_INTMASK);
mask &= stat;
if (!mask)
return IRQ_NONE;
while ((bit = ffs(mask)) != 0)
tegra30_mc_decode(mc, bit - 1);
mc_writel(mc, stat, MC_INTSTATUS);
return IRQ_HANDLED;
}
static int tegra30_mc_probe(struct platform_device *pdev)
{
struct resource *irq;
struct tegra30_mc *mc;
size_t bytes;
int err, i;
u32 intmask;
bytes = sizeof(*mc) + sizeof(u32) * ARRAY_SIZE(tegra30_mc_ctx);
mc = devm_kzalloc(&pdev->dev, bytes, GFP_KERNEL);
if (!mc)
return -ENOMEM;
mc->dev = &pdev->dev;
for (i = 0; i < ARRAY_SIZE(mc->regs); i++) {
struct resource *res;
res = platform_get_resource(pdev, IORESOURCE_MEM, i);
if (!res)
return -ENODEV;
mc->regs[i] = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(mc->regs[i]))
return PTR_ERR(mc->regs[i]);
}
irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!irq)
return -ENODEV;
err = devm_request_irq(&pdev->dev, irq->start, tegra30_mc_isr,
IRQF_SHARED, dev_name(&pdev->dev), mc);
if (err)
return -ENODEV;
platform_set_drvdata(pdev, mc);
intmask = MC_INT_INVALID_SMMU_PAGE |
MC_INT_DECERR_EMEM | MC_INT_SECURITY_VIOLATION;
mc_writel(mc, intmask, MC_INTMASK);
return 0;
}
static struct platform_driver tegra30_mc_driver = {
.probe = tegra30_mc_probe,
.driver = {
.name = DRV_NAME,
.owner = THIS_MODULE,
.of_match_table = tegra30_mc_of_match,
.pm = &tegra30_mc_pm,
},
};
module_platform_driver(tegra30_mc_driver);
MODULE_AUTHOR("Hiroshi DOYU <hdoyu@nvidia.com>");
MODULE_DESCRIPTION("Tegra30 MC driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:" DRV_NAME);