drivers: ddr: Add DDR2 SDRAM controller driver for Microchip PIC32.
PATCH v2 5/13 drivers: ddr: Add DDR2 SDRAM controller driver for Microchip PIC32.
---
Changes in v2:
- move ddr2 initialization from board/microchip/ to drivers/ddr/microchip
arch/mips/mach-pic32/include/mach/ddr.h | 32 ++++ drivers/Makefile | 1 + drivers/ddr/microchip/Makefile | 6 + drivers/ddr/microchip/ddr2.c | 277 ++++++++++++++++++++++++++++++++ drivers/ddr/microchip/ddr2_regs.h | 151 +++++++++++++++++ drivers/ddr/microchip/ddr2_timing.h | 65 ++++++++ 6 files changed, 532 insertions(+) create mode 100644 arch/mips/mach-pic32/include/mach/ddr.h create mode 100644 drivers/ddr/microchip/Makefile create mode 100644 drivers/ddr/microchip/ddr2.c create mode 100644 drivers/ddr/microchip/ddr2_regs.h create mode 100644 drivers/ddr/microchip/ddr2_timing.h
arch/mips/mach-pic32/include/mach/ddr.h new file +32 -0
@@ -0,0 +1,32 @@ +/* +* (c) 2015 Purna Chandra Mandal <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +* +*/ + +#ifndef __MICROCHIP_PIC32_DDR_H +#define __MICROCHIP_PIC32_DDR_H + +/* called by initdram() function */ +void ddr2_phy_init (void ); +void ddr2_ctrl_init (void ); +phys_size_t ddr2_calculate_size (void ); + +/* Maximum number of agents */ +#define NUM_AGENTS 5 + +/* Board can provide agent specific parameters for arbitration by +* filling struct ddr2_arbiter_params for all the agents and +* implementing board_get_ddr_arbiter_params() to return the filled +* structure. +*/ +struct ddr2_arbiter_params { +u32 min_limit;/* min bursts to execute per arbitration */ +u32 req_period;/* request period threshold for accepted cmds */ +u32 min_cmd_acpt;/* min number of accepted cmds */ +}; + +struct ddr2_arbiter_params *board_get_ddr_arbiter_params (void ); + +#endif /* __MICROCHIP_PIC32_DDR_H */
drivers/Makefile +1 -0
@@ -68,4 +68,5 @@ obj-y += soc/ obj-$(CONFIG_REMOTEPROC) += remoteproc/ obj-y += thermal/ +obj-$(CONFIG_MACH_PIC32) += ddr/microchip/ endif
drivers/ddr/microchip/Makefile new file +6 -0
@@ -0,0 +1,6 @@ +# +# Copyright (C) 2015 Microchip Technology Inc. +# +# SPDX-License-Identifier: GPL-2.0+ +# +obj-$(CONFIG_MACH_PIC32) += ddr2.o
drivers/ddr/microchip/ddr2.c new file +277 -0
277 lines not on this page · raw message
drivers/ddr/microchip/ddr2_regs.h new file +151 -0
151 lines not on this page · raw message
drivers/ddr/microchip/ddr2_timing.h new file +65 -0
65 lines not on this page · raw message
Signature · 1 line
1.8.3.1
PATCH v2 5/13 drivers: ddr: Add DDR2 SDRAM controller driver for Microchip PIC32.
2016-01-04 15:01 GMT+01:00 Purna Chandra Mandal <[email protected]>:
Quoted 100 lines
Signed-off-by Paul Thacker <[email protected]>Signed-off-by Purna Chandra Mandal <[email protected]>---
Changes in v2:
- move ddr2 initialization from board/microchip/ todrivers/ddr/microchiparch/mips/mach-pic32/include/mach/ddr.h | 32 ++++ drivers/Makefile | 1 + drivers/ddr/microchip/Makefile | 6 + drivers/ddr/microchip/ddr2.c | 277 ++++++++++++++++++++++++++++++++ drivers/ddr/microchip/ddr2_regs.h | 151 +++++++++++++++++ drivers/ddr/microchip/ddr2_timing.h | 65 ++++++++ 6 files changed, 532 insertions(+) create mode 100644 arch/mips/mach-pic32/include/mach/ddr.h create mode 100644 drivers/ddr/microchip/Makefile create mode 100644 drivers/ddr/microchip/ddr2.c create mode 100644 drivers/ddr/microchip/ddr2_regs.h create mode 100644 drivers/ddr/microchip/ddr2_timing.harch/mips/mach-pic32/include/mach/ddr.h new file +32
-0@@ -0,0 +1,32 @@ +/* +* (c) 2015 Purna Chandra Mandal <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +* +*/ + +#ifndef __MICROCHIP_PIC32_DDR_H +#define __MICROCHIP_PIC32_DDR_H + +/* called by initdram() function */ +void ddr2_phy_init (void ); +void ddr2_ctrl_init (void ); +phys_size_t ddr2_calculate_size (void ); + +/* Maximum number of agents */ +#define NUM_AGENTS 5 + +/* Board can provide agent specific parameters for arbitration by +* filling struct ddr2_arbiter_params for all the agents and +* implementing board_get_ddr_arbiter_params() to return the filled +* structure. +*/ +struct ddr2_arbiter_params { +u32 min_limit;/* min bursts to execute per arbitration */ +u32 req_period;/* request period threshold for accepted cmds */ +u32 min_cmd_acpt;/* min number of accepted cmds */ +}; + +struct ddr2_arbiter_params *board_get_ddr_arbiter_params (void ); + +#endif /* __MICROCHIP_PIC32_DDR_H */ drivers/Makefile +1
-0@@ -68,4 +68,5 @@ obj-y += soc/ obj-$(CONFIG_REMOTEPROC) += remoteproc/ obj-y += thermal/ +obj-$(CONFIG_MACH_PIC32) += ddr/microchip/ endifdrivers/ddr/microchip/Makefile new file +6
-0@@ -0,0 +1,6 @@ +# +# Copyright (C) 2015 Microchip Technology Inc. +# +# SPDX-License-Identifier: GPL-2.0+ +# +obj-$(CONFIG_MACH_PIC32) += ddr2.odrivers/ddr/microchip/ddr2.c new file +13
-0@@ -0,0 +1,277 @@ +/* +* (c) 2015 Paul Thacker <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +* +*/ +#include <asm/io.h> +#include <config.h> +#include <wait_bit.h> +#include <linux/kernel.h> +#include <linux/bitops.h> +#include <mach/pic32.h> +#include <mach/ddr.h>
drivers/ddr/microchip/ddr2.c line 23
Quoted 10 lines
drivers/ddr/microchip/ddr2.c new file +10
-0+#include "ddr2_regs.h" +#include "ddr2_timing.h" + +/* init DDR2 Phy */ +void ddr2_phy_init (void ) +{ +struct ddr2_phy_regs *ddr2_phy; +u32 pad_ctl; + + ddr2_phy = (struct ddr2_phy_regs *)pic32_ioremap (PIC32_DDR2P_BASE );
an explicit cast from 'void *' is not needed
Quoted 21 lines
drivers/ddr/microchip/ddr2.c new file +21
-0+ +/* PHY_DLL_RECALIB */ +writel (DELAY_START_VAL (3 ) |DISABLE_RECALIB (0 ) | +RECALIB_CNT (0x10 ), &ddr2_phy->dll_recalib); + +/* PHY_PAD_CTRL */ + pad_ctl =ODT_SEL |ODT_EN |DRIVE_SEL (0 ) | +ODT_PULLDOWN (2 ) |ODT_PULLUP (3 ) | +EXTRA_OEN_CLK (0 ) |NOEXT_DLL | +DLR_DFT_WRCMD |HALF_RATE | +DRVSTR_PFET (0xe ) |DRVSTR_NFET (0xe ) | +RCVR_EN |PREAMBLE_DLY (2 ); +writel (pad_ctl, &ddr2_phy->pad_ctrl); + +/* SCL_CONFIG_0 */ +writel (SCL_BURST8 |SCL_DDR_CONNECTED |SCL_RCAS_LAT (RL ) | +SCL_ODTCSWW , &ddr2_phy->scl_config_1); + +/* SCL_CONFIG_1 */ +writel (SCL_CSEN |SCL_WCAS_LAT (WL ), &ddr2_phy->scl_config_2); +
drivers/ddr/microchip/ddr2.c line 54
Quoted 10 lines
drivers/ddr/microchip/ddr2.c new file +10
-0+/* SCL_LAT */ +writel (SCL_CAPCLKDLY (3 ) |SCL_DDRCLKDLY (4 ), &ddr2_phy->scl_latency); +} + +/* start phy self calibration logic */ +static int ddr2_phy_calib_start (void ) +{ +struct ddr2_phy_regs *ddr2_phy; + + ddr2_phy = (struct ddr2_phy_regs *)pic32_ioremap (PIC32_DDR2P_BASE );
an explicit cast from 'void *' is not needed
Quoted 4 lines
drivers/ddr/microchip/ddr2.c new file +4
-0+ +/* DDR Phy SCL Start */ +writel (SCL_START |SCL_EN , &ddr2_phy->scl_start); +
drivers/ddr/microchip/ddr2.c line 68
Quoted 10 lines
drivers/ddr/microchip/ddr2.c new file +10
-0+/* Wait for SCL for data byte to pass */ +return wait_for_bit (__func__, &ddr2_phy->scl_start,SCL_LUBPASS , + true,CONFIG_SYS_HZ , false); +} + +/* DDR2 Controller initialization */ + +/* Target Agent Arbiter */ +static void ddr_set_arbiter (struct ddr2_ctrl_regs *ctrl, +struct ddr2_arbiter_params *param)
*param should be const
Quoted 18 lines
drivers/ddr/microchip/ddr2.c new file +18
-0+{ +int i; + +for (i =0 ; i <NUM_AGENTS ; i++) { +/* set min burst size */ +writel (i *MIN_LIM_WIDTH , &ctrl->tsel); +writel (param->min_limit, &ctrl->minlim); + +/* set request period (4 * req_period clocks) */ +writel (i *RQST_PERIOD_WIDTH , &ctrl->tsel); +writel (param->req_period, &ctrl->reqprd); + +/* set number of burst accepted */ +writel (i *MIN_CMDACPT_WIDTH , &ctrl->tsel); +writel (param->min_cmd_acpt, &ctrl->mincmd); + } +} +
drivers/ddr/microchip/ddr2.c line 96
Quoted 10 lines
drivers/ddr/microchip/ddr2.c new file +10
-0+struct ddr2_arbiter_params *__weak board_get_ddr_arbiter_params (void ) +{ +/* default arbiter parameters */ +static struct ddr2_arbiter_params arb_params[] = { + { .min_limit =0x1f , .req_period =0xff , .min_cmd_acpt =0x04 ,}, + { .min_limit =0x1f , .req_period =0xff , .min_cmd_acpt =0x10 ,}, + { .min_limit =0x1f , .req_period =0xff , .min_cmd_acpt =0x10 ,}, + { .min_limit =0x04 , .req_period =0xff , .min_cmd_acpt =0x04 ,}, + { .min_limit =0x04 , .req_period =0xff , .min_cmd_acpt =0x04 ,}, + };
is that a constant table? If yes the declaration of the table and the return value of this function should be annotated with const
drivers/ddr/microchip/ddr2.c line 98
Quoted 2 lines
drivers/ddr/microchip/ddr2.c new file +2
-0+ +return (struct ddr2_arbiter_params *)arb_params;
the cast is not needed. To return the address of the first element:
return &arb_params[0];
Quoted 8 lines
drivers/ddr/microchip/ddr2.c new file +8
-0+} + +static void host_load_cmd (struct ddr2_ctrl_regs *ctrl,u32 offset, +u32 hostcmd2,u32 hostcmd1,u32 delay) +{ +u32 hc_delay; + + hc_delay =max_t (u32,DIV_ROUND_UP (delay, tCK),2 ) -2 ;
drivers/ddr/microchip/ddr2.c line 116
Quoted 10 lines
drivers/ddr/microchip/ddr2.c new file +10
-0+writel (hostcmd1, &ctrl->cmd10 + offset); +writel ((hostcmd2 &0x7ff ) | (hc_delay <<11 ), &ctrl->cmd20 + offset); +} + +/* init DDR2 Controller */ +void ddr2_ctrl_init (void ) +{ +u32 wr2prech, rd2prech, wr2rd, wr2rd_cs; +u32 ras2ras, ras2cas, prech2ras, temp; +struct ddr2_arbiter_params *arb_params;
as mentioned above, this pointer should be const
drivers/ddr/microchip/ddr2.c line 119
Quoted 3 lines
drivers/ddr/microchip/ddr2.c new file +3
-0+struct ddr2_ctrl_regs *ctrl; + + ctrl = (struct ddr2_ctrl_regs *)pic32_ioremap (PIC32_DDR2C_BASE );
an explicit cast from 'void *' is not needed
Quoted 354 lines
drivers/ddr/microchip/ddr2.c new file +158
-0+ +/* PIC32 DDR2 controller always work in HALF_RATE */ +writel (HALF_RATE_MODE , &ctrl->memwidth); + +/* Set arbiter configuration per target */ + arb_params =board_get_ddr_arbiter_params (); +ddr_set_arbiter (ctrl, arb_params); + +/* Address Configuration, model {CS, ROW, BA, COL} */ +writel ((ROW_ADDR_RSHIFT | (BA_RSHFT <<8 ) | (CS_ADDR_RSHIFT <<16 ) | + (COL_HI_RSHFT <<24 ) | (SB_PRI <<29 ) | + (EN_AUTO_PRECH <<30 )), &ctrl->memcfg0); + +writel (ROW_ADDR_MASK , &ctrl->memcfg1); +writel (COL_HI_MASK , &ctrl->memcfg2); +writel (COL_LO_MASK , &ctrl->memcfg3); +writel (BA_MASK | (CS_ADDR_MASK <<8 ), &ctrl->memcfg4); + +/* Refresh Config */ +writel (REFCNT_CLK (DIV_ROUND_UP (tRFI, tCK_CTRL) -2 ) | +REFDLY_CLK (DIV_ROUND_UP (tRFC_MIN, tCK_CTRL) -2 ) | +MAX_PEND_REF (7 ), + &ctrl->refcfg); + +/* Power Config */ +writel (ECC_EN (0 ) |ERR_CORR_EN (0 ) |EN_AUTO_PWR_DN (0 ) | +EN_AUTO_SELF_REF (3 ) |PWR_DN_DLY (8 ) | +SELF_REF_DLY (17 ) |PRECH_PWR_DN_ONLY (0 ), + &ctrl->pwrcfg); + +/* Delay Config */ + wr2rd =max_t (u32,DIV_ROUND_UP (tWTR, tCK_CTRL), +DIV_ROUND_UP (tWTR_TCK,2 )) +WL +BL ; + wr2rd_cs =max_t (u32, wr2rd -1 ,3 ); + wr2prech =DIV_ROUND_UP (tWR, tCK_CTRL) + (WL +BL ); + rd2prech =max_t (u32,DIV_ROUND_UP (tRTP, tCK_CTRL), +DIV_ROUND_UP (tRTP_TCK,2 )) +BL -2 ; + ras2ras =max_t (u32,DIV_ROUND_UP (tRRD, tCK_CTRL), +DIV_ROUND_UP (tRRD_TCK,2 )) -1 ; + ras2cas =DIV_ROUND_UP (tRCD, tCK_CTRL) -1 ; + prech2ras =DIV_ROUND_UP (tRP, tCK_CTRL) -1 ; + +writel (((wr2rd &0x0f ) | + ((wr2rd_cs &0x0f ) <<4 ) | + ((BL -1 ) <<8 ) | + (BL <<12 ) | + ((BL -1 ) <<16 ) | + ((BL -1 ) <<20 ) | + ((BL +2 ) <<24 ) | + ((RL -WL +3 ) <<28 )), &ctrl->dlycfg0); + +writel (((tCKE_TCK -1 ) | + (((DIV_ROUND_UP (tDLLK,2 ) -2 ) &0xff ) <<8 ) | + ((tCKE_TCK -1 ) <<16 ) | + ((max_t (u32, tXP_TCK, tCKE_TCK) -1 ) <<20 ) | + ((wr2prech >>4 ) <<26 ) | + ((wr2rd >>4 ) <<27 ) | + ((wr2rd_cs >>4 ) <<28 ) | + (((RL +5 ) >>4 ) <<29 ) | + ((DIV_ROUND_UP (tDLLK,2 ) >>8 ) <<30 )), &ctrl->dlycfg1); + +writel ((DIV_ROUND_UP (tRP, tCK_CTRL) | + (rd2prech <<8 ) | + ((wr2prech &0x0f ) <<12 ) | + (ras2ras <<16 ) | + (ras2cas <<20 ) | + (prech2ras <<24 ) | + ((RL +3 ) <<28 )), &ctrl->dlycfg2); + +writel (((DIV_ROUND_UP (tRAS_MIN, tCK_CTRL) -1 ) | + ((DIV_ROUND_UP (tRC, tCK_CTRL) -1 ) <<8 ) | + ((DIV_ROUND_UP (tFAW, tCK_CTRL) -1 ) <<16 )), + &ctrl->dlycfg3); + +/* ODT Config */ +writel (0x0 , &ctrl->odtcfg); +writel (BIT (16 ), &ctrl->odtencfg); +writel (ODTRDLY (RL -3 ) |ODTWDLY (WL -3 ) |ODTRLEN (2 ) |ODTWLEN (3 ), + &ctrl->odtcfg); + +/* Transfer Configuration */ +writel (NXTDATRQDLY (2 ) |NXDATAVDLY (4 ) |RDATENDLY (2 ) | +MAX_BURST (3 ) | (7 <<28 ) |BIG_ENDIAN (0 ), + &ctrl->xfercfg); + +/* DRAM Initialization */ +/* CKE high after reset and wait 400 nsec */ +host_load_cmd (ctrl,0 ,0 ,IDLE_NOP ,400000 ); + +/* issue precharge all command */ +host_load_cmd (ctrl,4 ,0x04 ,PRECH_ALL_CMD , tRP + tCK); + +/* initialize EMR2 */ +host_load_cmd (ctrl,8 ,0x200 ,LOAD_MODE_CMD , tMRD_TCK * tCK); + +/* initialize EMR3 */ +host_load_cmd (ctrl,0xc ,0x300 ,LOAD_MODE_CMD , tMRD_TCK * tCK); + +/* +* RDQS disable, DQSB enable, OCD exit, 150 ohm termination, +* AL=0, DLL enable +*/ +host_load_cmd (ctrl,0x10 ,0x100 , +LOAD_MODE_CMD | (0x40 <<24 ), tMRD_TCK * tCK); +/* +* PD fast exit, WR REC = tWR in clocks -1, +* DLL reset, CAS = RL, burst = 4 +*/ + temp = ((DIV_ROUND_UP (tWR, tCK) -1 ) <<1 ) |1 ; +host_load_cmd (ctrl,0x14 , temp,LOAD_MODE_CMD | (RL <<28 ) | (2 <<24 ), + tMRD_TCK * tCK); + +/* issue precharge all command */ +host_load_cmd (ctrl,0x18 ,4 ,PRECH_ALL_CMD , tRP + tCK); + +/* issue refresh command */ +host_load_cmd (ctrl,0x1c ,0 ,REF_CMD , tRFC_MIN); + +/* issue refresh command */ +host_load_cmd (ctrl,0x20 ,0 ,REF_CMD , tRFC_MIN); + +/* Mode register programming as before without DLL reset */ +host_load_cmd (ctrl,0x24 , temp,LOAD_MODE_CMD | (RL <<28 ) | (3 <<24 ), + tMRD_TCK * tCK); + +/* extended mode register same as before with OCD default */ +host_load_cmd (ctrl,0x28 ,0x103 ,LOAD_MODE_CMD | (0xc <<24 ), + tMRD_TCK * tCK); + +/* extended mode register same as before with OCD exit */ +host_load_cmd (ctrl,0x2c ,0x100 ,LOAD_MODE_CMD | (0x4 <<28 ), +140 * tCK); + +writel (CMD_VALID |NUMHOSTCMD (11 ), &ctrl->cmdissue); + +/* start memory initialization */ +writel (INIT_START , &ctrl->memcon); + +/* wait for all host cmds to be transmitted */ +wait_for_bit (__func__, &ctrl->cmdissue,CMD_VALID , false, +CONFIG_SYS_HZ , false); + +/* inform all cmds issued, ready for normal operation */ +writel (INIT_START |INIT_DONE , &ctrl->memcon); + +/* perform phy caliberation */ +ddr2_phy_calib_start (); +} + +phys_size_t ddr2_calculate_size (void ) +{ +u32 temp; + + temp =1 << (COL_BITS +BA_BITS +ROW_BITS ); +/* 16-bit data width between controller and DIMM */ + temp = temp *CS_BITS * (16 /8 ); +return (phys_size_t )temp; +}drivers/ddr/microchip/ddr2_regs.h new file +151
-0@@ -0,0 +1,151 @@ +/* +* (c) 2015 Purna Chandra Mandal <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +* +*/ + +#ifndef __MICROCHIP_DDR2_REGS_H +#define __MICROCHIP_DDR2_REGS_H + +#include <config.h> +#include <linux/bitops.h> + +/* DDR2 Controller */ +struct ddr2_ctrl_regs { +u32 tsel; +u32 minlim; +u32 reqprd; +u32 mincmd; +u32 memcon; +u32 memcfg0; +u32 memcfg1; +u32 memcfg2; +u32 memcfg3; +u32 memcfg4; +u32 refcfg; +u32 pwrcfg; +u32 dlycfg0; +u32 dlycfg1; +u32 dlycfg2; +u32 dlycfg3; +u32 odtcfg; +u32 xfercfg; +u32 cmdissue; +u32 odtencfg; +u32 memwidth; +u32 unused[11 ]; +u32 cmd10; +u32 othercmd10[15 ]; +u32 cmd20; +u32 othercmd20[15 ]; +}; + +/* Arbiter Config */ +#define MIN_LIM_WIDTH 5 +#define RQST_PERIOD_WIDTH 8 +#define MIN_CMDACPT_WIDTH 8 + +/* Refresh Config */ +#define REFCNT_CLK (x) (x) +#define REFDLY_CLK (x) ((x) << 16) +#define MAX_PEND_REF (x) ((x) << 24) + +/* Power Config */ +#define PRECH_PWR_DN_ONLY (x) ((x) << 22) +#define SELF_REF_DLY (x) ((x) << 12) +#define PWR_DN_DLY (x) ((x) << 4) +#define EN_AUTO_SELF_REF (x) ((x) << 3) +#define EN_AUTO_PWR_DN (x) ((x) << 2) +#define ERR_CORR_EN (x) ((x) << 1) +#define ECC_EN (x) (x) + +/* Memory Width */ +#define HALF_RATE_MODE BIT(3) + +/* Delay Config */ +#define ODTWLEN (x) ((x) << 20) +#define ODTRLEN (x) ((x) << 16) +#define ODTWDLY (x) ((x) << 12) +#define ODTRDLY (x) ((x) << 8) + +/* Xfer Config */ +#define BIG_ENDIAN (x) ((x) << 31) +#define MAX_BURST (x) ((x) << 24) +#define RDATENDLY (x) ((x) << 16) +#define NXDATAVDLY (x) ((x) << 4) +#define NXTDATRQDLY (x) ((x) << 0) + +/* Host Commands */ +#define IDLE_NOP 0x00ffffff +#define PRECH_ALL_CMD 0x00fff401 +#define REF_CMD 0x00fff801 +#define LOAD_MODE_CMD 0x00fff001 +#define CKE_LOW 0x00ffeffe + +#define NUM_HOST_CMDS 12 + +/* Host CMD Issue */ +#define CMD_VALID BIT(4) +#define NUMHOSTCMD (x) (x) + +/* Memory Control */ +#define INIT_DONE BIT(1) +#define INIT_START BIT(0) + +/* Address Control */ +#define EN_AUTO_PRECH 0 +#define SB_PRI 1 + +/* DDR2 Phy Register */ +struct ddr2_phy_regs { +u32 scl_start; +u32 unused1[2 ]; +u32 scl_latency; +u32 unused2[2 ]; +u32 scl_config_1; +u32 scl_config_2; +u32 pad_ctrl; +u32 dll_recalib; +}; + +/* PHY PAD CONTROL */ +#define ODT_SEL BIT(0) +#define ODT_EN BIT(1) +#define DRIVE_SEL (x) ((x) << 2) +#define ODT_PULLDOWN (x) ((x) << 4) +#define ODT_PULLUP (x) ((x) << 6) +#define EXTRA_OEN_CLK (x) ((x) << 8) +#define NOEXT_DLL BIT(9) +#define DLR_DFT_WRCMD BIT(13) +#define HALF_RATE BIT(14) +#define DRVSTR_PFET (x) ((x) << 16) +#define DRVSTR_NFET (x) ((x) << 20) +#define RCVR_EN BIT(28) +#define PREAMBLE_DLY (x) ((x) << 29) + +/* PHY DLL RECALIBRATE */ +#define RECALIB_CNT (x) ((x) << 8) +#define DISABLE_RECALIB (x) ((x) << 26) +#define DELAY_START_VAL (x) ((x) << 28) + +/* PHY SCL CONFIG1 */ +#define SCL_BURST8 BIT(0) +#define SCL_DDR_CONNECTED BIT(1) +#define SCL_RCAS_LAT (x) ((x) << 4) +#define SCL_ODTCSWW BIT(24) + +/* PHY SCL CONFIG2 */ +#define SCL_CSEN BIT(0) +#define SCL_WCAS_LAT (x) ((x) << 8) + +/* PHY SCL Latency */ +#define SCL_CAPCLKDLY (x) ((x) << 0) +#define SCL_DDRCLKDLY (x) ((x) << 4) + +/* PHY SCL START */ +#define SCL_START BIT(28) +#define SCL_EN BIT(26) +#define SCL_LUBPASS (BIT(1) | BIT(0)) + +#endif /* __MICROCHIP_DDR2_REGS_H */ drivers/ddr/microchip/ddr2_timing.h new file +33
-0@@ -0,0 +1,65 @@ +/* +* (c) 2015 Purna Chandra Mandal <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +* +*/ + +#ifndef __MICROCHIP_DDR2_TIMING_H +#define __MICROCHIP_DDR2_TIMING_H + +/* MPLL freq is 400MHz */ +#define tCK 2500/* 2500 psec */ +#define tCK_CTRL (tCK * 2) + +/* Burst length in cycles */ +#define BL 2 +/* default CAS latency for all speed grades */ +#define RL 5 +/* default write latency for all speed grades = CL-1 */ +#define WL 4 + +/* From Micron MT47H64M16HR-3 data sheet */ +#define tRFC_MIN 127500/* psec */ +#define tWR 15000/* psec */ +#define tRP 12500/* psec */ +#define tRCD 12500/* psec */ +#define tRRD 7500/* psec */ +/* tRRD_TCK is minimum of 2 clk periods, regardless of freq */ +#define tRRD_TCK 2 +#define tWTR 7500/* psec */ +/* tWTR_TCK is minimum of 2 clk periods, regardless of freq */ +#define tWTR_TCK 2 +#define tRTP 7500/* psec */
drivers/ddr/microchip/ddr2_timing.h line 43
Quoted 10 lines
drivers/ddr/microchip/ddr2_timing.h new file +10
-0+#define tRTP_TCK (BL / 2) +#define tXP_TCK 2/* clocks */ +#define tCKE_TCK 3/* clocks */ +#define tXSNR (tRFC_MIN + 10000)/* psec */ +#define tDLLK 200/* clocks */ +#define tRAS_MIN 45000/* psec */ +#define tRC 57500/* psec */ +#define tFAW 35000/* psec */ +#define tMRD_TCK 2/* clocks */ +#define tRFI 7800000/* psec */
please avoid CamelCase. This should be renamed to something like this:
#define T_RFC_MIN
#define T_WR
Quoted 26 lines
drivers/ddr/microchip/ddr2_timing.h new file +22
-1+ +/* DDR Addressing */ +#define COL_BITS 10 +#define BA_BITS 3 +#define ROW_BITS 13 +#define CS_BITS 1 + +/* DDR Addressing scheme: {CS, ROW, BA, COL} */ +#define COL_HI_RSHFT 0 +#define COL_HI_MASK 0 +#define COL_LO_MASK ((1 << COL_BITS) - 1) + +#define BA_RSHFT COL_BITS +#define BA_MASK ((1 << BA_BITS) - 1) + +#define ROW_ADDR_RSHIFT (BA_RSHFT + BA_BITS) +#define ROW_ADDR_MASK ((1 << ROW_BITS) - 1) + +#define CS_ADDR_RSHIFT 0 +#define CS_ADDR_MASK 0 + +#endif /* __MICROCHIP_DDR2_TIMING_H */ --1.8.3.1
Signature · 1 line
- Daniel
PATCH v2 5/13 drivers: ddr: Add DDR2 SDRAM controller driver for Microchip PIC32.
On 01/06/2016 12:32 AM, Daniel Schwierzeck wrote:
[...]
Quoted 25 lines
+++
b/drivers/ddr/microchip/ddr2.cdrivers/ddr/microchip/ddr2.c new file +23
-0@@ -0,0 +1,277 @@ +/* +* (c) 2015 Paul Thacker <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +* +*/ +#include <asm/io.h> +#include <config.h> +#include <wait_bit.h> +#include <linux/kernel.h> +#include <linux/bitops.h> +#include <mach/pic32.h> +#include <mach/ddr.h> +#include "ddr2_regs.h" +#include "ddr2_timing.h" + +/* init DDR2 Phy */ +void ddr2_phy_init (void ) +{ +struct ddr2_phy_regs *ddr2_phy; +u32 pad_ctl; + + ddr2_phy = (struct ddr2_phy_regs *)pic32_ioremap (PIC32_DDR2P_BASE );
Quoted 1 line
an explicit cast from 'void *' is not needed
ack. Will remove.
Quoted 24 lines
Quoted 24 lines
drivers/ddr/microchip/ddr2.c new file +24
-0+ +/* PHY_DLL_RECALIB */ +writel (DELAY_START_VAL (3 ) |DISABLE_RECALIB (0 ) | +RECALIB_CNT (0x10 ), &ddr2_phy->dll_recalib); + +/* PHY_PAD_CTRL */ + pad_ctl =ODT_SEL |ODT_EN |DRIVE_SEL (0 ) | +ODT_PULLDOWN (2 ) |ODT_PULLUP (3 ) | +EXTRA_OEN_CLK (0 ) |NOEXT_DLL | +DLR_DFT_WRCMD |HALF_RATE | +DRVSTR_PFET (0xe ) |DRVSTR_NFET (0xe ) | +RCVR_EN |PREAMBLE_DLY (2 ); +writel (pad_ctl, &ddr2_phy->pad_ctrl); + +/* SCL_CONFIG_0 */ +writel (SCL_BURST8 |SCL_DDR_CONNECTED |SCL_RCAS_LAT (RL ) | +SCL_ODTCSWW , &ddr2_phy->scl_config_1); + +/* SCL_CONFIG_1 */ +writel (SCL_CSEN |SCL_WCAS_LAT (WL ), &ddr2_phy->scl_config_2); + +/* SCL_LAT */ +writel (SCL_CAPCLKDLY (3 ) |SCL_DDRCLKDLY (4 ), &ddr2_phy->scl_latency); +}
Quoted 8 lines
drivers/ddr/microchip/ddr2.c line 54
Quoted 7 lines
drivers/ddr/microchip/ddr2.c new file +7
-0+ +/* start phy self calibration logic */ +static int ddr2_phy_calib_start (void ) +{ +struct ddr2_phy_regs *ddr2_phy; + + ddr2_phy = (struct ddr2_phy_regs *)pic32_ioremap (PIC32_DDR2P_BASE );an explicit cast from 'void *' is not needed
ack.
Quoted 7 lines
Quoted 7 lines
drivers/ddr/microchip/ddr2.c new file +7
-0+ +/* DDR Phy SCL Start */ +writel (SCL_START |SCL_EN , &ddr2_phy->scl_start); + +/* Wait for SCL for data byte to pass */ +return wait_for_bit (__func__, &ddr2_phy->scl_start,SCL_LUBPASS , + true,CONFIG_SYS_HZ , false);
Quoted 8 lines
drivers/ddr/microchip/ddr2.c line 68
Quoted 7 lines
drivers/ddr/microchip/ddr2.c new file +7
-0+} + +/* DDR2 Controller initialization */ + +/* Target Agent Arbiter */ +static void ddr_set_arbiter (struct ddr2_ctrl_regs *ctrl, +struct ddr2_arbiter_params *param)*param should be const
ack.
Quoted 22 lines
Quoted 22 lines
drivers/ddr/microchip/ddr2.c new file +22
-0+{ +int i; + +for (i =0 ; i <NUM_AGENTS ; i++) { +/* set min burst size */ +writel (i *MIN_LIM_WIDTH , &ctrl->tsel); +writel (param->min_limit, &ctrl->minlim); + +/* set request period (4 * req_period clocks) */ +writel (i *RQST_PERIOD_WIDTH , &ctrl->tsel); +writel (param->req_period, &ctrl->reqprd); + +/* set number of burst accepted */ +writel (i *MIN_CMDACPT_WIDTH , &ctrl->tsel); +writel (param->min_cmd_acpt, &ctrl->mincmd); + } +} + +struct ddr2_arbiter_params *__weak board_get_ddr_arbiter_params (void ) +{ +/* default arbiter parameters */ +static struct ddr2_arbiter_params arb_params[] = {
Quoted 8 lines
drivers/ddr/microchip/ddr2.c line 96
Quoted 6 lines
drivers/ddr/microchip/ddr2.c new file +6
-0+ { .min_limit = 0x1f, .req_period = 0xff, .min_cmd_acpt = 0x04,}, + { .min_limit = 0x1f, .req_period = 0xff, .min_cmd_acpt = 0x10,}, + { .min_limit = 0x1f, .req_period = 0xff, .min_cmd_acpt = 0x10,}, + { .min_limit = 0x04, .req_period = 0xff, .min_cmd_acpt = 0x04,}, + { .min_limit = 0x04, .req_period = 0xff, .min_cmd_acpt = 0x04,}, + };is that a constant table? If yes the declaration of the table and the return value of this function should be annotated with const
Yes, it is constant table. will annotate accordingly.
Quoted 5 lines
Review
Quoted 2 lines
(quoted diff) +2
-0+ + return (struct ddr2_arbiter_params *)arb_params;the cast is not needed. To return the address of the first element:
return &arb_params[0];
ack.
Quoted 11 lines
Quoted 11 lines
drivers/ddr/microchip/ddr2.c new file +11
-0+} + +static void host_load_cmd (struct ddr2_ctrl_regs *ctrl,u32 offset, +u32 hostcmd2,u32 hostcmd1,u32 delay) +{ +u32 hc_delay; + + hc_delay =max_t (u32,DIV_ROUND_UP (delay, tCK),2 ) -2 ; +writel (hostcmd1, &ctrl->cmd10 + offset); +writel ((hostcmd2 &0x7ff ) | (hc_delay <<11 ), &ctrl->cmd20 + offset); +}
Quoted 8 lines
drivers/ddr/microchip/ddr2.c line 116
Quoted 7 lines
drivers/ddr/microchip/ddr2.c new file +7
-0+ +/* init DDR2 Controller */ +void ddr2_ctrl_init (void ) +{ +u32 wr2prech, rd2prech, wr2rd, wr2rd_cs; +u32 ras2ras, ras2cas, prech2ras, temp; +struct ddr2_arbiter_params *arb_params;as mentioned above, this pointer should be const
ack.
Quoted 4 lines
drivers/ddr/microchip/ddr2.c line 119
Quoted 3 lines
drivers/ddr/microchip/ddr2.c new file +3
-0+struct ddr2_ctrl_regs *ctrl; + + ctrl = (struct ddr2_ctrl_regs *)pic32_ioremap (PIC32_DDR2C_BASE );an explicit cast from 'void *' is not needed
ack.
Quoted 366 lines
Quoted 354 lines
drivers/ddr/microchip/ddr2.c new file +158
-0+ +/* PIC32 DDR2 controller always work in HALF_RATE */ +writel (HALF_RATE_MODE , &ctrl->memwidth); + +/* Set arbiter configuration per target */ + arb_params =board_get_ddr_arbiter_params (); +ddr_set_arbiter (ctrl, arb_params); + +/* Address Configuration, model {CS, ROW, BA, COL} */ +writel ((ROW_ADDR_RSHIFT | (BA_RSHFT <<8 ) | (CS_ADDR_RSHIFT <<16 ) | + (COL_HI_RSHFT <<24 ) | (SB_PRI <<29 ) | + (EN_AUTO_PRECH <<30 )), &ctrl->memcfg0); + +writel (ROW_ADDR_MASK , &ctrl->memcfg1); +writel (COL_HI_MASK , &ctrl->memcfg2); +writel (COL_LO_MASK , &ctrl->memcfg3); +writel (BA_MASK | (CS_ADDR_MASK <<8 ), &ctrl->memcfg4); + +/* Refresh Config */ +writel (REFCNT_CLK (DIV_ROUND_UP (tRFI, tCK_CTRL) -2 ) | +REFDLY_CLK (DIV_ROUND_UP (tRFC_MIN, tCK_CTRL) -2 ) | +MAX_PEND_REF (7 ), + &ctrl->refcfg); + +/* Power Config */ +writel (ECC_EN (0 ) |ERR_CORR_EN (0 ) |EN_AUTO_PWR_DN (0 ) | +EN_AUTO_SELF_REF (3 ) |PWR_DN_DLY (8 ) | +SELF_REF_DLY (17 ) |PRECH_PWR_DN_ONLY (0 ), + &ctrl->pwrcfg); + +/* Delay Config */ + wr2rd =max_t (u32,DIV_ROUND_UP (tWTR, tCK_CTRL), +DIV_ROUND_UP (tWTR_TCK,2 )) +WL +BL ; + wr2rd_cs =max_t (u32, wr2rd -1 ,3 ); + wr2prech =DIV_ROUND_UP (tWR, tCK_CTRL) + (WL +BL ); + rd2prech =max_t (u32,DIV_ROUND_UP (tRTP, tCK_CTRL), +DIV_ROUND_UP (tRTP_TCK,2 )) +BL -2 ; + ras2ras =max_t (u32,DIV_ROUND_UP (tRRD, tCK_CTRL), +DIV_ROUND_UP (tRRD_TCK,2 )) -1 ; + ras2cas =DIV_ROUND_UP (tRCD, tCK_CTRL) -1 ; + prech2ras =DIV_ROUND_UP (tRP, tCK_CTRL) -1 ; + +writel (((wr2rd &0x0f ) | + ((wr2rd_cs &0x0f ) <<4 ) | + ((BL -1 ) <<8 ) | + (BL <<12 ) | + ((BL -1 ) <<16 ) | + ((BL -1 ) <<20 ) | + ((BL +2 ) <<24 ) | + ((RL -WL +3 ) <<28 )), &ctrl->dlycfg0); + +writel (((tCKE_TCK -1 ) | + (((DIV_ROUND_UP (tDLLK,2 ) -2 ) &0xff ) <<8 ) | + ((tCKE_TCK -1 ) <<16 ) | + ((max_t (u32, tXP_TCK, tCKE_TCK) -1 ) <<20 ) | + ((wr2prech >>4 ) <<26 ) | + ((wr2rd >>4 ) <<27 ) | + ((wr2rd_cs >>4 ) <<28 ) | + (((RL +5 ) >>4 ) <<29 ) | + ((DIV_ROUND_UP (tDLLK,2 ) >>8 ) <<30 )), &ctrl->dlycfg1); + +writel ((DIV_ROUND_UP (tRP, tCK_CTRL) | + (rd2prech <<8 ) | + ((wr2prech &0x0f ) <<12 ) | + (ras2ras <<16 ) | + (ras2cas <<20 ) | + (prech2ras <<24 ) | + ((RL +3 ) <<28 )), &ctrl->dlycfg2); + +writel (((DIV_ROUND_UP (tRAS_MIN, tCK_CTRL) -1 ) | + ((DIV_ROUND_UP (tRC, tCK_CTRL) -1 ) <<8 ) | + ((DIV_ROUND_UP (tFAW, tCK_CTRL) -1 ) <<16 )), + &ctrl->dlycfg3); + +/* ODT Config */ +writel (0x0 , &ctrl->odtcfg); +writel (BIT (16 ), &ctrl->odtencfg); +writel (ODTRDLY (RL -3 ) |ODTWDLY (WL -3 ) |ODTRLEN (2 ) |ODTWLEN (3 ), + &ctrl->odtcfg); + +/* Transfer Configuration */ +writel (NXTDATRQDLY (2 ) |NXDATAVDLY (4 ) |RDATENDLY (2 ) | +MAX_BURST (3 ) | (7 <<28 ) |BIG_ENDIAN (0 ), + &ctrl->xfercfg); + +/* DRAM Initialization */ +/* CKE high after reset and wait 400 nsec */ +host_load_cmd (ctrl,0 ,0 ,IDLE_NOP ,400000 ); + +/* issue precharge all command */ +host_load_cmd (ctrl,4 ,0x04 ,PRECH_ALL_CMD , tRP + tCK); + +/* initialize EMR2 */ +host_load_cmd (ctrl,8 ,0x200 ,LOAD_MODE_CMD , tMRD_TCK * tCK); + +/* initialize EMR3 */ +host_load_cmd (ctrl,0xc ,0x300 ,LOAD_MODE_CMD , tMRD_TCK * tCK); + +/* +* RDQS disable, DQSB enable, OCD exit, 150 ohm termination, +* AL=0, DLL enable +*/ +host_load_cmd (ctrl,0x10 ,0x100 , +LOAD_MODE_CMD | (0x40 <<24 ), tMRD_TCK * tCK); +/* +* PD fast exit, WR REC = tWR in clocks -1, +* DLL reset, CAS = RL, burst = 4 +*/ + temp = ((DIV_ROUND_UP (tWR, tCK) -1 ) <<1 ) |1 ; +host_load_cmd (ctrl,0x14 , temp,LOAD_MODE_CMD | (RL <<28 ) | (2 <<24 ), + tMRD_TCK * tCK); + +/* issue precharge all command */ +host_load_cmd (ctrl,0x18 ,4 ,PRECH_ALL_CMD , tRP + tCK); + +/* issue refresh command */ +host_load_cmd (ctrl,0x1c ,0 ,REF_CMD , tRFC_MIN); + +/* issue refresh command */ +host_load_cmd (ctrl,0x20 ,0 ,REF_CMD , tRFC_MIN); + +/* Mode register programming as before without DLL reset */ +host_load_cmd (ctrl,0x24 , temp,LOAD_MODE_CMD | (RL <<28 ) | (3 <<24 ), + tMRD_TCK * tCK); + +/* extended mode register same as before with OCD default */ +host_load_cmd (ctrl,0x28 ,0x103 ,LOAD_MODE_CMD | (0xc <<24 ), + tMRD_TCK * tCK); + +/* extended mode register same as before with OCD exit */ +host_load_cmd (ctrl,0x2c ,0x100 ,LOAD_MODE_CMD | (0x4 <<28 ), +140 * tCK); + +writel (CMD_VALID |NUMHOSTCMD (11 ), &ctrl->cmdissue); + +/* start memory initialization */ +writel (INIT_START , &ctrl->memcon); + +/* wait for all host cmds to be transmitted */ +wait_for_bit (__func__, &ctrl->cmdissue,CMD_VALID , false, +CONFIG_SYS_HZ , false); + +/* inform all cmds issued, ready for normal operation */ +writel (INIT_START |INIT_DONE , &ctrl->memcon); + +/* perform phy caliberation */ +ddr2_phy_calib_start (); +} + +phys_size_t ddr2_calculate_size (void ) +{ +u32 temp; + + temp =1 << (COL_BITS +BA_BITS +ROW_BITS ); +/* 16-bit data width between controller and DIMM */ + temp = temp *CS_BITS * (16 /8 ); +return (phys_size_t )temp; +}drivers/ddr/microchip/ddr2_regs.h new file +151
-0@@ -0,0 +1,151 @@ +/* +* (c) 2015 Purna Chandra Mandal <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +* +*/ + +#ifndef __MICROCHIP_DDR2_REGS_H +#define __MICROCHIP_DDR2_REGS_H + +#include <config.h> +#include <linux/bitops.h> + +/* DDR2 Controller */ +struct ddr2_ctrl_regs { +u32 tsel; +u32 minlim; +u32 reqprd; +u32 mincmd; +u32 memcon; +u32 memcfg0; +u32 memcfg1; +u32 memcfg2; +u32 memcfg3; +u32 memcfg4; +u32 refcfg; +u32 pwrcfg; +u32 dlycfg0; +u32 dlycfg1; +u32 dlycfg2; +u32 dlycfg3; +u32 odtcfg; +u32 xfercfg; +u32 cmdissue; +u32 odtencfg; +u32 memwidth; +u32 unused[11 ]; +u32 cmd10; +u32 othercmd10[15 ]; +u32 cmd20; +u32 othercmd20[15 ]; +}; + +/* Arbiter Config */ +#define MIN_LIM_WIDTH 5 +#define RQST_PERIOD_WIDTH 8 +#define MIN_CMDACPT_WIDTH 8 + +/* Refresh Config */ +#define REFCNT_CLK (x) (x) +#define REFDLY_CLK (x) ((x) << 16) +#define MAX_PEND_REF (x) ((x) << 24) + +/* Power Config */ +#define PRECH_PWR_DN_ONLY (x) ((x) << 22) +#define SELF_REF_DLY (x) ((x) << 12) +#define PWR_DN_DLY (x) ((x) << 4) +#define EN_AUTO_SELF_REF (x) ((x) << 3) +#define EN_AUTO_PWR_DN (x) ((x) << 2) +#define ERR_CORR_EN (x) ((x) << 1) +#define ECC_EN (x) (x) + +/* Memory Width */ +#define HALF_RATE_MODE BIT(3) + +/* Delay Config */ +#define ODTWLEN (x) ((x) << 20) +#define ODTRLEN (x) ((x) << 16) +#define ODTWDLY (x) ((x) << 12) +#define ODTRDLY (x) ((x) << 8) + +/* Xfer Config */ +#define BIG_ENDIAN (x) ((x) << 31) +#define MAX_BURST (x) ((x) << 24) +#define RDATENDLY (x) ((x) << 16) +#define NXDATAVDLY (x) ((x) << 4) +#define NXTDATRQDLY (x) ((x) << 0) + +/* Host Commands */ +#define IDLE_NOP 0x00ffffff +#define PRECH_ALL_CMD 0x00fff401 +#define REF_CMD 0x00fff801 +#define LOAD_MODE_CMD 0x00fff001 +#define CKE_LOW 0x00ffeffe + +#define NUM_HOST_CMDS 12 + +/* Host CMD Issue */ +#define CMD_VALID BIT(4) +#define NUMHOSTCMD (x) (x) + +/* Memory Control */ +#define INIT_DONE BIT(1) +#define INIT_START BIT(0) + +/* Address Control */ +#define EN_AUTO_PRECH 0 +#define SB_PRI 1 + +/* DDR2 Phy Register */ +struct ddr2_phy_regs { +u32 scl_start; +u32 unused1[2 ]; +u32 scl_latency; +u32 unused2[2 ]; +u32 scl_config_1; +u32 scl_config_2; +u32 pad_ctrl; +u32 dll_recalib; +}; + +/* PHY PAD CONTROL */ +#define ODT_SEL BIT(0) +#define ODT_EN BIT(1) +#define DRIVE_SEL (x) ((x) << 2) +#define ODT_PULLDOWN (x) ((x) << 4) +#define ODT_PULLUP (x) ((x) << 6) +#define EXTRA_OEN_CLK (x) ((x) << 8) +#define NOEXT_DLL BIT(9) +#define DLR_DFT_WRCMD BIT(13) +#define HALF_RATE BIT(14) +#define DRVSTR_PFET (x) ((x) << 16) +#define DRVSTR_NFET (x) ((x) << 20) +#define RCVR_EN BIT(28) +#define PREAMBLE_DLY (x) ((x) << 29) + +/* PHY DLL RECALIBRATE */ +#define RECALIB_CNT (x) ((x) << 8) +#define DISABLE_RECALIB (x) ((x) << 26) +#define DELAY_START_VAL (x) ((x) << 28) + +/* PHY SCL CONFIG1 */ +#define SCL_BURST8 BIT(0) +#define SCL_DDR_CONNECTED BIT(1) +#define SCL_RCAS_LAT (x) ((x) << 4) +#define SCL_ODTCSWW BIT(24) + +/* PHY SCL CONFIG2 */ +#define SCL_CSEN BIT(0) +#define SCL_WCAS_LAT (x) ((x) << 8) + +/* PHY SCL Latency */ +#define SCL_CAPCLKDLY (x) ((x) << 0) +#define SCL_DDRCLKDLY (x) ((x) << 4) + +/* PHY SCL START */ +#define SCL_START BIT(28) +#define SCL_EN BIT(26) +#define SCL_LUBPASS (BIT(1) | BIT(0)) + +#endif /* __MICROCHIP_DDR2_REGS_H */ drivers/ddr/microchip/ddr2_timing.h new file +33
-0@@ -0,0 +1,65 @@ +/* +* (c) 2015 Purna Chandra Mandal <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +* +*/ + +#ifndef __MICROCHIP_DDR2_TIMING_H +#define __MICROCHIP_DDR2_TIMING_H + +/* MPLL freq is 400MHz */ +#define tCK 2500/* 2500 psec */ +#define tCK_CTRL (tCK * 2) + +/* Burst length in cycles */ +#define BL 2 +/* default CAS latency for all speed grades */ +#define RL 5 +/* default write latency for all speed grades = CL-1 */ +#define WL 4 + +/* From Micron MT47H64M16HR-3 data sheet */ +#define tRFC_MIN 127500/* psec */ +#define tWR 15000/* psec */ +#define tRP 12500/* psec */ +#define tRCD 12500/* psec */ +#define tRRD 7500/* psec */ +/* tRRD_TCK is minimum of 2 clk periods, regardless of freq */ +#define tRRD_TCK 2 +#define tWTR 7500/* psec */ +/* tWTR_TCK is minimum of 2 clk periods, regardless of freq */ +#define tWTR_TCK 2 +#define tRTP 7500/* psec */ drivers/ddr/microchip/ddr2_timing.h line 43
Quoted 10 lines
drivers/ddr/microchip/ddr2_timing.h new file +10
-0+#define tRTP_TCK (BL / 2) +#define tXP_TCK 2/* clocks */ +#define tCKE_TCK 3/* clocks */ +#define tXSNR (tRFC_MIN + 10000)/* psec */ +#define tDLLK 200/* clocks */ +#define tRAS_MIN 45000/* psec */ +#define tRC 57500/* psec */ +#define tFAW 35000/* psec */ +#define tMRD_TCK 2/* clocks */ +#define tRFI 7800000/* psec */ please avoid CamelCase. This should be renamed to something like this:
Quoted 2 lines
#define
T_RFC_MIN
#defineT_WR
ack.
Quoted 28 lines
Quoted 26 lines
drivers/ddr/microchip/ddr2_timing.h new file +22
-1+ +/* DDR Addressing */ +#define COL_BITS 10 +#define BA_BITS 3 +#define ROW_BITS 13 +#define CS_BITS 1 + +/* DDR Addressing scheme: {CS, ROW, BA, COL} */ +#define COL_HI_RSHFT 0 +#define COL_HI_MASK 0 +#define COL_LO_MASK ((1 << COL_BITS) - 1) + +#define BA_RSHFT COL_BITS +#define BA_MASK ((1 << BA_BITS) - 1) + +#define ROW_ADDR_RSHIFT (BA_RSHFT + BA_BITS) +#define ROW_ADDR_MASK ((1 << ROW_BITS) - 1) + +#define CS_ADDR_RSHIFT 0 +#define CS_ADDR_MASK 0 + +#endif /* __MICROCHIP_DDR2_TIMING_H */ --1.8.3.1
PATCH v2 5/13 drivers: ddr: Add DDR2 SDRAM controller driver for Microchip PIC32.
In reply to Purna Chandra MandalHi,
Quoted 2 lines · Purna Chandra Mandal
Signed-off-by Paul Thacker <[email protected]>Signed-off-by Purna Chandra Mandal <[email protected]>
Please add a commit message.
Quoted 6 lines
---
Changes in v2:
- move ddr2 initialization from board/microchip/ todrivers/ddr/microchip
Quoted 13 lines
arch/mips/mach-pic32/include/mach/ddr.h | 32 ++++ drivers/Makefile | 1 + drivers/ddr/microchip/Makefile | 6 + drivers/ddr/microchip/ddr2.c | 277 ++++++++++++++++++++++++++++++++ drivers/ddr/microchip/ddr2_regs.h | 151 +++++++++++++++++ drivers/ddr/microchip/ddr2_timing.h | 65 ++++++++ 6 files changed, 532 insertions(+) create mode 100644 arch/mips/mach-pic32/include/mach/ddr.h create mode 100644 drivers/ddr/microchip/Makefile create mode 100644 drivers/ddr/microchip/ddr2.c create mode 100644 drivers/ddr/microchip/ddr2_regs.h create mode 100644 drivers/ddr/microchip/ddr2_timing.h
Regards,
Simon
PATCH v2 5/13 drivers: ddr: Add DDR2 SDRAM controller driver for Microchip PIC32.
Quoted 7 lines · Simon Glass
Hi,
Quoted 2 lines · Purna Chandra Mandal
Signed-off-by Paul Thacker <[email protected]>Signed-off-by Purna Chandra Mandal <[email protected]>Please add a commit message.
Agreed, Will add.
Quoted 20 lines
Quoted 5 lines
---
Changes in v2:
- move ddr2 initialization from board/microchip/ todrivers/ddr/microchipQuoted 13 lines
arch/mips/mach-pic32/include/mach/ddr.h | 32 ++++ drivers/Makefile | 1 + drivers/ddr/microchip/Makefile | 6 + drivers/ddr/microchip/ddr2.c | 277 ++++++++++++++++++++++++++++++++ drivers/ddr/microchip/ddr2_regs.h | 151 +++++++++++++++++ drivers/ddr/microchip/ddr2_timing.h | 65 ++++++++ 6 files changed, 532 insertions(+) create mode 100644 arch/mips/mach-pic32/include/mach/ddr.h create mode 100644 drivers/ddr/microchip/Makefile create mode 100644 drivers/ddr/microchip/ddr2.c create mode 100644 drivers/ddr/microchip/ddr2_regs.h create mode 100644 drivers/ddr/microchip/ddr2_timing.hRegards,
Simon