Lines Matching full:bch
3 * JZ4780 BCH controller driver
59 /* Timeout for BCH calculation/correction. */
62 static void jz4780_bch_reset(struct ingenic_ecc *bch, in jz4780_bch_reset() argument
68 writel(readl(bch->base + BCH_BHINT), bch->base + BCH_BHINT); in jz4780_bch_reset()
70 /* Set up BCH count register. */ in jz4780_bch_reset()
73 writel(reg, bch->base + BCH_BHCNT); in jz4780_bch_reset()
75 /* Initialise and enable BCH. */ in jz4780_bch_reset()
80 writel(reg, bch->base + BCH_BHCR); in jz4780_bch_reset()
83 static void jz4780_bch_disable(struct ingenic_ecc *bch) in jz4780_bch_disable() argument
85 writel(readl(bch->base + BCH_BHINT), bch->base + BCH_BHINT); in jz4780_bch_disable()
86 writel(BCH_BHCR_BCHE, bch->base + BCH_BHCCR); in jz4780_bch_disable()
89 static void jz4780_bch_write_data(struct ingenic_ecc *bch, const void *buf, in jz4780_bch_write_data() argument
99 writel(*src32++, bch->base + BCH_BHDR); in jz4780_bch_write_data()
103 writeb(*src8++, bch->base + BCH_BHDR); in jz4780_bch_write_data()
106 static void jz4780_bch_read_parity(struct ingenic_ecc *bch, void *buf, in jz4780_bch_read_parity() argument
117 *dest32++ = readl(bch->base + BCH_BHPAR0 + offset); in jz4780_bch_read_parity()
122 val = readl(bch->base + BCH_BHPAR0 + offset); in jz4780_bch_read_parity()
136 static bool jz4780_bch_wait_complete(struct ingenic_ecc *bch, unsigned int irq, in jz4780_bch_wait_complete() argument
148 ret = readl_poll_timeout(bch->base + BCH_BHINT, reg, in jz4780_bch_wait_complete()
156 writel(reg, bch->base + BCH_BHINT); in jz4780_bch_wait_complete()
160 static int jz4780_calculate(struct ingenic_ecc *bch, in jz4780_calculate() argument
166 mutex_lock(&bch->lock); in jz4780_calculate()
168 jz4780_bch_reset(bch, params, true); in jz4780_calculate()
169 jz4780_bch_write_data(bch, buf, params->size); in jz4780_calculate()
171 if (jz4780_bch_wait_complete(bch, BCH_BHINT_ENCF, NULL)) { in jz4780_calculate()
172 jz4780_bch_read_parity(bch, ecc_code, params->bytes); in jz4780_calculate()
174 dev_err(bch->dev, "timed out while calculating ECC\n"); in jz4780_calculate()
178 jz4780_bch_disable(bch); in jz4780_calculate()
179 mutex_unlock(&bch->lock); in jz4780_calculate()
183 static int jz4780_correct(struct ingenic_ecc *bch, in jz4780_correct() argument
190 mutex_lock(&bch->lock); in jz4780_correct()
192 jz4780_bch_reset(bch, params, false); in jz4780_correct()
193 jz4780_bch_write_data(bch, buf, params->size); in jz4780_correct()
194 jz4780_bch_write_data(bch, ecc_code, params->bytes); in jz4780_correct()
196 if (!jz4780_bch_wait_complete(bch, BCH_BHINT_DECF, ®)) { in jz4780_correct()
197 dev_err(bch->dev, "timed out while correcting data\n"); in jz4780_correct()
203 dev_warn(bch->dev, "uncorrectable ECC error\n"); in jz4780_correct()
214 reg = readl(bch->base + BCH_BHERR0 + (i * 4)); in jz4780_correct()
227 jz4780_bch_disable(bch); in jz4780_correct()
228 mutex_unlock(&bch->lock); in jz4780_correct()
234 struct ingenic_ecc *bch; in jz4780_bch_probe() local
241 bch = platform_get_drvdata(pdev); in jz4780_bch_probe()
242 clk_set_rate(bch->clk, BCH_CLK_RATE); in jz4780_bch_probe()
254 { .compatible = "ingenic,jz4780-bch", .data = &jz4780_bch_ops },
262 .name = "jz4780-bch",
270 MODULE_DESCRIPTION("Ingenic JZ4780 BCH error correction driver");