qcom: nand: Add IPQ807x support

Change-Id: If83199c83275dba83350ddbf0f2d3a80de3e9c65
Signed-off-by: Sham Muthayyan <smuthayy@codeaurora.org>
This commit is contained in:
Sham Muthayyan 2016-06-01 11:36:04 +05:30 committed by Gerrit - the friendly Code Review server
parent 32d68e6e5b
commit 2a8bb9d7d7
6 changed files with 90 additions and 11 deletions

View file

@ -30,5 +30,14 @@
timer_load_val = <0x00FFFFFF 0xFFFFFFFF>; timer_load_val = <0x00FFFFFF 0xFFFFFFFF>;
}; };
nand: nand-controller@79B0000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "qcom,qpic-nand.1.5.20";
reg = <0x79B0000 0x10000>;
};
}; };

View file

@ -74,9 +74,9 @@
#define NAND_GENP_REG3 NAND_REG(0x009C) #define NAND_GENP_REG3 NAND_REG(0x009C)
#define NAND_SFLASHC_STATUS NAND_REG(0x001C) #define NAND_SFLASHC_STATUS NAND_REG(0x001C)
#define NAND_DEV_CMD0 NAND_REG(0x00A0) #define NAND_DEV_CMD0 NAND_REG(0x00A0)
#define NAND_DEV_CMD1 NAND_REG(0x00A4) #define NAND_DEV_CMD1_V1_4_20 NAND_REG(0x00A4)
#define NAND_DEV_CMD2 NAND_REG(0x00A8) #define NAND_DEV_CMD2 NAND_REG(0x00A8)
#define NAND_DEV_CMD_VLD NAND_REG(0x00AC) #define NAND_DEV_CMD_VLD_V1_4_20 NAND_REG(0x00AC)
#define NAND_EBI2_MISR_SIG_REG NAND_REG(0x00B0) #define NAND_EBI2_MISR_SIG_REG NAND_REG(0x00B0)
#define NAND_ADDR2 NAND_REG(0x00C0) #define NAND_ADDR2 NAND_REG(0x00C0)
#define NAND_ADDR3 NAND_REG(0x00C4) #define NAND_ADDR3 NAND_REG(0x00C4)
@ -102,6 +102,9 @@
#define NAND_RD_LOC_SIZE(x) ((x) << 16) #define NAND_RD_LOC_SIZE(x) ((x) << 16)
#define NAND_RD_LOC_OFFSET(x) ((x) << 0) #define NAND_RD_LOC_OFFSET(x) ((x) << 0)
#define NAND_DEV_CMD_VLD_V1_5_20 NAND_REG(0x70AC)
#define NAND_DEV_CMD1_V1_5_20 NAND_REG(0x70A4)
/* Shift Values */ /* Shift Values */
#define NAND_DEV0_CFG1_WIDE_BUS_SHIFT 1 #define NAND_DEV0_CFG1_WIDE_BUS_SHIFT 1
#define NAND_DEV0_CFG0_DIS_STS_AFTER_WR_SHIFT 4 #define NAND_DEV0_CFG0_DIS_STS_AFTER_WR_SHIFT 4
@ -266,6 +269,13 @@
#define QPIC_BAM_DATA_FIFO_SIZE 64 #define QPIC_BAM_DATA_FIFO_SIZE 64
#define QPIC_BAM_CMD_FIFO_SIZE 64 #define QPIC_BAM_CMD_FIFO_SIZE 64
enum qpic_verion{
QCOM_QPIC_V1_4_20,
QCOM_QPIC_V1_5_20,
};
/* result type */ /* result type */
typedef enum { typedef enum {
NANDC_RESULT_SUCCESS = 0, NANDC_RESULT_SUCCESS = 0,

View file

@ -19,6 +19,8 @@
#include "ipq807x.h" #include "ipq807x.h"
#include "../common/qca_common.h" #include "../common/qca_common.h"
#include <asm/arch-qcom-common/qpic_nand.h> #include <asm/arch-qcom-common/qpic_nand.h>
#include <fdtdec.h>
DECLARE_GLOBAL_DATA_PTR; DECLARE_GLOBAL_DATA_PTR;
@ -109,6 +111,15 @@ int board_mmc_init(bd_t *bis)
void board_nand_init(void) void board_nand_init(void)
{ {
int node, ret;
node = fdtdec_next_compatible(gd->fdt_blob, 0,
COMPAT_QCOM_QPIC_NAND);
if (node < 0) {
printf("Could not find nand-flash in device tree\n");
return;
}
struct qpic_nand_init_config config; struct qpic_nand_init_config config;
config.pipes.read_pipe = DATA_PRODUCER_PIPE; config.pipes.read_pipe = DATA_PRODUCER_PIPE;
@ -120,9 +131,10 @@ void board_nand_init(void)
config.pipes.cmd_pipe_grp = CMD_PIPE_GRP; config.pipes.cmd_pipe_grp = CMD_PIPE_GRP;
config.bam_base = QPIC_BAM_CTRL_BASE; config.bam_base = QPIC_BAM_CTRL_BASE;
config.nand_base = QPIC_EBI2ND_BASE; config.nand_base = fdtdec_get_addr(gd->fdt_blob, node, "reg");;
config.ee = QPIC_NAND_EE; config.ee = QPIC_NAND_EE;
config.max_desc_len = QPIC_NAND_MAX_DESC_LEN; config.max_desc_len = QPIC_NAND_MAX_DESC_LEN;
qpic_nand_init(&config); qpic_nand_init(&config);
} }

View file

@ -35,9 +35,15 @@
#include <linux/mtd/nand.h> #include <linux/mtd/nand.h>
#include <asm/arch-qcom-common/bam.h> #include <asm/arch-qcom-common/bam.h>
#include <asm/arch-qcom-common/qpic_nand.h> #include <asm/arch-qcom-common/qpic_nand.h>
#include <fdtdec.h>
#include <dm.h>
DECLARE_GLOBAL_DATA_PTR;
typedef unsigned long addr_t; typedef unsigned long addr_t;
static uint32_t hw_ver;
struct cmd_element ce_array[100] __attribute__ ((aligned(16))); struct cmd_element ce_array[100] __attribute__ ((aligned(16)));
struct cmd_element ce_read_array[20] __attribute__ ((aligned(16))); struct cmd_element ce_read_array[20] __attribute__ ((aligned(16)));
static struct qpic_nand_dev qpic_nand_dev; static struct qpic_nand_dev qpic_nand_dev;
@ -46,6 +52,13 @@ struct bam_desc qpic_data_desc_fifo[QPIC_BAM_DATA_FIFO_SIZE] __attribute__ ((ali
static struct bam_instance bam; static struct bam_instance bam;
struct nand_ecclayout fake_ecc_layout; struct nand_ecclayout fake_ecc_layout;
static const struct udevice_id qpic_ver_ids[] = {
{ .compatible = "qcom,qpic-nand.1.4.20", .data = QCOM_QPIC_V1_4_20 },
{ .compatible = "qcom,qpic-nand.1.5.20", .data = QCOM_QPIC_V1_5_20 },
{ },
};
static void static void
qpic_nand_wait_for_cmd_exec(uint32_t num_desc) qpic_nand_wait_for_cmd_exec(uint32_t num_desc)
{ {
@ -190,6 +203,7 @@ qpic_nand_fetch_id(struct mtd_info *mtd)
uint32_t exec_cmd = 1; uint32_t exec_cmd = 1;
int nand_ret = NANDC_RESULT_SUCCESS; int nand_ret = NANDC_RESULT_SUCCESS;
uint32_t vld; uint32_t vld;
uint32_t cmd_vld = NAND_DEV_CMD_VLD_V1_4_20;
/* Issue the Fetch id command to the NANDc */ /* Issue the Fetch id command to the NANDc */
bam_add_cmd_element(cmd_list_ptr, NAND_FLASH_CMD, (uint32_t)flash_cmd, bam_add_cmd_element(cmd_list_ptr, NAND_FLASH_CMD, (uint32_t)flash_cmd,
@ -198,7 +212,10 @@ qpic_nand_fetch_id(struct mtd_info *mtd)
vld = NAND_CMD_VALID_BASE; vld = NAND_CMD_VALID_BASE;
bam_add_cmd_element(cmd_list_ptr, NAND_DEV_CMD_VLD, (uint32_t)vld, if (hw_ver == QCOM_QPIC_V1_5_20)
cmd_vld = NAND_DEV_CMD_VLD_V1_5_20;
bam_add_cmd_element(cmd_list_ptr, cmd_vld, (uint32_t)vld,
CE_WRITE_TYPE); CE_WRITE_TYPE);
cmd_list_ptr++; cmd_list_ptr++;
@ -379,13 +396,19 @@ qpic_nand_add_onfi_probe_ce(struct onfi_probe_params *params,
struct cmd_element *start) struct cmd_element *start)
{ {
struct cmd_element *cmd_list_ptr = start; struct cmd_element *cmd_list_ptr = start;
uint32_t cmd_vld = NAND_DEV_CMD_VLD_V1_4_20;
uint32_t dev_cmd1 = NAND_DEV_CMD1_V1_4_20;
cmd_list_ptr = qpic_nand_add_addr_n_cfg_ce(&params->cfg, cmd_list_ptr); cmd_list_ptr = qpic_nand_add_addr_n_cfg_ce(&params->cfg, cmd_list_ptr);
bam_add_cmd_element(cmd_list_ptr, NAND_DEV_CMD1, if (hw_ver == QCOM_QPIC_V1_5_20) {
cmd_vld = NAND_DEV_CMD_VLD_V1_5_20;
dev_cmd1 = NAND_DEV_CMD1_V1_5_20;
}
bam_add_cmd_element(cmd_list_ptr, dev_cmd1,
(uint32_t)params->dev_cmd1, CE_WRITE_TYPE); (uint32_t)params->dev_cmd1, CE_WRITE_TYPE);
cmd_list_ptr++; cmd_list_ptr++;
bam_add_cmd_element(cmd_list_ptr, NAND_DEV_CMD_VLD, bam_add_cmd_element(cmd_list_ptr, cmd_vld,
(uint32_t)params->vld, CE_WRITE_TYPE); (uint32_t)params->vld, CE_WRITE_TYPE);
cmd_list_ptr++; cmd_list_ptr++;
bam_add_cmd_element(cmd_list_ptr, NAND_READ_LOCATION_n(0), bam_add_cmd_element(cmd_list_ptr, NAND_READ_LOCATION_n(0),
@ -467,11 +490,17 @@ qpic_nand_onfi_probe_cleanup(uint32_t vld, uint32_t dev_cmd1)
{ {
struct cmd_element *cmd_list_ptr = ce_array; struct cmd_element *cmd_list_ptr = ce_array;
struct cmd_element *cmd_list_ptr_start = ce_array; struct cmd_element *cmd_list_ptr_start = ce_array;
uint32_t cmd_vld = NAND_DEV_CMD_VLD_V1_4_20;
uint32_t dev_cmd1_reg = NAND_DEV_CMD1_V1_4_20;
bam_add_cmd_element(cmd_list_ptr, NAND_DEV_CMD1, dev_cmd1, if (hw_ver == QCOM_QPIC_V1_5_20) {
cmd_vld = NAND_DEV_CMD_VLD_V1_5_20;
dev_cmd1_reg = NAND_DEV_CMD1_V1_5_20;
}
bam_add_cmd_element(cmd_list_ptr, dev_cmd1_reg, dev_cmd1,
CE_WRITE_TYPE); CE_WRITE_TYPE);
cmd_list_ptr++; cmd_list_ptr++;
bam_add_cmd_element(cmd_list_ptr, NAND_DEV_CMD_VLD, vld, bam_add_cmd_element(cmd_list_ptr, cmd_vld, vld,
CE_WRITE_TYPE); CE_WRITE_TYPE);
cmd_list_ptr++; cmd_list_ptr++;
@ -642,6 +671,8 @@ qpic_nand_onfi_probe(struct mtd_info *mtd)
struct onfi_probe_params params; struct onfi_probe_params params;
uint32_t vld; uint32_t vld;
uint32_t dev_cmd1; uint32_t dev_cmd1;
uint32_t cmd_vld = NAND_DEV_CMD_VLD_V1_4_20;
uint32_t dev_cmd1_reg = NAND_DEV_CMD1_V1_4_20;
unsigned char *buffer; unsigned char *buffer;
unsigned char onfi_str[4]; unsigned char onfi_str[4];
uint32_t *id; uint32_t *id;
@ -655,9 +686,13 @@ qpic_nand_onfi_probe(struct mtd_info *mtd)
return -ENOMEM; return -ENOMEM;
} }
if (hw_ver == QCOM_QPIC_V1_5_20) {
cmd_vld = NAND_DEV_CMD_VLD_V1_5_20;
dev_cmd1_reg = NAND_DEV_CMD1_V1_5_20;
}
/* Read the vld and dev_cmd1 registers before modifying */ /* Read the vld and dev_cmd1 registers before modifying */
vld = qpic_nand_read_reg(NAND_DEV_CMD_VLD, 0); vld = qpic_nand_read_reg(cmd_vld, 0);
dev_cmd1 = qpic_nand_read_reg(NAND_DEV_CMD1, 0); dev_cmd1 = qpic_nand_read_reg(dev_cmd1_reg, 0);
/* Initialize flash cmd */ /* Initialize flash cmd */
params.cfg.cmd = NAND_CMD_PAGE_READ; params.cfg.cmd = NAND_CMD_PAGE_READ;
@ -2136,18 +2171,29 @@ int
qpic_nand_init(struct qpic_nand_init_config *config) qpic_nand_init(struct qpic_nand_init_config *config)
{ {
struct mtd_info *mtd; struct mtd_info *mtd;
const struct udevice_id *of_match = qpic_ver_ids;
struct nand_chip *chip; struct nand_chip *chip;
int ret = 0; int ret = 0;
struct qpic_nand_dev *dev; struct qpic_nand_dev *dev;
size_t alloc_size; size_t alloc_size;
unsigned char *buf; unsigned char *buf;
while (of_match->compatible) {
ret = fdt_node_offset_by_compatible(gd->fdt_blob, 0,
of_match->compatible);
if (ret < 0) {
of_match++;
continue;
}
hw_ver = of_match->data;
break;
}
mtd = &nand_info[CONFIG_QPIC_NAND_NAND_INFO_IDX]; mtd = &nand_info[CONFIG_QPIC_NAND_NAND_INFO_IDX];
mtd->priv = &nand_chip[0]; mtd->priv = &nand_chip[0];
chip = mtd->priv; chip = mtd->priv;
chip->priv = &qpic_nand_dev; chip->priv = &qpic_nand_dev;
qpic_bam_init(config); qpic_bam_init(config);
ret = qpic_nand_onfi_probe(mtd); ret = qpic_nand_onfi_probe(mtd);

View file

@ -170,6 +170,7 @@ enum fdt_compat_id {
COMPAT_ALTERA_SOCFPGA_DWC2USB, /* SoCFPGA DWC2 USB controller */ COMPAT_ALTERA_SOCFPGA_DWC2USB, /* SoCFPGA DWC2 USB controller */
COMPAT_INTEL_BAYTRAIL_FSP, /* Intel Bay Trail FSP */ COMPAT_INTEL_BAYTRAIL_FSP, /* Intel Bay Trail FSP */
COMPAT_INTEL_BAYTRAIL_FSP_MDP, /* Intel FSP memory-down params */ COMPAT_INTEL_BAYTRAIL_FSP_MDP, /* Intel FSP memory-down params */
COMPAT_QCOM_QPIC_NAND, /* Qualcomm QPIC NAND controller */
COMPAT_COUNT, COMPAT_COUNT,
}; };

View file

@ -74,6 +74,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
COMPAT(ALTERA_SOCFPGA_DWC2USB, "snps,dwc2"), COMPAT(ALTERA_SOCFPGA_DWC2USB, "snps,dwc2"),
COMPAT(COMPAT_INTEL_BAYTRAIL_FSP, "intel,baytrail-fsp"), COMPAT(COMPAT_INTEL_BAYTRAIL_FSP, "intel,baytrail-fsp"),
COMPAT(COMPAT_INTEL_BAYTRAIL_FSP_MDP, "intel,baytrail-fsp-mdp"), COMPAT(COMPAT_INTEL_BAYTRAIL_FSP_MDP, "intel,baytrail-fsp-mdp"),
COMPAT(QCOM_QPIC_NAND, "qcom,qpic-nand.1.5.20"),
}; };
const char *fdtdec_get_compatible(enum fdt_compat_id id) const char *fdtdec_get_compatible(enum fdt_compat_id id)