Example #1
0
void elm_reset(void)
{
	u32 reg_val;

	reg_val = elm_read_reg(ELM_SYSCONFIG);
	reg_val |= ELM_SYSCONFIG_SOFTRESET;
	elm_write_reg(ELM_SYSCONFIG, reg_val);

	while ((elm_read_reg(ELM_SYSSTATUS) & ELM_SYSSTATUS_RESETDONE)
			!= ELM_SYSSTATUS_RESETDONE)
		;

	reg_val = elm_read_reg(ELM_SYSCONFIG);
	reg_val &= ~ELM_SYSCONFIG_SIDLE_MASK;
	reg_val |= ELM_SYSCONFIG_SMART_IDLE;
	elm_write_reg(ELM_SYSCONFIG, reg_val);
}
Example #2
0
void elm_start_processing(void)
{
	u32 reg_val;

	reg_val = elm_read_reg(ELM_SYNDROME_FRAGMENT_6);
	reg_val |= ELM_SYNDROME_VALID;
	elm_write_reg(ELM_SYNDROME_FRAGMENT_6, reg_val);
}
Example #3
0
void elm_load_syndrome(int bch_type, char *syndrome)
{
	int reg_val;
	int i;

	for (i = 0; i < 4; i++) {
		reg_val = syndrome[0] | syndrome[1] << 8 |
			syndrome[2] << 16 | syndrome[3] << 24;
		elm_write_reg(ELM_SYNDROME_FRAGMENT_0 + i * 4, reg_val);
		syndrome += 4;
	}
}
void elm_load_syndrome(unsigned int ecc_bytes, char *syndrome)
{
	int reg_val;
	int i;

	for (i = 0; i < ecc_bytes; i += 4) {
		reg_val = syndrome[0] | syndrome[1] << 8 |
			syndrome[2] << 16 | syndrome[3] << 24;
		elm_write_reg(ELM_SYNDROME_FRAGMENT_0 + i, reg_val);
		syndrome += 4;
	}
}
Example #5
0
void elm_config(int bch_type)
{
	u32 reg_val;
	u32 buffer_size = 0x7ff;

	reg_val = (bch_type & ECC_BCH_LEVEL_MASK) | (buffer_size << 16);
	elm_write_reg(ELM_LOCATION_CONFIG, reg_val);

	/* clearing interrupts */
	reg_val = elm_read_reg(ELM_IRQSTATUS);
	elm_write_reg(ELM_IRQSTATUS, reg_val & INTR_STATUS_LOC_VALID_0);
	elm_write_reg(ELM_IRQSTATUS, INTR_STATUS_LOC_VALID_0);

	/* enable in interupt mode */
	reg_val = elm_read_reg(ELM_IRQENABLE);
	reg_val |= INTR_EN_LOCATION_MASK_0;
	elm_write_reg(ELM_IRQENABLE, reg_val);

	/* config in Continuous mode */
	reg_val = elm_read_reg(ELM_PAGE_CTRL);
	reg_val = 0;
	elm_write_reg(ELM_PAGE_CTRL, reg_val);
}
Example #6
0
static irqreturn_t elm_isr(int this_irq, void *dev_id)
{
	u32 reg_val;

	reg_val = elm_read_reg(ELM_IRQSTATUS);

	if (reg_val & INTR_STATUS_LOC_VALID_0) {
		elm_write_reg(ELM_IRQSTATUS, reg_val & INTR_STATUS_LOC_VALID_0);
		complete(&elm_completion);
		return IRQ_HANDLED;
	}

	return IRQ_NONE;
}
int elm_decode_bch_error(int bch_type,
				char *ecc_calc, unsigned int *err_loc)
{
	u8 ecc_data[28] = {0};
	u32 reg_val;
	int i, err_no;

	/* input calculated ECC syndrome to ELM engine */
	switch (bch_type) {
	case ECC_TYPE_BCH16:
		rotate_ecc_bytes(ECC_BYTES_BCH16, ecc_calc, ecc_data);
		elm_load_syndrome(ECC_BYTES_BCH16, ecc_data);
		break;
	case ECC_TYPE_BCH8:
		rotate_ecc_bytes(ECC_BYTES_BCH8, ecc_calc, ecc_data);
		elm_load_syndrome(ECC_BYTES_BCH8, ecc_data);
		break;
	case ECC_TYPE_BCH4:
		rotate_ecc_bytes(ECC_BYTES_BCH4, ecc_calc, ecc_data);
		elm_load_syndrome(ECC_BYTES_BCH4, ecc_data);
		break;
	default:
		return -EINVAL;
	}

	/* start elm processing */
	reg_val = elm_read_reg(ELM_SYNDROME_FRAGMENT_6);
	reg_val |= ELM_SYNDROME_VALID;
	elm_write_reg(ELM_SYNDROME_FRAGMENT_6, reg_val);

	wait_for_completion(&elm_completion);
	reg_val = elm_read_reg(ELM_LOCATION_STATUS);

	if (reg_val & ECC_CORRECTABLE_MASK) {
		err_no = reg_val & ECC_NB_ERRORS_MASK;

		for (i = 0; i < err_no; i++) {
			reg_val = elm_read_reg(ELM_ERROR_LOCATION_0 + i * 4);
			err_loc[i] = reg_val;
		}

		return err_no;
	}

	return -EINVAL;
}