From 2a8bb9d7d7186df187c8e0d88eb13e41bfcfeb17 Mon Sep 17 00:00:00 2001 From: Sham Muthayyan Date: Wed, 1 Jun 2016 11:36:04 +0530 Subject: [PATCH] qcom: nand: Add IPQ807x support Change-Id: If83199c83275dba83350ddbf0f2d3a80de3e9c65 Signed-off-by: Sham Muthayyan --- arch/arm/dts/ipq807x-hk01.dtsi | 9 +++ .../include/asm/arch-qcom-common/qpic_nand.h | 14 ++++- board/qca/ipq807x/ipq807x.c | 14 ++++- drivers/mtd/nand/qpic_nand.c | 62 ++++++++++++++++--- include/fdtdec.h | 1 + lib/fdtdec.c | 1 + 6 files changed, 90 insertions(+), 11 deletions(-) diff --git a/arch/arm/dts/ipq807x-hk01.dtsi b/arch/arm/dts/ipq807x-hk01.dtsi index d032b53983..e80ecaf121 100644 --- a/arch/arm/dts/ipq807x-hk01.dtsi +++ b/arch/arm/dts/ipq807x-hk01.dtsi @@ -30,5 +30,14 @@ 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>; + + }; + + }; diff --git a/arch/arm/include/asm/arch-qcom-common/qpic_nand.h b/arch/arm/include/asm/arch-qcom-common/qpic_nand.h index f917cdeb2a..27d2133941 100644 --- a/arch/arm/include/asm/arch-qcom-common/qpic_nand.h +++ b/arch/arm/include/asm/arch-qcom-common/qpic_nand.h @@ -74,9 +74,9 @@ #define NAND_GENP_REG3 NAND_REG(0x009C) #define NAND_SFLASHC_STATUS NAND_REG(0x001C) #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_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_ADDR2 NAND_REG(0x00C0) #define NAND_ADDR3 NAND_REG(0x00C4) @@ -102,6 +102,9 @@ #define NAND_RD_LOC_SIZE(x) ((x) << 16) #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 */ #define NAND_DEV0_CFG1_WIDE_BUS_SHIFT 1 #define NAND_DEV0_CFG0_DIS_STS_AFTER_WR_SHIFT 4 @@ -266,6 +269,13 @@ #define QPIC_BAM_DATA_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 */ typedef enum { NANDC_RESULT_SUCCESS = 0, diff --git a/board/qca/ipq807x/ipq807x.c b/board/qca/ipq807x/ipq807x.c index 1780fa6b61..9e0265b310 100644 --- a/board/qca/ipq807x/ipq807x.c +++ b/board/qca/ipq807x/ipq807x.c @@ -19,6 +19,8 @@ #include "ipq807x.h" #include "../common/qca_common.h" #include +#include + DECLARE_GLOBAL_DATA_PTR; @@ -109,6 +111,15 @@ int board_mmc_init(bd_t *bis) 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; 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.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.max_desc_len = QPIC_NAND_MAX_DESC_LEN; qpic_nand_init(&config); + } diff --git a/drivers/mtd/nand/qpic_nand.c b/drivers/mtd/nand/qpic_nand.c index 5aa58a61d8..1abb91db83 100644 --- a/drivers/mtd/nand/qpic_nand.c +++ b/drivers/mtd/nand/qpic_nand.c @@ -35,9 +35,15 @@ #include #include #include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; typedef unsigned long addr_t; +static uint32_t hw_ver; + struct cmd_element ce_array[100] __attribute__ ((aligned(16))); struct cmd_element ce_read_array[20] __attribute__ ((aligned(16))); 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; 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 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; int nand_ret = NANDC_RESULT_SUCCESS; uint32_t vld; + uint32_t cmd_vld = NAND_DEV_CMD_VLD_V1_4_20; /* Issue the Fetch id command to the NANDc */ 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; - 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); 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 *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(¶ms->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); 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); cmd_list_ptr++; 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_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); 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); cmd_list_ptr++; @@ -642,6 +671,8 @@ qpic_nand_onfi_probe(struct mtd_info *mtd) struct onfi_probe_params params; uint32_t vld; 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 onfi_str[4]; uint32_t *id; @@ -655,9 +686,13 @@ qpic_nand_onfi_probe(struct mtd_info *mtd) 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 */ - vld = qpic_nand_read_reg(NAND_DEV_CMD_VLD, 0); - dev_cmd1 = qpic_nand_read_reg(NAND_DEV_CMD1, 0); + vld = qpic_nand_read_reg(cmd_vld, 0); + dev_cmd1 = qpic_nand_read_reg(dev_cmd1_reg, 0); /* Initialize flash cmd */ params.cfg.cmd = NAND_CMD_PAGE_READ; @@ -2136,18 +2171,29 @@ int qpic_nand_init(struct qpic_nand_init_config *config) { struct mtd_info *mtd; + const struct udevice_id *of_match = qpic_ver_ids; struct nand_chip *chip; int ret = 0; struct qpic_nand_dev *dev; size_t alloc_size; 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->priv = &nand_chip[0]; chip = mtd->priv; chip->priv = &qpic_nand_dev; - + qpic_bam_init(config); ret = qpic_nand_onfi_probe(mtd); diff --git a/include/fdtdec.h b/include/fdtdec.h index d82dc35073..51811b4140 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -170,6 +170,7 @@ enum fdt_compat_id { COMPAT_ALTERA_SOCFPGA_DWC2USB, /* SoCFPGA DWC2 USB controller */ COMPAT_INTEL_BAYTRAIL_FSP, /* Intel Bay Trail FSP */ COMPAT_INTEL_BAYTRAIL_FSP_MDP, /* Intel FSP memory-down params */ + COMPAT_QCOM_QPIC_NAND, /* Qualcomm QPIC NAND controller */ COMPAT_COUNT, }; diff --git a/lib/fdtdec.c b/lib/fdtdec.c index ae0b708ddc..885bfb4410 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -74,6 +74,7 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(ALTERA_SOCFPGA_DWC2USB, "snps,dwc2"), COMPAT(COMPAT_INTEL_BAYTRAIL_FSP, "intel,baytrail-fsp"), 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)