Lines Matching refs:xsdfec
234 static inline void xsdfec_regwrite(struct xsdfec_dev *xsdfec, u32 addr,
237 dev_dbg(xsdfec->dev, "Writing 0x%x to offset 0x%x", value, addr);
238 iowrite32(value, xsdfec->regs + addr);
241 static inline u32 xsdfec_regread(struct xsdfec_dev *xsdfec, u32 addr)
245 rval = ioread32(xsdfec->regs + addr);
246 dev_dbg(xsdfec->dev, "Read value = 0x%x from offset 0x%x", rval, addr);
250 static void update_bool_config_from_reg(struct xsdfec_dev *xsdfec,
257 reg_val = xsdfec_regread(xsdfec, reg_offset);
261 static void update_config_from_hw(struct xsdfec_dev *xsdfec)
267 reg_value = xsdfec_regread(xsdfec, XSDFEC_ORDER_ADDR);
268 xsdfec->config.order = reg_value;
270 update_bool_config_from_reg(xsdfec, XSDFEC_BYPASS_ADDR,
272 &xsdfec->config.bypass);
274 update_bool_config_from_reg(xsdfec, XSDFEC_CODE_WR_PROTECT_ADDR,
276 &xsdfec->config.code_wr_protect);
278 reg_value = xsdfec_regread(xsdfec, XSDFEC_IMR_ADDR);
279 xsdfec->config.irq.enable_isr = (reg_value & XSDFEC_ISR_MASK) > 0;
281 reg_value = xsdfec_regread(xsdfec, XSDFEC_ECC_IMR_ADDR);
282 xsdfec->config.irq.enable_ecc_isr =
285 reg_value = xsdfec_regread(xsdfec, XSDFEC_AXIS_ENABLE_ADDR);
288 xsdfec->state = XSDFEC_STARTED;
290 xsdfec->state = XSDFEC_STOPPED;
293 static int xsdfec_get_status(struct xsdfec_dev *xsdfec, void __user *arg)
299 spin_lock_irqsave(&xsdfec->error_data_lock, xsdfec->flags);
300 status.state = xsdfec->state;
301 xsdfec->state_updated = false;
302 spin_unlock_irqrestore(&xsdfec->error_data_lock, xsdfec->flags);
303 status.activity = (xsdfec_regread(xsdfec, XSDFEC_ACTIVE_ADDR) &
313 static int xsdfec_get_config(struct xsdfec_dev *xsdfec, void __user *arg)
317 err = copy_to_user(arg, &xsdfec->config, sizeof(xsdfec->config));
324 static int xsdfec_isr_enable(struct xsdfec_dev *xsdfec, bool enable)
330 xsdfec_regwrite(xsdfec, XSDFEC_IER_ADDR, XSDFEC_ISR_MASK);
331 mask_read = xsdfec_regread(xsdfec, XSDFEC_IMR_ADDR);
333 dev_dbg(xsdfec->dev,
339 xsdfec_regwrite(xsdfec, XSDFEC_IDR_ADDR, XSDFEC_ISR_MASK);
340 mask_read = xsdfec_regread(xsdfec, XSDFEC_IMR_ADDR);
342 dev_dbg(xsdfec->dev,
350 static int xsdfec_ecc_isr_enable(struct xsdfec_dev *xsdfec, bool enable)
356 xsdfec_regwrite(xsdfec, XSDFEC_ECC_IER_ADDR,
358 mask_read = xsdfec_regread(xsdfec, XSDFEC_ECC_IMR_ADDR);
360 dev_dbg(xsdfec->dev,
366 xsdfec_regwrite(xsdfec, XSDFEC_ECC_IDR_ADDR,
368 mask_read = xsdfec_regread(xsdfec, XSDFEC_ECC_IMR_ADDR);
373 dev_dbg(xsdfec->dev,
381 static int xsdfec_set_irq(struct xsdfec_dev *xsdfec, void __user *arg)
393 isr_err = xsdfec_isr_enable(xsdfec, irq.enable_isr);
395 xsdfec->config.irq.enable_isr = irq.enable_isr;
398 ecc_err = xsdfec_ecc_isr_enable(xsdfec, irq.enable_ecc_isr);
400 xsdfec->config.irq.enable_ecc_isr = irq.enable_ecc_isr;
408 static int xsdfec_set_turbo(struct xsdfec_dev *xsdfec, void __user *arg)
425 if (xsdfec->config.code == XSDFEC_LDPC_CODE)
431 xsdfec_regwrite(xsdfec, XSDFEC_TURBO_ADDR, turbo_write);
435 static int xsdfec_get_turbo(struct xsdfec_dev *xsdfec, void __user *arg)
441 if (xsdfec->config.code == XSDFEC_LDPC_CODE)
445 reg_value = xsdfec_regread(xsdfec, XSDFEC_TURBO_ADDR);
458 static int xsdfec_reg0_write(struct xsdfec_dev *xsdfec, u32 n, u32 k, u32 psize,
465 dev_dbg(xsdfec->dev, "N value is not in range");
472 dev_dbg(xsdfec->dev, "K value is not in range");
480 dev_dbg(xsdfec->dev, "Writing outside of LDPC reg0 space 0x%x",
485 xsdfec_regwrite(xsdfec,
492 static int xsdfec_reg1_write(struct xsdfec_dev *xsdfec, u32 psize,
498 dev_dbg(xsdfec->dev, "Psize is not in range");
503 dev_dbg(xsdfec->dev, "No-packing bit register invalid");
508 dev_dbg(xsdfec->dev, "NM is beyond 10 bits");
514 dev_dbg(xsdfec->dev, "Writing outside of LDPC reg1 space 0x%x",
519 xsdfec_regwrite(xsdfec,
526 static int xsdfec_reg2_write(struct xsdfec_dev *xsdfec, u32 nlayers, u32 nmqc,
534 dev_dbg(xsdfec->dev, "Nlayers is not in range");
539 dev_dbg(xsdfec->dev, "NMQC exceeds 11 bits");
543 dev_dbg(xsdfec->dev, "Norm type is invalid");
547 dev_dbg(xsdfec->dev, "Special QC in invalid");
552 dev_dbg(xsdfec->dev, "No final parity check invalid");
558 dev_dbg(xsdfec->dev, "Max Schedule exceeds 2 bits");
567 dev_dbg(xsdfec->dev, "Writing outside of LDPC reg2 space 0x%x",
572 xsdfec_regwrite(xsdfec,
579 static int xsdfec_reg3_write(struct xsdfec_dev *xsdfec, u8 sc_off, u8 la_off,
588 dev_dbg(xsdfec->dev, "Writing outside of LDPC reg3 space 0x%x",
593 xsdfec_regwrite(xsdfec,
600 static int xsdfec_table_write(struct xsdfec_dev *xsdfec, u32 offset,
617 dev_dbg(xsdfec->dev, "Write exceeds SC table length");
641 xsdfec_regwrite(xsdfec,
653 static int xsdfec_add_ldpc(struct xsdfec_dev *xsdfec, void __user *arg)
662 if (xsdfec->config.code == XSDFEC_TURBO_CODE) {
668 if (xsdfec->state == XSDFEC_STARTED) {
673 if (xsdfec->config.code_wr_protect) {
679 ret = xsdfec_reg0_write(xsdfec, ldpc->n, ldpc->k, ldpc->psize,
685 ret = xsdfec_reg1_write(xsdfec, ldpc->psize, ldpc->no_packing, ldpc->nm,
691 ret = xsdfec_reg2_write(xsdfec, ldpc->nlayers, ldpc->nmqc,
699 ret = xsdfec_reg3_write(xsdfec, ldpc->sc_off, ldpc->la_off,
709 ret = xsdfec_table_write(xsdfec, ldpc->sc_off, ldpc->sc_table, n,
715 ret = xsdfec_table_write(xsdfec, 4 * ldpc->la_off, ldpc->la_table,
721 ret = xsdfec_table_write(xsdfec, 4 * ldpc->qc_off, ldpc->qc_table,
729 static int xsdfec_set_order(struct xsdfec_dev *xsdfec, void __user *arg)
745 if (xsdfec->state == XSDFEC_STARTED)
748 xsdfec_regwrite(xsdfec, XSDFEC_ORDER_ADDR, order);
750 xsdfec->config.order = order;
755 static int xsdfec_set_bypass(struct xsdfec_dev *xsdfec, bool __user *arg)
765 if (xsdfec->state == XSDFEC_STARTED)
769 xsdfec_regwrite(xsdfec, XSDFEC_BYPASS_ADDR, 1);
771 xsdfec_regwrite(xsdfec, XSDFEC_BYPASS_ADDR, 0);
773 xsdfec->config.bypass = bypass;
778 static int xsdfec_is_active(struct xsdfec_dev *xsdfec, bool __user *arg)
784 reg_value = xsdfec_regread(xsdfec, XSDFEC_ACTIVE_ADDR);
828 static int xsdfec_cfg_axi_streams(struct xsdfec_dev *xsdfec)
835 struct xsdfec_config *config = &xsdfec->config;
852 xsdfec_regwrite(xsdfec, XSDFEC_AXIS_WIDTH_ADDR, reg_value);
867 static int xsdfec_start(struct xsdfec_dev *xsdfec)
871 regread = xsdfec_regread(xsdfec, XSDFEC_FEC_CODE_ADDR);
873 if (regread != xsdfec->config.code) {
874 dev_dbg(xsdfec->dev,
876 __func__, regread, xsdfec->config.code);
881 xsdfec_regwrite(xsdfec, XSDFEC_AXIS_ENABLE_ADDR,
884 xsdfec->state = XSDFEC_STARTED;
888 static int xsdfec_stop(struct xsdfec_dev *xsdfec)
892 if (xsdfec->state != XSDFEC_STARTED)
893 dev_dbg(xsdfec->dev, "Device not started correctly");
895 regread = xsdfec_regread(xsdfec, XSDFEC_AXIS_ENABLE_ADDR);
897 xsdfec_regwrite(xsdfec, XSDFEC_AXIS_ENABLE_ADDR, regread);
899 xsdfec->state = XSDFEC_STOPPED;
903 static int xsdfec_clear_stats(struct xsdfec_dev *xsdfec)
905 spin_lock_irqsave(&xsdfec->error_data_lock, xsdfec->flags);
906 xsdfec->isr_err_count = 0;
907 xsdfec->uecc_count = 0;
908 xsdfec->cecc_count = 0;
909 spin_unlock_irqrestore(&xsdfec->error_data_lock, xsdfec->flags);
914 static int xsdfec_get_stats(struct xsdfec_dev *xsdfec, void __user *arg)
919 spin_lock_irqsave(&xsdfec->error_data_lock, xsdfec->flags);
920 user_stats.isr_err_count = xsdfec->isr_err_count;
921 user_stats.cecc_count = xsdfec->cecc_count;
922 user_stats.uecc_count = xsdfec->uecc_count;
923 xsdfec->stats_updated = false;
924 spin_unlock_irqrestore(&xsdfec->error_data_lock, xsdfec->flags);
933 static int xsdfec_set_default_config(struct xsdfec_dev *xsdfec)
936 xsdfec_regwrite(xsdfec, XSDFEC_FEC_CODE_ADDR, xsdfec->config.code);
937 xsdfec_cfg_axi_streams(xsdfec);
938 update_config_from_hw(xsdfec);
946 struct xsdfec_dev *xsdfec;
950 xsdfec = container_of(fptr->private_data, struct xsdfec_dev, miscdev);
953 if (xsdfec->state == XSDFEC_NEEDS_RESET &&
971 rval = xsdfec_start(xsdfec);
974 rval = xsdfec_stop(xsdfec);
977 rval = xsdfec_clear_stats(xsdfec);
980 rval = xsdfec_get_stats(xsdfec, arg);
983 rval = xsdfec_get_status(xsdfec, arg);
986 rval = xsdfec_get_config(xsdfec, arg);
989 rval = xsdfec_set_default_config(xsdfec);
992 rval = xsdfec_set_irq(xsdfec, arg);
995 rval = xsdfec_set_turbo(xsdfec, arg);
998 rval = xsdfec_get_turbo(xsdfec, arg);
1001 rval = xsdfec_add_ldpc(xsdfec, arg);
1004 rval = xsdfec_set_order(xsdfec, arg);
1007 rval = xsdfec_set_bypass(xsdfec, arg);
1010 rval = xsdfec_is_active(xsdfec, (bool __user *)arg);
1030 struct xsdfec_dev *xsdfec;
1032 xsdfec = container_of(file->private_data, struct xsdfec_dev, miscdev);
1034 if (!xsdfec)
1037 poll_wait(file, &xsdfec->waitq, wait);
1040 spin_lock_irqsave(&xsdfec->error_data_lock, xsdfec->flags);
1041 if (xsdfec->state_updated)
1044 if (xsdfec->stats_updated)
1046 spin_unlock_irqrestore(&xsdfec->error_data_lock, xsdfec->flags);
1062 static int xsdfec_parse_of(struct xsdfec_dev *xsdfec)
1064 struct device *dev = xsdfec->dev;
1078 xsdfec->config.code = XSDFEC_LDPC_CODE;
1080 xsdfec->config.code = XSDFEC_TURBO_CODE;
1090 xsdfec->config.din_word_include = din_word_include;
1103 xsdfec->config.din_width = din_width;
1115 xsdfec->config.dout_word_include = dout_word_include;
1128 xsdfec->config.dout_width = dout_width;
1135 xsdfec_regwrite(xsdfec, XSDFEC_FEC_CODE_ADDR, xsdfec->config.code);
1137 xsdfec_cfg_axi_streams(xsdfec);
1144 struct xsdfec_dev *xsdfec = dev_id;
1154 WARN_ON(xsdfec->irq != irq);
1157 xsdfec_isr_enable(xsdfec, false);
1158 xsdfec_ecc_isr_enable(xsdfec, false);
1160 ecc_err = xsdfec_regread(xsdfec, XSDFEC_ECC_ISR_ADDR);
1161 isr_err = xsdfec_regread(xsdfec, XSDFEC_ISR_ADDR);
1163 xsdfec_regwrite(xsdfec, XSDFEC_ECC_ISR_ADDR, ecc_err);
1164 xsdfec_regwrite(xsdfec, XSDFEC_ISR_ADDR, isr_err);
1175 dev_dbg(xsdfec->dev, "tmp=%x, uecc=%x, aecc=%x, cecc=%x, isr=%x", tmp,
1177 dev_dbg(xsdfec->dev, "uecc=%x, cecc=%x, isr=%x", xsdfec->uecc_count,
1178 xsdfec->cecc_count, xsdfec->isr_err_count);
1180 spin_lock_irqsave(&xsdfec->error_data_lock, xsdfec->flags);
1183 xsdfec->uecc_count += uecc_count;
1186 xsdfec->cecc_count += cecc_count;
1189 xsdfec->isr_err_count += isr_err_count;
1194 xsdfec->state = XSDFEC_NEEDS_RESET;
1196 xsdfec->state = XSDFEC_PL_RECONFIGURE;
1197 xsdfec->stats_updated = true;
1198 xsdfec->state_updated = true;
1202 xsdfec->stats_updated = true;
1205 xsdfec->state = XSDFEC_NEEDS_RESET;
1206 xsdfec->stats_updated = true;
1207 xsdfec->state_updated = true;
1210 spin_unlock_irqrestore(&xsdfec->error_data_lock, xsdfec->flags);
1211 dev_dbg(xsdfec->dev, "state=%x, stats=%x", xsdfec->state_updated,
1212 xsdfec->stats_updated);
1215 if (xsdfec->state_updated || xsdfec->stats_updated)
1216 wake_up_interruptible(&xsdfec->waitq);
1221 xsdfec_isr_enable(xsdfec, true);
1222 xsdfec_ecc_isr_enable(xsdfec, true);
1382 struct xsdfec_dev *xsdfec;
1388 xsdfec = devm_kzalloc(&pdev->dev, sizeof(*xsdfec), GFP_KERNEL);
1389 if (!xsdfec)
1392 xsdfec->dev = &pdev->dev;
1393 spin_lock_init(&xsdfec->error_data_lock);
1395 err = xsdfec_clk_init(pdev, &xsdfec->clks);
1399 dev = xsdfec->dev;
1401 xsdfec->regs = devm_ioremap_resource(dev, res);
1402 if (IS_ERR(xsdfec->regs)) {
1403 err = PTR_ERR(xsdfec->regs);
1407 xsdfec->irq = platform_get_irq(pdev, 0);
1408 if (xsdfec->irq < 0) {
1413 err = xsdfec_parse_of(xsdfec);
1417 update_config_from_hw(xsdfec);
1420 platform_set_drvdata(pdev, xsdfec);
1423 init_waitqueue_head(&xsdfec->waitq);
1425 err = devm_request_threaded_irq(dev, xsdfec->irq, NULL,
1427 "xilinx-sdfec16", xsdfec);
1429 dev_err(dev, "unable to request IRQ%d", xsdfec->irq);
1437 xsdfec->dev_id = err;
1439 snprintf(xsdfec->dev_name, DEV_NAME_LEN, "xsdfec%d", xsdfec->dev_id);
1440 xsdfec->miscdev.minor = MISC_DYNAMIC_MINOR;
1441 xsdfec->miscdev.name = xsdfec->dev_name;
1442 xsdfec->miscdev.fops = &xsdfec_fops;
1443 xsdfec->miscdev.parent = dev;
1444 err = misc_register(&xsdfec->miscdev);
1452 ida_free(&dev_nrs, xsdfec->dev_id);
1454 xsdfec_disable_all_clks(&xsdfec->clks);
1460 struct xsdfec_dev *xsdfec;
1462 xsdfec = platform_get_drvdata(pdev);
1463 misc_deregister(&xsdfec->miscdev);
1464 ida_free(&dev_nrs, xsdfec->dev_id);
1465 xsdfec_disable_all_clks(&xsdfec->clks);