1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Xilinx SDFEC 4 * 5 * Copyright (C) 2019 Xilinx, Inc. 6 * 7 * Description: 8 * This driver is developed for SDFEC16 (Soft Decision FEC 16nm) 9 * IP. It exposes a char device which supports file operations 10 * like open(), close() and ioctl(). 11 */ 12 13 #include <linux/miscdevice.h> 14 #include <linux/io.h> 15 #include <linux/interrupt.h> 16 #include <linux/kernel.h> 17 #include <linux/module.h> 18 #include <linux/of_platform.h> 19 #include <linux/poll.h> 20 #include <linux/slab.h> 21 #include <linux/clk.h> 22 #include <linux/compat.h> 23 #include <linux/highmem.h> 24 25 #include <uapi/misc/xilinx_sdfec.h> 26 27 #define DEV_NAME_LEN 12 28 29 static struct idr dev_idr; 30 static struct mutex dev_idr_lock; 31 32 /* Xilinx SDFEC Register Map */ 33 /* CODE_WRI_PROTECT Register */ 34 #define XSDFEC_CODE_WR_PROTECT_ADDR (0x4) 35 36 /* ACTIVE Register */ 37 #define XSDFEC_ACTIVE_ADDR (0x8) 38 #define XSDFEC_IS_ACTIVITY_SET (0x1) 39 40 /* AXIS_WIDTH Register */ 41 #define XSDFEC_AXIS_WIDTH_ADDR (0xC) 42 #define XSDFEC_AXIS_DOUT_WORDS_LSB (5) 43 #define XSDFEC_AXIS_DOUT_WIDTH_LSB (3) 44 #define XSDFEC_AXIS_DIN_WORDS_LSB (2) 45 #define XSDFEC_AXIS_DIN_WIDTH_LSB (0) 46 47 /* AXIS_ENABLE Register */ 48 #define XSDFEC_AXIS_ENABLE_ADDR (0x10) 49 #define XSDFEC_AXIS_OUT_ENABLE_MASK (0x38) 50 #define XSDFEC_AXIS_IN_ENABLE_MASK (0x7) 51 #define XSDFEC_AXIS_ENABLE_MASK \ 52 (XSDFEC_AXIS_OUT_ENABLE_MASK | XSDFEC_AXIS_IN_ENABLE_MASK) 53 54 /* FEC_CODE Register */ 55 #define XSDFEC_FEC_CODE_ADDR (0x14) 56 57 /* ORDER Register Map */ 58 #define XSDFEC_ORDER_ADDR (0x18) 59 60 /* Interrupt Status Register */ 61 #define XSDFEC_ISR_ADDR (0x1C) 62 /* Interrupt Status Register Bit Mask */ 63 #define XSDFEC_ISR_MASK (0x3F) 64 65 /* Write Only - Interrupt Enable Register */ 66 #define XSDFEC_IER_ADDR (0x20) 67 /* Write Only - Interrupt Disable Register */ 68 #define XSDFEC_IDR_ADDR (0x24) 69 /* Read Only - Interrupt Mask Register */ 70 #define XSDFEC_IMR_ADDR (0x28) 71 72 /* ECC Interrupt Status Register */ 73 #define XSDFEC_ECC_ISR_ADDR (0x2C) 74 /* Single Bit Errors */ 75 #define XSDFEC_ECC_ISR_SBE_MASK (0x7FF) 76 /* PL Initialize Single Bit Errors */ 77 #define XSDFEC_PL_INIT_ECC_ISR_SBE_MASK (0x3C00000) 78 /* Multi Bit Errors */ 79 #define XSDFEC_ECC_ISR_MBE_MASK (0x3FF800) 80 /* PL Initialize Multi Bit Errors */ 81 #define XSDFEC_PL_INIT_ECC_ISR_MBE_MASK (0x3C000000) 82 /* Multi Bit Error to Event Shift */ 83 #define XSDFEC_ECC_ISR_MBE_TO_EVENT_SHIFT (11) 84 /* PL Initialize Multi Bit Error to Event Shift */ 85 #define XSDFEC_PL_INIT_ECC_ISR_MBE_TO_EVENT_SHIFT (4) 86 /* ECC Interrupt Status Bit Mask */ 87 #define XSDFEC_ECC_ISR_MASK (XSDFEC_ECC_ISR_SBE_MASK | XSDFEC_ECC_ISR_MBE_MASK) 88 /* ECC Interrupt Status PL Initialize Bit Mask */ 89 #define XSDFEC_PL_INIT_ECC_ISR_MASK \ 90 (XSDFEC_PL_INIT_ECC_ISR_SBE_MASK | XSDFEC_PL_INIT_ECC_ISR_MBE_MASK) 91 /* ECC Interrupt Status All Bit Mask */ 92 #define XSDFEC_ALL_ECC_ISR_MASK \ 93 (XSDFEC_ECC_ISR_MASK | XSDFEC_PL_INIT_ECC_ISR_MASK) 94 /* ECC Interrupt Status Single Bit Errors Mask */ 95 #define XSDFEC_ALL_ECC_ISR_SBE_MASK \ 96 (XSDFEC_ECC_ISR_SBE_MASK | XSDFEC_PL_INIT_ECC_ISR_SBE_MASK) 97 /* ECC Interrupt Status Multi Bit Errors Mask */ 98 #define XSDFEC_ALL_ECC_ISR_MBE_MASK \ 99 (XSDFEC_ECC_ISR_MBE_MASK | XSDFEC_PL_INIT_ECC_ISR_MBE_MASK) 100 101 /* Write Only - ECC Interrupt Enable Register */ 102 #define XSDFEC_ECC_IER_ADDR (0x30) 103 /* Write Only - ECC Interrupt Disable Register */ 104 #define XSDFEC_ECC_IDR_ADDR (0x34) 105 /* Read Only - ECC Interrupt Mask Register */ 106 #define XSDFEC_ECC_IMR_ADDR (0x38) 107 108 /* BYPASS Register */ 109 #define XSDFEC_BYPASS_ADDR (0x3C) 110 111 /* Turbo Code Register */ 112 #define XSDFEC_TURBO_ADDR (0x100) 113 #define XSDFEC_TURBO_SCALE_MASK (0xFFF) 114 #define XSDFEC_TURBO_SCALE_BIT_POS (8) 115 #define XSDFEC_TURBO_SCALE_MAX (15) 116 117 /* REG0 Register */ 118 #define XSDFEC_LDPC_CODE_REG0_ADDR_BASE (0x2000) 119 #define XSDFEC_LDPC_CODE_REG0_ADDR_HIGH (0x27F0) 120 #define XSDFEC_REG0_N_MIN (4) 121 #define XSDFEC_REG0_N_MAX (32768) 122 #define XSDFEC_REG0_N_MUL_P (256) 123 #define XSDFEC_REG0_N_LSB (0) 124 #define XSDFEC_REG0_K_MIN (2) 125 #define XSDFEC_REG0_K_MAX (32766) 126 #define XSDFEC_REG0_K_MUL_P (256) 127 #define XSDFEC_REG0_K_LSB (16) 128 129 /* REG1 Register */ 130 #define XSDFEC_LDPC_CODE_REG1_ADDR_BASE (0x2004) 131 #define XSDFEC_LDPC_CODE_REG1_ADDR_HIGH (0x27f4) 132 #define XSDFEC_REG1_PSIZE_MIN (2) 133 #define XSDFEC_REG1_PSIZE_MAX (512) 134 #define XSDFEC_REG1_NO_PACKING_MASK (0x400) 135 #define XSDFEC_REG1_NO_PACKING_LSB (10) 136 #define XSDFEC_REG1_NM_MASK (0xFF800) 137 #define XSDFEC_REG1_NM_LSB (11) 138 #define XSDFEC_REG1_BYPASS_MASK (0x100000) 139 140 /* REG2 Register */ 141 #define XSDFEC_LDPC_CODE_REG2_ADDR_BASE (0x2008) 142 #define XSDFEC_LDPC_CODE_REG2_ADDR_HIGH (0x27f8) 143 #define XSDFEC_REG2_NLAYERS_MIN (1) 144 #define XSDFEC_REG2_NLAYERS_MAX (256) 145 #define XSDFEC_REG2_NNMQC_MASK (0xFFE00) 146 #define XSDFEC_REG2_NMQC_LSB (9) 147 #define XSDFEC_REG2_NORM_TYPE_MASK (0x100000) 148 #define XSDFEC_REG2_NORM_TYPE_LSB (20) 149 #define XSDFEC_REG2_SPECIAL_QC_MASK (0x200000) 150 #define XSDFEC_REG2_SPEICAL_QC_LSB (21) 151 #define XSDFEC_REG2_NO_FINAL_PARITY_MASK (0x400000) 152 #define XSDFEC_REG2_NO_FINAL_PARITY_LSB (22) 153 #define XSDFEC_REG2_MAX_SCHEDULE_MASK (0x1800000) 154 #define XSDFEC_REG2_MAX_SCHEDULE_LSB (23) 155 156 /* REG3 Register */ 157 #define XSDFEC_LDPC_CODE_REG3_ADDR_BASE (0x200C) 158 #define XSDFEC_LDPC_CODE_REG3_ADDR_HIGH (0x27FC) 159 #define XSDFEC_REG3_LA_OFF_LSB (8) 160 #define XSDFEC_REG3_QC_OFF_LSB (16) 161 162 #define XSDFEC_LDPC_REG_JUMP (0x10) 163 #define XSDFEC_REG_WIDTH_JUMP (4) 164 165 /* The maximum number of pinned pages */ 166 #define MAX_NUM_PAGES ((XSDFEC_QC_TABLE_DEPTH / PAGE_SIZE) + 1) 167 168 /** 169 * struct xsdfec_clks - For managing SD-FEC clocks 170 * @core_clk: Main processing clock for core 171 * @axi_clk: AXI4-Lite memory-mapped clock 172 * @din_words_clk: DIN Words AXI4-Stream Slave clock 173 * @din_clk: DIN AXI4-Stream Slave clock 174 * @dout_clk: DOUT Words AXI4-Stream Slave clock 175 * @dout_words_clk: DOUT AXI4-Stream Slave clock 176 * @ctrl_clk: Control AXI4-Stream Slave clock 177 * @status_clk: Status AXI4-Stream Slave clock 178 */ 179 struct xsdfec_clks { 180 struct clk *core_clk; 181 struct clk *axi_clk; 182 struct clk *din_words_clk; 183 struct clk *din_clk; 184 struct clk *dout_clk; 185 struct clk *dout_words_clk; 186 struct clk *ctrl_clk; 187 struct clk *status_clk; 188 }; 189 190 /** 191 * struct xsdfec_dev - Driver data for SDFEC 192 * @miscdev: Misc device handle 193 * @clks: Clocks managed by the SDFEC driver 194 * @waitq: Driver wait queue 195 * @config: Configuration of the SDFEC device 196 * @dev_name: Device name 197 * @flags: spinlock flags 198 * @regs: device physical base address 199 * @dev: pointer to device struct 200 * @state: State of the SDFEC device 201 * @error_data_lock: Error counter and states spinlock 202 * @dev_id: Device ID 203 * @isr_err_count: Count of ISR errors 204 * @cecc_count: Count of Correctable ECC errors (SBE) 205 * @uecc_count: Count of Uncorrectable ECC errors (MBE) 206 * @irq: IRQ number 207 * @state_updated: indicates State updated by interrupt handler 208 * @stats_updated: indicates Stats updated by interrupt handler 209 * @intr_enabled: indicates IRQ enabled 210 * 211 * This structure contains necessary state for SDFEC driver to operate 212 */ 213 struct xsdfec_dev { 214 struct miscdevice miscdev; 215 struct xsdfec_clks clks; 216 wait_queue_head_t waitq; 217 struct xsdfec_config config; 218 char dev_name[DEV_NAME_LEN]; 219 unsigned long flags; 220 void __iomem *regs; 221 struct device *dev; 222 enum xsdfec_state state; 223 /* Spinlock to protect state_updated and stats_updated */ 224 spinlock_t error_data_lock; 225 int dev_id; 226 u32 isr_err_count; 227 u32 cecc_count; 228 u32 uecc_count; 229 int irq; 230 bool state_updated; 231 bool stats_updated; 232 bool intr_enabled; 233 }; 234 235 static inline void xsdfec_regwrite(struct xsdfec_dev *xsdfec, u32 addr, 236 u32 value) 237 { 238 dev_dbg(xsdfec->dev, "Writing 0x%x to offset 0x%x", value, addr); 239 iowrite32(value, xsdfec->regs + addr); 240 } 241 242 static inline u32 xsdfec_regread(struct xsdfec_dev *xsdfec, u32 addr) 243 { 244 u32 rval; 245 246 rval = ioread32(xsdfec->regs + addr); 247 dev_dbg(xsdfec->dev, "Read value = 0x%x from offset 0x%x", rval, addr); 248 return rval; 249 } 250 251 static void update_bool_config_from_reg(struct xsdfec_dev *xsdfec, 252 u32 reg_offset, u32 bit_num, 253 char *config_value) 254 { 255 u32 reg_val; 256 u32 bit_mask = 1 << bit_num; 257 258 reg_val = xsdfec_regread(xsdfec, reg_offset); 259 *config_value = (reg_val & bit_mask) > 0; 260 } 261 262 static void update_config_from_hw(struct xsdfec_dev *xsdfec) 263 { 264 u32 reg_value; 265 bool sdfec_started; 266 267 /* Update the Order */ 268 reg_value = xsdfec_regread(xsdfec, XSDFEC_ORDER_ADDR); 269 xsdfec->config.order = reg_value; 270 271 update_bool_config_from_reg(xsdfec, XSDFEC_BYPASS_ADDR, 272 0, /* Bit Number, maybe change to mask */ 273 &xsdfec->config.bypass); 274 275 update_bool_config_from_reg(xsdfec, XSDFEC_CODE_WR_PROTECT_ADDR, 276 0, /* Bit Number */ 277 &xsdfec->config.code_wr_protect); 278 279 reg_value = xsdfec_regread(xsdfec, XSDFEC_IMR_ADDR); 280 xsdfec->config.irq.enable_isr = (reg_value & XSDFEC_ISR_MASK) > 0; 281 282 reg_value = xsdfec_regread(xsdfec, XSDFEC_ECC_IMR_ADDR); 283 xsdfec->config.irq.enable_ecc_isr = 284 (reg_value & XSDFEC_ECC_ISR_MASK) > 0; 285 286 reg_value = xsdfec_regread(xsdfec, XSDFEC_AXIS_ENABLE_ADDR); 287 sdfec_started = (reg_value & XSDFEC_AXIS_IN_ENABLE_MASK) > 0; 288 if (sdfec_started) 289 xsdfec->state = XSDFEC_STARTED; 290 else 291 xsdfec->state = XSDFEC_STOPPED; 292 } 293 294 static int xsdfec_get_status(struct xsdfec_dev *xsdfec, void __user *arg) 295 { 296 struct xsdfec_status status; 297 int err; 298 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) & 304 XSDFEC_IS_ACTIVITY_SET); 305 306 err = copy_to_user(arg, &status, sizeof(status)); 307 if (err) 308 err = -EFAULT; 309 310 return err; 311 } 312 313 static int xsdfec_get_config(struct xsdfec_dev *xsdfec, void __user *arg) 314 { 315 int err; 316 317 err = copy_to_user(arg, &xsdfec->config, sizeof(xsdfec->config)); 318 if (err) 319 err = -EFAULT; 320 321 return err; 322 } 323 324 static int xsdfec_isr_enable(struct xsdfec_dev *xsdfec, bool enable) 325 { 326 u32 mask_read; 327 328 if (enable) { 329 /* Enable */ 330 xsdfec_regwrite(xsdfec, XSDFEC_IER_ADDR, XSDFEC_ISR_MASK); 331 mask_read = xsdfec_regread(xsdfec, XSDFEC_IMR_ADDR); 332 if (mask_read & XSDFEC_ISR_MASK) { 333 dev_dbg(xsdfec->dev, 334 "SDFEC enabling irq with IER failed"); 335 return -EIO; 336 } 337 } else { 338 /* Disable */ 339 xsdfec_regwrite(xsdfec, XSDFEC_IDR_ADDR, XSDFEC_ISR_MASK); 340 mask_read = xsdfec_regread(xsdfec, XSDFEC_IMR_ADDR); 341 if ((mask_read & XSDFEC_ISR_MASK) != XSDFEC_ISR_MASK) { 342 dev_dbg(xsdfec->dev, 343 "SDFEC disabling irq with IDR failed"); 344 return -EIO; 345 } 346 } 347 return 0; 348 } 349 350 static int xsdfec_ecc_isr_enable(struct xsdfec_dev *xsdfec, bool enable) 351 { 352 u32 mask_read; 353 354 if (enable) { 355 /* Enable */ 356 xsdfec_regwrite(xsdfec, XSDFEC_ECC_IER_ADDR, 357 XSDFEC_ALL_ECC_ISR_MASK); 358 mask_read = xsdfec_regread(xsdfec, XSDFEC_ECC_IMR_ADDR); 359 if (mask_read & XSDFEC_ALL_ECC_ISR_MASK) { 360 dev_dbg(xsdfec->dev, 361 "SDFEC enabling ECC irq with ECC IER failed"); 362 return -EIO; 363 } 364 } else { 365 /* Disable */ 366 xsdfec_regwrite(xsdfec, XSDFEC_ECC_IDR_ADDR, 367 XSDFEC_ALL_ECC_ISR_MASK); 368 mask_read = xsdfec_regread(xsdfec, XSDFEC_ECC_IMR_ADDR); 369 if (!(((mask_read & XSDFEC_ALL_ECC_ISR_MASK) == 370 XSDFEC_ECC_ISR_MASK) || 371 ((mask_read & XSDFEC_ALL_ECC_ISR_MASK) == 372 XSDFEC_PL_INIT_ECC_ISR_MASK))) { 373 dev_dbg(xsdfec->dev, 374 "SDFEC disable ECC irq with ECC IDR failed"); 375 return -EIO; 376 } 377 } 378 return 0; 379 } 380 381 static int xsdfec_set_irq(struct xsdfec_dev *xsdfec, void __user *arg) 382 { 383 struct xsdfec_irq irq; 384 int err; 385 int isr_err; 386 int ecc_err; 387 388 err = copy_from_user(&irq, arg, sizeof(irq)); 389 if (err) 390 return -EFAULT; 391 392 /* Setup tlast related IRQ */ 393 isr_err = xsdfec_isr_enable(xsdfec, irq.enable_isr); 394 if (!isr_err) 395 xsdfec->config.irq.enable_isr = irq.enable_isr; 396 397 /* Setup ECC related IRQ */ 398 ecc_err = xsdfec_ecc_isr_enable(xsdfec, irq.enable_ecc_isr); 399 if (!ecc_err) 400 xsdfec->config.irq.enable_ecc_isr = irq.enable_ecc_isr; 401 402 if (isr_err < 0 || ecc_err < 0) 403 err = -EIO; 404 405 return err; 406 } 407 408 static int xsdfec_set_turbo(struct xsdfec_dev *xsdfec, void __user *arg) 409 { 410 struct xsdfec_turbo turbo; 411 int err; 412 u32 turbo_write; 413 414 err = copy_from_user(&turbo, arg, sizeof(turbo)); 415 if (err) 416 return -EFAULT; 417 418 if (turbo.alg >= XSDFEC_TURBO_ALG_MAX) 419 return -EINVAL; 420 421 if (turbo.scale > XSDFEC_TURBO_SCALE_MAX) 422 return -EINVAL; 423 424 /* Check to see what device tree says about the FEC codes */ 425 if (xsdfec->config.code == XSDFEC_LDPC_CODE) 426 return -EIO; 427 428 turbo_write = ((turbo.scale & XSDFEC_TURBO_SCALE_MASK) 429 << XSDFEC_TURBO_SCALE_BIT_POS) | 430 turbo.alg; 431 xsdfec_regwrite(xsdfec, XSDFEC_TURBO_ADDR, turbo_write); 432 return err; 433 } 434 435 static int xsdfec_get_turbo(struct xsdfec_dev *xsdfec, void __user *arg) 436 { 437 u32 reg_value; 438 struct xsdfec_turbo turbo_params; 439 int err; 440 441 if (xsdfec->config.code == XSDFEC_LDPC_CODE) 442 return -EIO; 443 444 reg_value = xsdfec_regread(xsdfec, XSDFEC_TURBO_ADDR); 445 446 turbo_params.scale = (reg_value & XSDFEC_TURBO_SCALE_MASK) >> 447 XSDFEC_TURBO_SCALE_BIT_POS; 448 turbo_params.alg = reg_value & 0x1; 449 450 err = copy_to_user(arg, &turbo_params, sizeof(turbo_params)); 451 if (err) 452 err = -EFAULT; 453 454 return err; 455 } 456 457 static int xsdfec_reg0_write(struct xsdfec_dev *xsdfec, u32 n, u32 k, u32 psize, 458 u32 offset) 459 { 460 u32 wdata; 461 462 if (n < XSDFEC_REG0_N_MIN || n > XSDFEC_REG0_N_MAX || 463 (n > XSDFEC_REG0_N_MUL_P * psize) || n <= k || ((n % psize) != 0)) { 464 dev_dbg(xsdfec->dev, "N value is not in range"); 465 return -EINVAL; 466 } 467 n <<= XSDFEC_REG0_N_LSB; 468 469 if (k < XSDFEC_REG0_K_MIN || k > XSDFEC_REG0_K_MAX || 470 (k > XSDFEC_REG0_K_MUL_P * psize) || ((k % psize) != 0)) { 471 dev_dbg(xsdfec->dev, "K value is not in range"); 472 return -EINVAL; 473 } 474 k = k << XSDFEC_REG0_K_LSB; 475 wdata = k | n; 476 477 if (XSDFEC_LDPC_CODE_REG0_ADDR_BASE + (offset * XSDFEC_LDPC_REG_JUMP) > 478 XSDFEC_LDPC_CODE_REG0_ADDR_HIGH) { 479 dev_dbg(xsdfec->dev, "Writing outside of LDPC reg0 space 0x%x", 480 XSDFEC_LDPC_CODE_REG0_ADDR_BASE + 481 (offset * XSDFEC_LDPC_REG_JUMP)); 482 return -EINVAL; 483 } 484 xsdfec_regwrite(xsdfec, 485 XSDFEC_LDPC_CODE_REG0_ADDR_BASE + 486 (offset * XSDFEC_LDPC_REG_JUMP), 487 wdata); 488 return 0; 489 } 490 491 static int xsdfec_reg1_write(struct xsdfec_dev *xsdfec, u32 psize, 492 u32 no_packing, u32 nm, u32 offset) 493 { 494 u32 wdata; 495 496 if (psize < XSDFEC_REG1_PSIZE_MIN || psize > XSDFEC_REG1_PSIZE_MAX) { 497 dev_dbg(xsdfec->dev, "Psize is not in range"); 498 return -EINVAL; 499 } 500 501 if (no_packing != 0 && no_packing != 1) 502 dev_dbg(xsdfec->dev, "No-packing bit register invalid"); 503 no_packing = ((no_packing << XSDFEC_REG1_NO_PACKING_LSB) & 504 XSDFEC_REG1_NO_PACKING_MASK); 505 506 if (nm & ~(XSDFEC_REG1_NM_MASK >> XSDFEC_REG1_NM_LSB)) 507 dev_dbg(xsdfec->dev, "NM is beyond 10 bits"); 508 nm = (nm << XSDFEC_REG1_NM_LSB) & XSDFEC_REG1_NM_MASK; 509 510 wdata = nm | no_packing | psize; 511 if (XSDFEC_LDPC_CODE_REG1_ADDR_BASE + (offset * XSDFEC_LDPC_REG_JUMP) > 512 XSDFEC_LDPC_CODE_REG1_ADDR_HIGH) { 513 dev_dbg(xsdfec->dev, "Writing outside of LDPC reg1 space 0x%x", 514 XSDFEC_LDPC_CODE_REG1_ADDR_BASE + 515 (offset * XSDFEC_LDPC_REG_JUMP)); 516 return -EINVAL; 517 } 518 xsdfec_regwrite(xsdfec, 519 XSDFEC_LDPC_CODE_REG1_ADDR_BASE + 520 (offset * XSDFEC_LDPC_REG_JUMP), 521 wdata); 522 return 0; 523 } 524 525 static int xsdfec_reg2_write(struct xsdfec_dev *xsdfec, u32 nlayers, u32 nmqc, 526 u32 norm_type, u32 special_qc, u32 no_final_parity, 527 u32 max_schedule, u32 offset) 528 { 529 u32 wdata; 530 531 if (nlayers < XSDFEC_REG2_NLAYERS_MIN || 532 nlayers > XSDFEC_REG2_NLAYERS_MAX) { 533 dev_dbg(xsdfec->dev, "Nlayers is not in range"); 534 return -EINVAL; 535 } 536 537 if (nmqc & ~(XSDFEC_REG2_NNMQC_MASK >> XSDFEC_REG2_NMQC_LSB)) 538 dev_dbg(xsdfec->dev, "NMQC exceeds 11 bits"); 539 nmqc = (nmqc << XSDFEC_REG2_NMQC_LSB) & XSDFEC_REG2_NNMQC_MASK; 540 541 if (norm_type > 1) 542 dev_dbg(xsdfec->dev, "Norm type is invalid"); 543 norm_type = ((norm_type << XSDFEC_REG2_NORM_TYPE_LSB) & 544 XSDFEC_REG2_NORM_TYPE_MASK); 545 if (special_qc > 1) 546 dev_dbg(xsdfec->dev, "Special QC in invalid"); 547 special_qc = ((special_qc << XSDFEC_REG2_SPEICAL_QC_LSB) & 548 XSDFEC_REG2_SPECIAL_QC_MASK); 549 550 if (no_final_parity > 1) 551 dev_dbg(xsdfec->dev, "No final parity check invalid"); 552 no_final_parity = 553 ((no_final_parity << XSDFEC_REG2_NO_FINAL_PARITY_LSB) & 554 XSDFEC_REG2_NO_FINAL_PARITY_MASK); 555 if (max_schedule & 556 ~(XSDFEC_REG2_MAX_SCHEDULE_MASK >> XSDFEC_REG2_MAX_SCHEDULE_LSB)) 557 dev_dbg(xsdfec->dev, "Max Schdule exceeds 2 bits"); 558 max_schedule = ((max_schedule << XSDFEC_REG2_MAX_SCHEDULE_LSB) & 559 XSDFEC_REG2_MAX_SCHEDULE_MASK); 560 561 wdata = (max_schedule | no_final_parity | special_qc | norm_type | 562 nmqc | nlayers); 563 564 if (XSDFEC_LDPC_CODE_REG2_ADDR_BASE + (offset * XSDFEC_LDPC_REG_JUMP) > 565 XSDFEC_LDPC_CODE_REG2_ADDR_HIGH) { 566 dev_dbg(xsdfec->dev, "Writing outside of LDPC reg2 space 0x%x", 567 XSDFEC_LDPC_CODE_REG2_ADDR_BASE + 568 (offset * XSDFEC_LDPC_REG_JUMP)); 569 return -EINVAL; 570 } 571 xsdfec_regwrite(xsdfec, 572 XSDFEC_LDPC_CODE_REG2_ADDR_BASE + 573 (offset * XSDFEC_LDPC_REG_JUMP), 574 wdata); 575 return 0; 576 } 577 578 static int xsdfec_reg3_write(struct xsdfec_dev *xsdfec, u8 sc_off, u8 la_off, 579 u16 qc_off, u32 offset) 580 { 581 u32 wdata; 582 583 wdata = ((qc_off << XSDFEC_REG3_QC_OFF_LSB) | 584 (la_off << XSDFEC_REG3_LA_OFF_LSB) | sc_off); 585 if (XSDFEC_LDPC_CODE_REG3_ADDR_BASE + (offset * XSDFEC_LDPC_REG_JUMP) > 586 XSDFEC_LDPC_CODE_REG3_ADDR_HIGH) { 587 dev_dbg(xsdfec->dev, "Writing outside of LDPC reg3 space 0x%x", 588 XSDFEC_LDPC_CODE_REG3_ADDR_BASE + 589 (offset * XSDFEC_LDPC_REG_JUMP)); 590 return -EINVAL; 591 } 592 xsdfec_regwrite(xsdfec, 593 XSDFEC_LDPC_CODE_REG3_ADDR_BASE + 594 (offset * XSDFEC_LDPC_REG_JUMP), 595 wdata); 596 return 0; 597 } 598 599 static int xsdfec_table_write(struct xsdfec_dev *xsdfec, u32 offset, 600 u32 *src_ptr, u32 len, const u32 base_addr, 601 const u32 depth) 602 { 603 u32 reg = 0; 604 u32 res; 605 u32 n, i; 606 u32 *addr = NULL; 607 struct page *page[MAX_NUM_PAGES]; 608 609 /* 610 * Writes that go beyond the length of 611 * Shared Scale(SC) table should fail 612 */ 613 if ((XSDFEC_REG_WIDTH_JUMP * (offset + len)) > depth) { 614 dev_dbg(xsdfec->dev, "Write exceeds SC table length"); 615 return -EINVAL; 616 } 617 618 n = (len * XSDFEC_REG_WIDTH_JUMP) / PAGE_SIZE; 619 if ((len * XSDFEC_REG_WIDTH_JUMP) % PAGE_SIZE) 620 n += 1; 621 622 res = get_user_pages_fast((unsigned long)src_ptr, n, 0, page); 623 if (res < n) { 624 for (i = 0; i < res; i++) 625 put_page(page[i]); 626 return -EINVAL; 627 } 628 629 for (i = 0; i < n; i++) { 630 addr = kmap(page[i]); 631 do { 632 xsdfec_regwrite(xsdfec, 633 base_addr + ((offset + reg) * 634 XSDFEC_REG_WIDTH_JUMP), 635 addr[reg]); 636 reg++; 637 } while ((reg < len) && 638 ((reg * XSDFEC_REG_WIDTH_JUMP) % PAGE_SIZE)); 639 put_page(page[i]); 640 } 641 return reg; 642 } 643 644 static int xsdfec_add_ldpc(struct xsdfec_dev *xsdfec, void __user *arg) 645 { 646 struct xsdfec_ldpc_params *ldpc; 647 int ret, n; 648 649 ldpc = kzalloc(sizeof(*ldpc), GFP_KERNEL); 650 if (!ldpc) 651 return -ENOMEM; 652 653 ret = copy_from_user(ldpc, arg, sizeof(*ldpc)); 654 if (ret) 655 goto err_out; 656 657 if (xsdfec->config.code == XSDFEC_TURBO_CODE) { 658 ret = -EIO; 659 goto err_out; 660 } 661 662 /* Verify Device has not started */ 663 if (xsdfec->state == XSDFEC_STARTED) { 664 ret = -EIO; 665 goto err_out; 666 } 667 668 if (xsdfec->config.code_wr_protect) { 669 ret = -EIO; 670 goto err_out; 671 } 672 673 /* Write Reg 0 */ 674 ret = xsdfec_reg0_write(xsdfec, ldpc->n, ldpc->k, ldpc->psize, 675 ldpc->code_id); 676 if (ret) 677 goto err_out; 678 679 /* Write Reg 1 */ 680 ret = xsdfec_reg1_write(xsdfec, ldpc->psize, ldpc->no_packing, ldpc->nm, 681 ldpc->code_id); 682 if (ret) 683 goto err_out; 684 685 /* Write Reg 2 */ 686 ret = xsdfec_reg2_write(xsdfec, ldpc->nlayers, ldpc->nmqc, 687 ldpc->norm_type, ldpc->special_qc, 688 ldpc->no_final_parity, ldpc->max_schedule, 689 ldpc->code_id); 690 if (ret) 691 goto err_out; 692 693 /* Write Reg 3 */ 694 ret = xsdfec_reg3_write(xsdfec, ldpc->sc_off, ldpc->la_off, 695 ldpc->qc_off, ldpc->code_id); 696 if (ret) 697 goto err_out; 698 699 /* Write Shared Codes */ 700 n = ldpc->nlayers / 4; 701 if (ldpc->nlayers % 4) 702 n++; 703 704 ret = xsdfec_table_write(xsdfec, ldpc->sc_off, ldpc->sc_table, n, 705 XSDFEC_LDPC_SC_TABLE_ADDR_BASE, 706 XSDFEC_SC_TABLE_DEPTH); 707 if (ret < 0) 708 goto err_out; 709 710 ret = xsdfec_table_write(xsdfec, 4 * ldpc->la_off, ldpc->la_table, 711 ldpc->nlayers, XSDFEC_LDPC_LA_TABLE_ADDR_BASE, 712 XSDFEC_LA_TABLE_DEPTH); 713 if (ret < 0) 714 goto err_out; 715 716 ret = xsdfec_table_write(xsdfec, 4 * ldpc->qc_off, ldpc->qc_table, 717 ldpc->nqc, XSDFEC_LDPC_QC_TABLE_ADDR_BASE, 718 XSDFEC_QC_TABLE_DEPTH); 719 if (ret > 0) 720 ret = 0; 721 err_out: 722 kfree(ldpc); 723 return ret; 724 } 725 726 static int xsdfec_set_order(struct xsdfec_dev *xsdfec, void __user *arg) 727 { 728 bool order_invalid; 729 enum xsdfec_order order; 730 int err; 731 732 err = get_user(order, (enum xsdfec_order *)arg); 733 if (err) 734 return -EFAULT; 735 736 order_invalid = (order != XSDFEC_MAINTAIN_ORDER) && 737 (order != XSDFEC_OUT_OF_ORDER); 738 if (order_invalid) 739 return -EINVAL; 740 741 /* Verify Device has not started */ 742 if (xsdfec->state == XSDFEC_STARTED) 743 return -EIO; 744 745 xsdfec_regwrite(xsdfec, XSDFEC_ORDER_ADDR, order); 746 747 xsdfec->config.order = order; 748 749 return 0; 750 } 751 752 static int xsdfec_set_bypass(struct xsdfec_dev *xsdfec, bool __user *arg) 753 { 754 bool bypass; 755 int err; 756 757 err = get_user(bypass, arg); 758 if (err) 759 return -EFAULT; 760 761 /* Verify Device has not started */ 762 if (xsdfec->state == XSDFEC_STARTED) 763 return -EIO; 764 765 if (bypass) 766 xsdfec_regwrite(xsdfec, XSDFEC_BYPASS_ADDR, 1); 767 else 768 xsdfec_regwrite(xsdfec, XSDFEC_BYPASS_ADDR, 0); 769 770 xsdfec->config.bypass = bypass; 771 772 return 0; 773 } 774 775 static int xsdfec_is_active(struct xsdfec_dev *xsdfec, bool __user *arg) 776 { 777 u32 reg_value; 778 bool is_active; 779 int err; 780 781 reg_value = xsdfec_regread(xsdfec, XSDFEC_ACTIVE_ADDR); 782 /* using a double ! operator instead of casting */ 783 is_active = !!(reg_value & XSDFEC_IS_ACTIVITY_SET); 784 err = put_user(is_active, arg); 785 if (err) 786 return -EFAULT; 787 788 return err; 789 } 790 791 static u32 792 xsdfec_translate_axis_width_cfg_val(enum xsdfec_axis_width axis_width_cfg) 793 { 794 u32 axis_width_field = 0; 795 796 switch (axis_width_cfg) { 797 case XSDFEC_1x128b: 798 axis_width_field = 0; 799 break; 800 case XSDFEC_2x128b: 801 axis_width_field = 1; 802 break; 803 case XSDFEC_4x128b: 804 axis_width_field = 2; 805 break; 806 } 807 808 return axis_width_field; 809 } 810 811 static u32 xsdfec_translate_axis_words_cfg_val(enum xsdfec_axis_word_include 812 axis_word_inc_cfg) 813 { 814 u32 axis_words_field = 0; 815 816 if (axis_word_inc_cfg == XSDFEC_FIXED_VALUE || 817 axis_word_inc_cfg == XSDFEC_IN_BLOCK) 818 axis_words_field = 0; 819 else if (axis_word_inc_cfg == XSDFEC_PER_AXI_TRANSACTION) 820 axis_words_field = 1; 821 822 return axis_words_field; 823 } 824 825 static int xsdfec_cfg_axi_streams(struct xsdfec_dev *xsdfec) 826 { 827 u32 reg_value; 828 u32 dout_words_field; 829 u32 dout_width_field; 830 u32 din_words_field; 831 u32 din_width_field; 832 struct xsdfec_config *config = &xsdfec->config; 833 834 /* translate config info to register values */ 835 dout_words_field = 836 xsdfec_translate_axis_words_cfg_val(config->dout_word_include); 837 dout_width_field = 838 xsdfec_translate_axis_width_cfg_val(config->dout_width); 839 din_words_field = 840 xsdfec_translate_axis_words_cfg_val(config->din_word_include); 841 din_width_field = 842 xsdfec_translate_axis_width_cfg_val(config->din_width); 843 844 reg_value = dout_words_field << XSDFEC_AXIS_DOUT_WORDS_LSB; 845 reg_value |= dout_width_field << XSDFEC_AXIS_DOUT_WIDTH_LSB; 846 reg_value |= din_words_field << XSDFEC_AXIS_DIN_WORDS_LSB; 847 reg_value |= din_width_field << XSDFEC_AXIS_DIN_WIDTH_LSB; 848 849 xsdfec_regwrite(xsdfec, XSDFEC_AXIS_WIDTH_ADDR, reg_value); 850 851 return 0; 852 } 853 854 static int xsdfec_dev_open(struct inode *iptr, struct file *fptr) 855 { 856 return 0; 857 } 858 859 static int xsdfec_dev_release(struct inode *iptr, struct file *fptr) 860 { 861 return 0; 862 } 863 864 static int xsdfec_start(struct xsdfec_dev *xsdfec) 865 { 866 u32 regread; 867 868 regread = xsdfec_regread(xsdfec, XSDFEC_FEC_CODE_ADDR); 869 regread &= 0x1; 870 if (regread != xsdfec->config.code) { 871 dev_dbg(xsdfec->dev, 872 "%s SDFEC HW code does not match driver code, reg %d, code %d", 873 __func__, regread, xsdfec->config.code); 874 return -EINVAL; 875 } 876 877 /* Set AXIS enable */ 878 xsdfec_regwrite(xsdfec, XSDFEC_AXIS_ENABLE_ADDR, 879 XSDFEC_AXIS_ENABLE_MASK); 880 /* Done */ 881 xsdfec->state = XSDFEC_STARTED; 882 return 0; 883 } 884 885 static int xsdfec_stop(struct xsdfec_dev *xsdfec) 886 { 887 u32 regread; 888 889 if (xsdfec->state != XSDFEC_STARTED) 890 dev_dbg(xsdfec->dev, "Device not started correctly"); 891 /* Disable AXIS_ENABLE Input interfaces only */ 892 regread = xsdfec_regread(xsdfec, XSDFEC_AXIS_ENABLE_ADDR); 893 regread &= (~XSDFEC_AXIS_IN_ENABLE_MASK); 894 xsdfec_regwrite(xsdfec, XSDFEC_AXIS_ENABLE_ADDR, regread); 895 /* Stop */ 896 xsdfec->state = XSDFEC_STOPPED; 897 return 0; 898 } 899 900 static int xsdfec_clear_stats(struct xsdfec_dev *xsdfec) 901 { 902 spin_lock_irqsave(&xsdfec->error_data_lock, xsdfec->flags); 903 xsdfec->isr_err_count = 0; 904 xsdfec->uecc_count = 0; 905 xsdfec->cecc_count = 0; 906 spin_unlock_irqrestore(&xsdfec->error_data_lock, xsdfec->flags); 907 908 return 0; 909 } 910 911 static int xsdfec_get_stats(struct xsdfec_dev *xsdfec, void __user *arg) 912 { 913 int err; 914 struct xsdfec_stats user_stats; 915 916 spin_lock_irqsave(&xsdfec->error_data_lock, xsdfec->flags); 917 user_stats.isr_err_count = xsdfec->isr_err_count; 918 user_stats.cecc_count = xsdfec->cecc_count; 919 user_stats.uecc_count = xsdfec->uecc_count; 920 xsdfec->stats_updated = false; 921 spin_unlock_irqrestore(&xsdfec->error_data_lock, xsdfec->flags); 922 923 err = copy_to_user(arg, &user_stats, sizeof(user_stats)); 924 if (err) 925 err = -EFAULT; 926 927 return err; 928 } 929 930 static int xsdfec_set_default_config(struct xsdfec_dev *xsdfec) 931 { 932 /* Ensure registers are aligned with core configuration */ 933 xsdfec_regwrite(xsdfec, XSDFEC_FEC_CODE_ADDR, xsdfec->config.code); 934 xsdfec_cfg_axi_streams(xsdfec); 935 update_config_from_hw(xsdfec); 936 937 return 0; 938 } 939 940 static long xsdfec_dev_ioctl(struct file *fptr, unsigned int cmd, 941 unsigned long data) 942 { 943 struct xsdfec_dev *xsdfec; 944 void __user *arg = NULL; 945 int rval = -EINVAL; 946 947 xsdfec = container_of(fptr->private_data, struct xsdfec_dev, miscdev); 948 949 /* In failed state allow only reset and get status IOCTLs */ 950 if (xsdfec->state == XSDFEC_NEEDS_RESET && 951 (cmd != XSDFEC_SET_DEFAULT_CONFIG && cmd != XSDFEC_GET_STATUS && 952 cmd != XSDFEC_GET_STATS && cmd != XSDFEC_CLEAR_STATS)) { 953 return -EPERM; 954 } 955 956 if (_IOC_TYPE(cmd) != XSDFEC_MAGIC) 957 return -ENOTTY; 958 959 /* check if ioctl argument is present and valid */ 960 if (_IOC_DIR(cmd) != _IOC_NONE) { 961 arg = (void __user *)data; 962 if (!arg) 963 return rval; 964 } 965 966 switch (cmd) { 967 case XSDFEC_START_DEV: 968 rval = xsdfec_start(xsdfec); 969 break; 970 case XSDFEC_STOP_DEV: 971 rval = xsdfec_stop(xsdfec); 972 break; 973 case XSDFEC_CLEAR_STATS: 974 rval = xsdfec_clear_stats(xsdfec); 975 break; 976 case XSDFEC_GET_STATS: 977 rval = xsdfec_get_stats(xsdfec, arg); 978 break; 979 case XSDFEC_GET_STATUS: 980 rval = xsdfec_get_status(xsdfec, arg); 981 break; 982 case XSDFEC_GET_CONFIG: 983 rval = xsdfec_get_config(xsdfec, arg); 984 break; 985 case XSDFEC_SET_DEFAULT_CONFIG: 986 rval = xsdfec_set_default_config(xsdfec); 987 break; 988 case XSDFEC_SET_IRQ: 989 rval = xsdfec_set_irq(xsdfec, arg); 990 break; 991 case XSDFEC_SET_TURBO: 992 rval = xsdfec_set_turbo(xsdfec, arg); 993 break; 994 case XSDFEC_GET_TURBO: 995 rval = xsdfec_get_turbo(xsdfec, arg); 996 break; 997 case XSDFEC_ADD_LDPC_CODE_PARAMS: 998 rval = xsdfec_add_ldpc(xsdfec, arg); 999 break; 1000 case XSDFEC_SET_ORDER: 1001 rval = xsdfec_set_order(xsdfec, arg); 1002 break; 1003 case XSDFEC_SET_BYPASS: 1004 rval = xsdfec_set_bypass(xsdfec, arg); 1005 break; 1006 case XSDFEC_IS_ACTIVE: 1007 rval = xsdfec_is_active(xsdfec, (bool __user *)arg); 1008 break; 1009 default: 1010 /* Should not get here */ 1011 break; 1012 } 1013 return rval; 1014 } 1015 1016 #ifdef CONFIG_COMPAT 1017 static long xsdfec_dev_compat_ioctl(struct file *file, unsigned int cmd, 1018 unsigned long data) 1019 { 1020 return xsdfec_dev_ioctl(file, cmd, (unsigned long)compat_ptr(data)); 1021 } 1022 #endif 1023 1024 static unsigned int xsdfec_poll(struct file *file, poll_table *wait) 1025 { 1026 unsigned int mask = 0; 1027 struct xsdfec_dev *xsdfec; 1028 1029 xsdfec = container_of(file->private_data, struct xsdfec_dev, miscdev); 1030 1031 if (!xsdfec) 1032 return POLLNVAL | POLLHUP; 1033 1034 poll_wait(file, &xsdfec->waitq, wait); 1035 1036 /* XSDFEC ISR detected an error */ 1037 spin_lock_irqsave(&xsdfec->error_data_lock, xsdfec->flags); 1038 if (xsdfec->state_updated) 1039 mask |= POLLIN | POLLPRI; 1040 1041 if (xsdfec->stats_updated) 1042 mask |= POLLIN | POLLRDNORM; 1043 spin_unlock_irqrestore(&xsdfec->error_data_lock, xsdfec->flags); 1044 1045 return mask; 1046 } 1047 1048 static const struct file_operations xsdfec_fops = { 1049 .owner = THIS_MODULE, 1050 .open = xsdfec_dev_open, 1051 .release = xsdfec_dev_release, 1052 .unlocked_ioctl = xsdfec_dev_ioctl, 1053 .poll = xsdfec_poll, 1054 #ifdef CONFIG_COMPAT 1055 .compat_ioctl = xsdfec_dev_compat_ioctl, 1056 #endif 1057 }; 1058 1059 static int xsdfec_parse_of(struct xsdfec_dev *xsdfec) 1060 { 1061 struct device *dev = xsdfec->dev; 1062 struct device_node *node = dev->of_node; 1063 int rval; 1064 const char *fec_code; 1065 u32 din_width; 1066 u32 din_word_include; 1067 u32 dout_width; 1068 u32 dout_word_include; 1069 1070 rval = of_property_read_string(node, "xlnx,sdfec-code", &fec_code); 1071 if (rval < 0) 1072 return rval; 1073 1074 if (!strcasecmp(fec_code, "ldpc")) 1075 xsdfec->config.code = XSDFEC_LDPC_CODE; 1076 else if (!strcasecmp(fec_code, "turbo")) 1077 xsdfec->config.code = XSDFEC_TURBO_CODE; 1078 else 1079 return -EINVAL; 1080 1081 rval = of_property_read_u32(node, "xlnx,sdfec-din-words", 1082 &din_word_include); 1083 if (rval < 0) 1084 return rval; 1085 1086 if (din_word_include < XSDFEC_AXIS_WORDS_INCLUDE_MAX) 1087 xsdfec->config.din_word_include = din_word_include; 1088 else 1089 return -EINVAL; 1090 1091 rval = of_property_read_u32(node, "xlnx,sdfec-din-width", &din_width); 1092 if (rval < 0) 1093 return rval; 1094 1095 switch (din_width) { 1096 /* Fall through and set for valid values */ 1097 case XSDFEC_1x128b: 1098 case XSDFEC_2x128b: 1099 case XSDFEC_4x128b: 1100 xsdfec->config.din_width = din_width; 1101 break; 1102 default: 1103 return -EINVAL; 1104 } 1105 1106 rval = of_property_read_u32(node, "xlnx,sdfec-dout-words", 1107 &dout_word_include); 1108 if (rval < 0) 1109 return rval; 1110 1111 if (dout_word_include < XSDFEC_AXIS_WORDS_INCLUDE_MAX) 1112 xsdfec->config.dout_word_include = dout_word_include; 1113 else 1114 return -EINVAL; 1115 1116 rval = of_property_read_u32(node, "xlnx,sdfec-dout-width", &dout_width); 1117 if (rval < 0) 1118 return rval; 1119 1120 switch (dout_width) { 1121 /* Fall through and set for valid values */ 1122 case XSDFEC_1x128b: 1123 case XSDFEC_2x128b: 1124 case XSDFEC_4x128b: 1125 xsdfec->config.dout_width = dout_width; 1126 break; 1127 default: 1128 return -EINVAL; 1129 } 1130 1131 /* Write LDPC to CODE Register */ 1132 xsdfec_regwrite(xsdfec, XSDFEC_FEC_CODE_ADDR, xsdfec->config.code); 1133 1134 xsdfec_cfg_axi_streams(xsdfec); 1135 1136 return 0; 1137 } 1138 1139 static irqreturn_t xsdfec_irq_thread(int irq, void *dev_id) 1140 { 1141 struct xsdfec_dev *xsdfec = dev_id; 1142 irqreturn_t ret = IRQ_HANDLED; 1143 u32 ecc_err; 1144 u32 isr_err; 1145 u32 uecc_count; 1146 u32 cecc_count; 1147 u32 isr_err_count; 1148 u32 aecc_count; 1149 u32 tmp; 1150 1151 WARN_ON(xsdfec->irq != irq); 1152 1153 /* Mask Interrupts */ 1154 xsdfec_isr_enable(xsdfec, false); 1155 xsdfec_ecc_isr_enable(xsdfec, false); 1156 /* Read ISR */ 1157 ecc_err = xsdfec_regread(xsdfec, XSDFEC_ECC_ISR_ADDR); 1158 isr_err = xsdfec_regread(xsdfec, XSDFEC_ISR_ADDR); 1159 /* Clear the interrupts */ 1160 xsdfec_regwrite(xsdfec, XSDFEC_ECC_ISR_ADDR, ecc_err); 1161 xsdfec_regwrite(xsdfec, XSDFEC_ISR_ADDR, isr_err); 1162 1163 tmp = ecc_err & XSDFEC_ALL_ECC_ISR_MBE_MASK; 1164 /* Count uncorrectable 2-bit errors */ 1165 uecc_count = hweight32(tmp); 1166 /* Count all ECC errors */ 1167 aecc_count = hweight32(ecc_err); 1168 /* Number of correctable 1-bit ECC error */ 1169 cecc_count = aecc_count - 2 * uecc_count; 1170 /* Count ISR errors */ 1171 isr_err_count = hweight32(isr_err); 1172 dev_dbg(xsdfec->dev, "tmp=%x, uecc=%x, aecc=%x, cecc=%x, isr=%x", tmp, 1173 uecc_count, aecc_count, cecc_count, isr_err_count); 1174 dev_dbg(xsdfec->dev, "uecc=%x, cecc=%x, isr=%x", xsdfec->uecc_count, 1175 xsdfec->cecc_count, xsdfec->isr_err_count); 1176 1177 spin_lock_irqsave(&xsdfec->error_data_lock, xsdfec->flags); 1178 /* Add new errors to a 2-bits counter */ 1179 if (uecc_count) 1180 xsdfec->uecc_count += uecc_count; 1181 /* Add new errors to a 1-bits counter */ 1182 if (cecc_count) 1183 xsdfec->cecc_count += cecc_count; 1184 /* Add new errors to a ISR counter */ 1185 if (isr_err_count) 1186 xsdfec->isr_err_count += isr_err_count; 1187 1188 /* Update state/stats flag */ 1189 if (uecc_count) { 1190 if (ecc_err & XSDFEC_ECC_ISR_MBE_MASK) 1191 xsdfec->state = XSDFEC_NEEDS_RESET; 1192 else if (ecc_err & XSDFEC_PL_INIT_ECC_ISR_MBE_MASK) 1193 xsdfec->state = XSDFEC_PL_RECONFIGURE; 1194 xsdfec->stats_updated = true; 1195 xsdfec->state_updated = true; 1196 } 1197 1198 if (cecc_count) 1199 xsdfec->stats_updated = true; 1200 1201 if (isr_err_count) { 1202 xsdfec->state = XSDFEC_NEEDS_RESET; 1203 xsdfec->stats_updated = true; 1204 xsdfec->state_updated = true; 1205 } 1206 1207 spin_unlock_irqrestore(&xsdfec->error_data_lock, xsdfec->flags); 1208 dev_dbg(xsdfec->dev, "state=%x, stats=%x", xsdfec->state_updated, 1209 xsdfec->stats_updated); 1210 1211 /* Enable another polling */ 1212 if (xsdfec->state_updated || xsdfec->stats_updated) 1213 wake_up_interruptible(&xsdfec->waitq); 1214 else 1215 ret = IRQ_NONE; 1216 1217 /* Unmask Interrupts */ 1218 xsdfec_isr_enable(xsdfec, true); 1219 xsdfec_ecc_isr_enable(xsdfec, true); 1220 1221 return ret; 1222 } 1223 1224 static int xsdfec_clk_init(struct platform_device *pdev, 1225 struct xsdfec_clks *clks) 1226 { 1227 int err; 1228 1229 clks->core_clk = devm_clk_get(&pdev->dev, "core_clk"); 1230 if (IS_ERR(clks->core_clk)) { 1231 dev_err(&pdev->dev, "failed to get core_clk"); 1232 return PTR_ERR(clks->core_clk); 1233 } 1234 1235 clks->axi_clk = devm_clk_get(&pdev->dev, "s_axi_aclk"); 1236 if (IS_ERR(clks->axi_clk)) { 1237 dev_err(&pdev->dev, "failed to get axi_clk"); 1238 return PTR_ERR(clks->axi_clk); 1239 } 1240 1241 clks->din_words_clk = devm_clk_get(&pdev->dev, "s_axis_din_words_aclk"); 1242 if (IS_ERR(clks->din_words_clk)) { 1243 if (PTR_ERR(clks->din_words_clk) != -ENOENT) { 1244 err = PTR_ERR(clks->din_words_clk); 1245 return err; 1246 } 1247 clks->din_words_clk = NULL; 1248 } 1249 1250 clks->din_clk = devm_clk_get(&pdev->dev, "s_axis_din_aclk"); 1251 if (IS_ERR(clks->din_clk)) { 1252 if (PTR_ERR(clks->din_clk) != -ENOENT) { 1253 err = PTR_ERR(clks->din_clk); 1254 return err; 1255 } 1256 clks->din_clk = NULL; 1257 } 1258 1259 clks->dout_clk = devm_clk_get(&pdev->dev, "m_axis_dout_aclk"); 1260 if (IS_ERR(clks->dout_clk)) { 1261 if (PTR_ERR(clks->dout_clk) != -ENOENT) { 1262 err = PTR_ERR(clks->dout_clk); 1263 return err; 1264 } 1265 clks->dout_clk = NULL; 1266 } 1267 1268 clks->dout_words_clk = 1269 devm_clk_get(&pdev->dev, "s_axis_dout_words_aclk"); 1270 if (IS_ERR(clks->dout_words_clk)) { 1271 if (PTR_ERR(clks->dout_words_clk) != -ENOENT) { 1272 err = PTR_ERR(clks->dout_words_clk); 1273 return err; 1274 } 1275 clks->dout_words_clk = NULL; 1276 } 1277 1278 clks->ctrl_clk = devm_clk_get(&pdev->dev, "s_axis_ctrl_aclk"); 1279 if (IS_ERR(clks->ctrl_clk)) { 1280 if (PTR_ERR(clks->ctrl_clk) != -ENOENT) { 1281 err = PTR_ERR(clks->ctrl_clk); 1282 return err; 1283 } 1284 clks->ctrl_clk = NULL; 1285 } 1286 1287 clks->status_clk = devm_clk_get(&pdev->dev, "m_axis_status_aclk"); 1288 if (IS_ERR(clks->status_clk)) { 1289 if (PTR_ERR(clks->status_clk) != -ENOENT) { 1290 err = PTR_ERR(clks->status_clk); 1291 return err; 1292 } 1293 clks->status_clk = NULL; 1294 } 1295 1296 err = clk_prepare_enable(clks->core_clk); 1297 if (err) { 1298 dev_err(&pdev->dev, "failed to enable core_clk (%d)", err); 1299 return err; 1300 } 1301 1302 err = clk_prepare_enable(clks->axi_clk); 1303 if (err) { 1304 dev_err(&pdev->dev, "failed to enable axi_clk (%d)", err); 1305 goto err_disable_core_clk; 1306 } 1307 1308 err = clk_prepare_enable(clks->din_clk); 1309 if (err) { 1310 dev_err(&pdev->dev, "failed to enable din_clk (%d)", err); 1311 goto err_disable_axi_clk; 1312 } 1313 1314 err = clk_prepare_enable(clks->din_words_clk); 1315 if (err) { 1316 dev_err(&pdev->dev, "failed to enable din_words_clk (%d)", err); 1317 goto err_disable_din_clk; 1318 } 1319 1320 err = clk_prepare_enable(clks->dout_clk); 1321 if (err) { 1322 dev_err(&pdev->dev, "failed to enable dout_clk (%d)", err); 1323 goto err_disable_din_words_clk; 1324 } 1325 1326 err = clk_prepare_enable(clks->dout_words_clk); 1327 if (err) { 1328 dev_err(&pdev->dev, "failed to enable dout_words_clk (%d)", 1329 err); 1330 goto err_disable_dout_clk; 1331 } 1332 1333 err = clk_prepare_enable(clks->ctrl_clk); 1334 if (err) { 1335 dev_err(&pdev->dev, "failed to enable ctrl_clk (%d)", err); 1336 goto err_disable_dout_words_clk; 1337 } 1338 1339 err = clk_prepare_enable(clks->status_clk); 1340 if (err) { 1341 dev_err(&pdev->dev, "failed to enable status_clk (%d)\n", err); 1342 goto err_disable_ctrl_clk; 1343 } 1344 1345 return err; 1346 1347 err_disable_ctrl_clk: 1348 clk_disable_unprepare(clks->ctrl_clk); 1349 err_disable_dout_words_clk: 1350 clk_disable_unprepare(clks->dout_words_clk); 1351 err_disable_dout_clk: 1352 clk_disable_unprepare(clks->dout_clk); 1353 err_disable_din_words_clk: 1354 clk_disable_unprepare(clks->din_words_clk); 1355 err_disable_din_clk: 1356 clk_disable_unprepare(clks->din_clk); 1357 err_disable_axi_clk: 1358 clk_disable_unprepare(clks->axi_clk); 1359 err_disable_core_clk: 1360 clk_disable_unprepare(clks->core_clk); 1361 1362 return err; 1363 } 1364 1365 static void xsdfec_disable_all_clks(struct xsdfec_clks *clks) 1366 { 1367 clk_disable_unprepare(clks->status_clk); 1368 clk_disable_unprepare(clks->ctrl_clk); 1369 clk_disable_unprepare(clks->dout_words_clk); 1370 clk_disable_unprepare(clks->dout_clk); 1371 clk_disable_unprepare(clks->din_words_clk); 1372 clk_disable_unprepare(clks->din_clk); 1373 clk_disable_unprepare(clks->core_clk); 1374 clk_disable_unprepare(clks->axi_clk); 1375 } 1376 1377 static void xsdfec_idr_remove(struct xsdfec_dev *xsdfec) 1378 { 1379 mutex_lock(&dev_idr_lock); 1380 idr_remove(&dev_idr, xsdfec->dev_id); 1381 mutex_unlock(&dev_idr_lock); 1382 } 1383 1384 static int xsdfec_probe(struct platform_device *pdev) 1385 { 1386 struct xsdfec_dev *xsdfec; 1387 struct device *dev; 1388 struct resource *res; 1389 int err; 1390 bool irq_enabled = true; 1391 1392 xsdfec = devm_kzalloc(&pdev->dev, sizeof(*xsdfec), GFP_KERNEL); 1393 if (!xsdfec) 1394 return -ENOMEM; 1395 1396 xsdfec->dev = &pdev->dev; 1397 spin_lock_init(&xsdfec->error_data_lock); 1398 1399 err = xsdfec_clk_init(pdev, &xsdfec->clks); 1400 if (err) 1401 return err; 1402 1403 dev = xsdfec->dev; 1404 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1405 xsdfec->regs = devm_ioremap_resource(dev, res); 1406 if (IS_ERR(xsdfec->regs)) { 1407 err = PTR_ERR(xsdfec->regs); 1408 goto err_xsdfec_dev; 1409 } 1410 1411 xsdfec->irq = platform_get_irq(pdev, 0); 1412 if (xsdfec->irq < 0) { 1413 dev_dbg(dev, "platform_get_irq failed"); 1414 irq_enabled = false; 1415 } 1416 1417 err = xsdfec_parse_of(xsdfec); 1418 if (err < 0) 1419 goto err_xsdfec_dev; 1420 1421 update_config_from_hw(xsdfec); 1422 1423 /* Save driver private data */ 1424 platform_set_drvdata(pdev, xsdfec); 1425 1426 if (irq_enabled) { 1427 init_waitqueue_head(&xsdfec->waitq); 1428 /* Register IRQ thread */ 1429 err = devm_request_threaded_irq(dev, xsdfec->irq, NULL, 1430 xsdfec_irq_thread, IRQF_ONESHOT, 1431 "xilinx-sdfec16", xsdfec); 1432 if (err < 0) { 1433 dev_err(dev, "unable to request IRQ%d", xsdfec->irq); 1434 goto err_xsdfec_dev; 1435 } 1436 } 1437 1438 mutex_lock(&dev_idr_lock); 1439 err = idr_alloc(&dev_idr, xsdfec->dev_name, 0, 0, GFP_KERNEL); 1440 mutex_unlock(&dev_idr_lock); 1441 if (err < 0) 1442 goto err_xsdfec_dev; 1443 xsdfec->dev_id = err; 1444 1445 snprintf(xsdfec->dev_name, DEV_NAME_LEN, "xsdfec%d", xsdfec->dev_id); 1446 xsdfec->miscdev.minor = MISC_DYNAMIC_MINOR; 1447 xsdfec->miscdev.name = xsdfec->dev_name; 1448 xsdfec->miscdev.fops = &xsdfec_fops; 1449 xsdfec->miscdev.parent = dev; 1450 err = misc_register(&xsdfec->miscdev); 1451 if (err) { 1452 dev_err(dev, "error:%d. Unable to register device", err); 1453 goto err_xsdfec_idr; 1454 } 1455 return 0; 1456 1457 err_xsdfec_idr: 1458 xsdfec_idr_remove(xsdfec); 1459 err_xsdfec_dev: 1460 xsdfec_disable_all_clks(&xsdfec->clks); 1461 return err; 1462 } 1463 1464 static int xsdfec_remove(struct platform_device *pdev) 1465 { 1466 struct xsdfec_dev *xsdfec; 1467 1468 xsdfec = platform_get_drvdata(pdev); 1469 misc_deregister(&xsdfec->miscdev); 1470 xsdfec_idr_remove(xsdfec); 1471 xsdfec_disable_all_clks(&xsdfec->clks); 1472 return 0; 1473 } 1474 1475 static const struct of_device_id xsdfec_of_match[] = { 1476 { 1477 .compatible = "xlnx,sd-fec-1.1", 1478 }, 1479 { /* end of table */ } 1480 }; 1481 MODULE_DEVICE_TABLE(of, xsdfec_of_match); 1482 1483 static struct platform_driver xsdfec_driver = { 1484 .driver = { 1485 .name = "xilinx-sdfec", 1486 .of_match_table = xsdfec_of_match, 1487 }, 1488 .probe = xsdfec_probe, 1489 .remove = xsdfec_remove, 1490 }; 1491 1492 static int __init xsdfec_init(void) 1493 { 1494 int err; 1495 1496 mutex_init(&dev_idr_lock); 1497 idr_init(&dev_idr); 1498 err = platform_driver_register(&xsdfec_driver); 1499 if (err < 0) { 1500 pr_err("%s Unabled to register SDFEC driver", __func__); 1501 return err; 1502 } 1503 return 0; 1504 } 1505 1506 static void __exit xsdfec_exit(void) 1507 { 1508 platform_driver_unregister(&xsdfec_driver); 1509 idr_destroy(&dev_idr); 1510 } 1511 1512 module_init(xsdfec_init); 1513 module_exit(xsdfec_exit); 1514 1515 MODULE_AUTHOR("Xilinx, Inc"); 1516 MODULE_DESCRIPTION("Xilinx SD-FEC16 Driver"); 1517 MODULE_LICENSE("GPL"); 1518