static uint32_t qpic_nand_fetch_id(struct flash_info *flash) { struct cmd_element *cmd_list_ptr = ce_array; struct cmd_element *cmd_list_ptr_start = ce_array; int num_desc = 0; uint32_t status; uint32_t id; uint32_t flash_cmd = NAND_CMD_FETCH_ID; uint32_t exec_cmd = 1; int nand_ret = NANDC_RESULT_SUCCESS; /* Issue the Fetch id command to the NANDc */ bam_add_cmd_element(cmd_list_ptr, NAND_FLASH_CMD, (uint32_t)flash_cmd, CE_WRITE_TYPE); cmd_list_ptr++; /* Execute the cmd */ bam_add_cmd_element(cmd_list_ptr, NAND_EXEC_CMD, (uint32_t)exec_cmd, CE_WRITE_TYPE); cmd_list_ptr++; /* Prepare the cmd desc for the above commands */ bam_add_one_desc(&bam, CMD_PIPE_INDEX, (unsigned char*)cmd_list_ptr_start, PA((uint32_t)cmd_list_ptr - (uint32_t)cmd_list_ptr_start), BAM_DESC_LOCK_FLAG | BAM_DESC_INT_FLAG | BAM_DESC_NWD_FLAG | BAM_DESC_CMD_FLAG); /* Keep track of the number of desc added. */ num_desc++; qpic_nand_wait_for_cmd_exec(num_desc); cmd_list_ptr_start = ce_array; cmd_list_ptr = ce_array; /* Read the status register */ status = qpic_nand_read_reg(NAND_FLASH_STATUS, 0, cmd_list_ptr); /* Check for errors */ nand_ret = qpic_nand_check_status(status); if (nand_ret) { dprintf( CRITICAL, "Read ID cmd status failed\n"); goto qpic_nand_fetch_id_err; } /* Read the id */ id = qpic_nand_read_reg(NAND_READ_ID, BAM_DESC_UNLOCK_FLAG, cmd_list_ptr); flash->id = id; flash->vendor = id & 0xff; flash->device = (id >> 8) & 0xff; flash->dev_cfg = (id >> 24) & 0xFF; flash->widebus = 0; flash->widebus &= (id >> 24) & 0xFF; flash->widebus = flash->widebus? 1: 0; qpic_nand_fetch_id_err: return nand_ret; }
static uint32_t crypto_write_reg(struct bam_instance *bam_core, uint32_t reg_addr, uint32_t val, uint8_t flags) { uint32_t ret = 0; struct cmd_element cmd_list_ptr; ret = (uint32_t)bam_add_cmd_element(&cmd_list_ptr, reg_addr, val, CE_WRITE_TYPE); /* Enqueue the desc for the above command */ ret = bam_add_one_desc(bam_core, CRYPTO_WRITE_PIPE_INDEX, (unsigned char*)PA((addr_t)&cmd_list_ptr), BAM_CE_SIZE, BAM_DESC_CMD_FLAG | BAM_DESC_INT_FLAG | flags); if (ret) { dprintf(CRITICAL, "CRYPTO_WRITE_REG: Reg write failed. reg addr = %x\n", reg_addr); goto crypto_read_reg_err; } crypto_wait_for_cmd_exec(bam_core, 1, CRYPTO_WRITE_PIPE_INDEX); crypto_read_reg_err: return val; }
/* Adds command elements for addr and cfg register writes. * cfg: Defines the configuration for the flash cmd. * start: Address where the command elements are added. * * Returns the address where the next cmd element can be added. */ static struct cmd_element* qpic_nand_add_addr_n_cfg_ce(struct cfg_params *cfg, struct cmd_element *start) { struct cmd_element *cmd_list_ptr = start; bam_add_cmd_element(cmd_list_ptr, NAND_ADDR0, (uint32_t)cfg->addr0, CE_WRITE_TYPE); cmd_list_ptr++; bam_add_cmd_element(cmd_list_ptr, NAND_ADDR1, (uint32_t)cfg->addr1, CE_WRITE_TYPE); cmd_list_ptr++; bam_add_cmd_element(cmd_list_ptr, NAND_DEV0_CFG0, (uint32_t)cfg->cfg0, CE_WRITE_TYPE); cmd_list_ptr++; bam_add_cmd_element(cmd_list_ptr, NAND_DEV0_CFG1, (uint32_t)cfg->cfg1, CE_WRITE_TYPE); cmd_list_ptr++; return cmd_list_ptr; }
/* TODO: check why both vld and cmd need to be written. */ void 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; bam_add_cmd_element(cmd_list_ptr, NAND_DEV_CMD1, dev_cmd1, CE_WRITE_TYPE); cmd_list_ptr++; bam_add_cmd_element(cmd_list_ptr, NAND_DEV_CMD_VLD, vld, CE_WRITE_TYPE); cmd_list_ptr++; /* Enqueue the desc for the above commands */ bam_add_one_desc(&bam, CMD_PIPE_INDEX, (unsigned char*)cmd_list_ptr_start, PA((uint32_t)cmd_list_ptr - (uint32_t)cmd_list_ptr_start), BAM_DESC_UNLOCK_FLAG | BAM_DESC_CMD_FLAG| BAM_DESC_INT_FLAG); qpic_nand_wait_for_cmd_exec(1); }
static void crypto_add_cmd_element(struct crypto_dev *dev, uint32_t addr, uint32_t val) { struct cmd_element *ptr = dev->ce_array; bam_add_cmd_element(&(ptr[dev->ce_array_index]), addr, val, CE_WRITE_TYPE); arch_clean_invalidate_cache_range((addr_t) &(ptr[dev->ce_array_index]), sizeof(struct cmd_element)); dev->ce_array_index++; }
static struct cmd_element* qpic_nand_add_onfi_probe_ce(struct onfi_probe_params *params, struct cmd_element *start) { struct cmd_element *cmd_list_ptr = start; 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, (uint32_t)params->dev_cmd1, CE_WRITE_TYPE); cmd_list_ptr++; bam_add_cmd_element(cmd_list_ptr, NAND_DEV_CMD_VLD, (uint32_t)params->vld, CE_WRITE_TYPE); cmd_list_ptr++; bam_add_cmd_element(cmd_list_ptr, NAND_READ_LOCATION_n(0), (uint32_t)params->cfg.addr_loc_0, CE_WRITE_TYPE); cmd_list_ptr++; bam_add_cmd_element(cmd_list_ptr, NAND_FLASH_CMD, (uint32_t)params->cfg.cmd, CE_WRITE_TYPE); cmd_list_ptr++; bam_add_cmd_element(cmd_list_ptr, NAND_EXEC_CMD, (uint32_t)params->cfg.exec, CE_WRITE_TYPE); cmd_list_ptr++; return cmd_list_ptr; }
/* Assume the BAM is in a locked state. */ void qpic_nand_erased_status_reset(struct cmd_element *cmd_list_ptr, uint8_t flags) { uint32_t val = 0; /* Reset the Erased Codeword/Page detection controller. */ val = NAND_ERASED_CW_DETECT_CFG_RESET_CTRL; bam_add_cmd_element(cmd_list_ptr, NAND_ERASED_CW_DETECT_CFG, val, CE_WRITE_TYPE); /* Enqueue the desc for the above command */ bam_add_one_desc(&bam, CMD_PIPE_INDEX, (unsigned char*)cmd_list_ptr, BAM_CE_SIZE, BAM_DESC_CMD_FLAG | BAM_DESC_INT_FLAG | flags); qpic_nand_wait_for_cmd_exec(1); /* Enable the Erased Codeword/Page detection * controller to check the data as it arrives. * Also disable ECC reporting for an erased CW. */ val = NAND_ERASED_CW_DETECT_CFG_ACTIVATE_CTRL | NAND_ERASED_CW_DETECT_ERASED_CW_ECC_MASK; bam_add_cmd_element(cmd_list_ptr, NAND_ERASED_CW_DETECT_CFG, val, CE_WRITE_TYPE); /* Enqueue the desc for the above command */ bam_add_one_desc(&bam, CMD_PIPE_INDEX, (unsigned char*)cmd_list_ptr, BAM_CE_SIZE, BAM_DESC_CMD_FLAG | BAM_DESC_INT_FLAG); qpic_nand_wait_for_cmd_exec(1); }
static uint32_t qpic_nand_read_reg(uint32_t reg_addr, uint8_t flags, struct cmd_element *cmd_list_ptr) { uint32_t val; bam_add_cmd_element(cmd_list_ptr, reg_addr, (uint32_t)PA((addr_t)&val), CE_READ_TYPE); /* Enqueue the desc for the above command */ bam_add_one_desc(&bam, CMD_PIPE_INDEX, (unsigned char*)PA((addr_t)cmd_list_ptr), BAM_CE_SIZE, BAM_DESC_CMD_FLAG| BAM_DESC_INT_FLAG | flags); qpic_nand_wait_for_cmd_exec(1); return val; }