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 * 210 * This structure contains necessary state for SDFEC driver to operate 211 */ 212 struct xsdfec_dev { 213 struct miscdevice miscdev; 214 struct xsdfec_clks clks; 215 wait_queue_head_t waitq; 216 struct xsdfec_config config; 217 char dev_name[DEV_NAME_LEN]; 218 unsigned long flags; 219 void __iomem *regs; 220 struct device *dev; 221 enum xsdfec_state state; 222 /* Spinlock to protect state_updated and stats_updated */ 223 spinlock_t error_data_lock; 224 int dev_id; 225 u32 isr_err_count; 226 u32 cecc_count; 227 u32 uecc_count; 228 int irq; 229 bool state_updated; 230 bool stats_updated; 231 }; 232 233 static inline void xsdfec_regwrite(struct xsdfec_dev *xsdfec, u32 addr, 234 u32 value) 235 { 236 dev_dbg(xsdfec->dev, "Writing 0x%x to offset 0x%x", value, addr); 237 iowrite32(value, xsdfec->regs + addr); 238 } 239 240 static inline u32 xsdfec_regread(struct xsdfec_dev *xsdfec, u32 addr) 241 { 242 u32 rval; 243 244 rval = ioread32(xsdfec->regs + addr); 245 dev_dbg(xsdfec->dev, "Read value = 0x%x from offset 0x%x", rval, addr); 246 return rval; 247 } 248 249 static void update_bool_config_from_reg(struct xsdfec_dev *xsdfec, 250 u32 reg_offset, u32 bit_num, 251 char *config_value) 252 { 253 u32 reg_val; 254 u32 bit_mask = 1 << bit_num; 255 256 reg_val = xsdfec_regread(xsdfec, reg_offset); 257 *config_value = (reg_val & bit_mask) > 0; 258 } 259 260 static void update_config_from_hw(struct xsdfec_dev *xsdfec) 261 { 262 u32 reg_value; 263 bool sdfec_started; 264 265 /* Update the Order */ 266 reg_value = xsdfec_regread(xsdfec, XSDFEC_ORDER_ADDR); 267 xsdfec->config.order = reg_value; 268 269 update_bool_config_from_reg(xsdfec, XSDFEC_BYPASS_ADDR, 270 0, /* Bit Number, maybe change to mask */ 271 &xsdfec->config.bypass); 272 273 update_bool_config_from_reg(xsdfec, XSDFEC_CODE_WR_PROTECT_ADDR, 274 0, /* Bit Number */ 275 &xsdfec->config.code_wr_protect); 276 277 reg_value = xsdfec_regread(xsdfec, XSDFEC_IMR_ADDR); 278 xsdfec->config.irq.enable_isr = (reg_value & XSDFEC_ISR_MASK) > 0; 279 280 reg_value = xsdfec_regread(xsdfec, XSDFEC_ECC_IMR_ADDR); 281 xsdfec->config.irq.enable_ecc_isr = 282 (reg_value & XSDFEC_ECC_ISR_MASK) > 0; 283 284 reg_value = xsdfec_regread(xsdfec, XSDFEC_AXIS_ENABLE_ADDR); 285 sdfec_started = (reg_value & XSDFEC_AXIS_IN_ENABLE_MASK) > 0; 286 if (sdfec_started) 287 xsdfec->state = XSDFEC_STARTED; 288 else 289 xsdfec->state = XSDFEC_STOPPED; 290 } 291 292 static int xsdfec_get_config(struct xsdfec_dev *xsdfec, void __user *arg) 293 { 294 int err; 295 296 err = copy_to_user(arg, &xsdfec->config, sizeof(xsdfec->config)); 297 if (err) 298 err = -EFAULT; 299 300 return err; 301 } 302 303 static int xsdfec_isr_enable(struct xsdfec_dev *xsdfec, bool enable) 304 { 305 u32 mask_read; 306 307 if (enable) { 308 /* Enable */ 309 xsdfec_regwrite(xsdfec, XSDFEC_IER_ADDR, XSDFEC_ISR_MASK); 310 mask_read = xsdfec_regread(xsdfec, XSDFEC_IMR_ADDR); 311 if (mask_read & XSDFEC_ISR_MASK) { 312 dev_dbg(xsdfec->dev, 313 "SDFEC enabling irq with IER failed"); 314 return -EIO; 315 } 316 } else { 317 /* Disable */ 318 xsdfec_regwrite(xsdfec, XSDFEC_IDR_ADDR, XSDFEC_ISR_MASK); 319 mask_read = xsdfec_regread(xsdfec, XSDFEC_IMR_ADDR); 320 if ((mask_read & XSDFEC_ISR_MASK) != XSDFEC_ISR_MASK) { 321 dev_dbg(xsdfec->dev, 322 "SDFEC disabling irq with IDR failed"); 323 return -EIO; 324 } 325 } 326 return 0; 327 } 328 329 static int xsdfec_ecc_isr_enable(struct xsdfec_dev *xsdfec, bool enable) 330 { 331 u32 mask_read; 332 333 if (enable) { 334 /* Enable */ 335 xsdfec_regwrite(xsdfec, XSDFEC_ECC_IER_ADDR, 336 XSDFEC_ALL_ECC_ISR_MASK); 337 mask_read = xsdfec_regread(xsdfec, XSDFEC_ECC_IMR_ADDR); 338 if (mask_read & XSDFEC_ALL_ECC_ISR_MASK) { 339 dev_dbg(xsdfec->dev, 340 "SDFEC enabling ECC irq with ECC IER failed"); 341 return -EIO; 342 } 343 } else { 344 /* Disable */ 345 xsdfec_regwrite(xsdfec, XSDFEC_ECC_IDR_ADDR, 346 XSDFEC_ALL_ECC_ISR_MASK); 347 mask_read = xsdfec_regread(xsdfec, XSDFEC_ECC_IMR_ADDR); 348 if (!(((mask_read & XSDFEC_ALL_ECC_ISR_MASK) == 349 XSDFEC_ECC_ISR_MASK) || 350 ((mask_read & XSDFEC_ALL_ECC_ISR_MASK) == 351 XSDFEC_PL_INIT_ECC_ISR_MASK))) { 352 dev_dbg(xsdfec->dev, 353 "SDFEC disable ECC irq with ECC IDR failed"); 354 return -EIO; 355 } 356 } 357 return 0; 358 } 359 360 static int xsdfec_set_irq(struct xsdfec_dev *xsdfec, void __user *arg) 361 { 362 struct xsdfec_irq irq; 363 int err; 364 int isr_err; 365 int ecc_err; 366 367 err = copy_from_user(&irq, arg, sizeof(irq)); 368 if (err) 369 return -EFAULT; 370 371 /* Setup tlast related IRQ */ 372 isr_err = xsdfec_isr_enable(xsdfec, irq.enable_isr); 373 if (!isr_err) 374 xsdfec->config.irq.enable_isr = irq.enable_isr; 375 376 /* Setup ECC related IRQ */ 377 ecc_err = xsdfec_ecc_isr_enable(xsdfec, irq.enable_ecc_isr); 378 if (!ecc_err) 379 xsdfec->config.irq.enable_ecc_isr = irq.enable_ecc_isr; 380 381 if (isr_err < 0 || ecc_err < 0) 382 err = -EIO; 383 384 return err; 385 } 386 387 static int xsdfec_set_turbo(struct xsdfec_dev *xsdfec, void __user *arg) 388 { 389 struct xsdfec_turbo turbo; 390 int err; 391 u32 turbo_write; 392 393 err = copy_from_user(&turbo, arg, sizeof(turbo)); 394 if (err) 395 return -EFAULT; 396 397 if (turbo.alg >= XSDFEC_TURBO_ALG_MAX) 398 return -EINVAL; 399 400 if (turbo.scale > XSDFEC_TURBO_SCALE_MAX) 401 return -EINVAL; 402 403 /* Check to see what device tree says about the FEC codes */ 404 if (xsdfec->config.code == XSDFEC_LDPC_CODE) 405 return -EIO; 406 407 turbo_write = ((turbo.scale & XSDFEC_TURBO_SCALE_MASK) 408 << XSDFEC_TURBO_SCALE_BIT_POS) | 409 turbo.alg; 410 xsdfec_regwrite(xsdfec, XSDFEC_TURBO_ADDR, turbo_write); 411 return err; 412 } 413 414 static int xsdfec_get_turbo(struct xsdfec_dev *xsdfec, void __user *arg) 415 { 416 u32 reg_value; 417 struct xsdfec_turbo turbo_params; 418 int err; 419 420 if (xsdfec->config.code == XSDFEC_LDPC_CODE) 421 return -EIO; 422 423 reg_value = xsdfec_regread(xsdfec, XSDFEC_TURBO_ADDR); 424 425 turbo_params.scale = (reg_value & XSDFEC_TURBO_SCALE_MASK) >> 426 XSDFEC_TURBO_SCALE_BIT_POS; 427 turbo_params.alg = reg_value & 0x1; 428 429 err = copy_to_user(arg, &turbo_params, sizeof(turbo_params)); 430 if (err) 431 err = -EFAULT; 432 433 return err; 434 } 435 436 static int xsdfec_reg0_write(struct xsdfec_dev *xsdfec, u32 n, u32 k, u32 psize, 437 u32 offset) 438 { 439 u32 wdata; 440 441 if (n < XSDFEC_REG0_N_MIN || n > XSDFEC_REG0_N_MAX || 442 (n > XSDFEC_REG0_N_MUL_P * psize) || n <= k || ((n % psize) != 0)) { 443 dev_dbg(xsdfec->dev, "N value is not in range"); 444 return -EINVAL; 445 } 446 n <<= XSDFEC_REG0_N_LSB; 447 448 if (k < XSDFEC_REG0_K_MIN || k > XSDFEC_REG0_K_MAX || 449 (k > XSDFEC_REG0_K_MUL_P * psize) || ((k % psize) != 0)) { 450 dev_dbg(xsdfec->dev, "K value is not in range"); 451 return -EINVAL; 452 } 453 k = k << XSDFEC_REG0_K_LSB; 454 wdata = k | n; 455 456 if (XSDFEC_LDPC_CODE_REG0_ADDR_BASE + (offset * XSDFEC_LDPC_REG_JUMP) > 457 XSDFEC_LDPC_CODE_REG0_ADDR_HIGH) { 458 dev_dbg(xsdfec->dev, "Writing outside of LDPC reg0 space 0x%x", 459 XSDFEC_LDPC_CODE_REG0_ADDR_BASE + 460 (offset * XSDFEC_LDPC_REG_JUMP)); 461 return -EINVAL; 462 } 463 xsdfec_regwrite(xsdfec, 464 XSDFEC_LDPC_CODE_REG0_ADDR_BASE + 465 (offset * XSDFEC_LDPC_REG_JUMP), 466 wdata); 467 return 0; 468 } 469 470 static int xsdfec_reg1_write(struct xsdfec_dev *xsdfec, u32 psize, 471 u32 no_packing, u32 nm, u32 offset) 472 { 473 u32 wdata; 474 475 if (psize < XSDFEC_REG1_PSIZE_MIN || psize > XSDFEC_REG1_PSIZE_MAX) { 476 dev_dbg(xsdfec->dev, "Psize is not in range"); 477 return -EINVAL; 478 } 479 480 if (no_packing != 0 && no_packing != 1) 481 dev_dbg(xsdfec->dev, "No-packing bit register invalid"); 482 no_packing = ((no_packing << XSDFEC_REG1_NO_PACKING_LSB) & 483 XSDFEC_REG1_NO_PACKING_MASK); 484 485 if (nm & ~(XSDFEC_REG1_NM_MASK >> XSDFEC_REG1_NM_LSB)) 486 dev_dbg(xsdfec->dev, "NM is beyond 10 bits"); 487 nm = (nm << XSDFEC_REG1_NM_LSB) & XSDFEC_REG1_NM_MASK; 488 489 wdata = nm | no_packing | psize; 490 if (XSDFEC_LDPC_CODE_REG1_ADDR_BASE + (offset * XSDFEC_LDPC_REG_JUMP) > 491 XSDFEC_LDPC_CODE_REG1_ADDR_HIGH) { 492 dev_dbg(xsdfec->dev, "Writing outside of LDPC reg1 space 0x%x", 493 XSDFEC_LDPC_CODE_REG1_ADDR_BASE + 494 (offset * XSDFEC_LDPC_REG_JUMP)); 495 return -EINVAL; 496 } 497 xsdfec_regwrite(xsdfec, 498 XSDFEC_LDPC_CODE_REG1_ADDR_BASE + 499 (offset * XSDFEC_LDPC_REG_JUMP), 500 wdata); 501 return 0; 502 } 503 504 static int xsdfec_reg2_write(struct xsdfec_dev *xsdfec, u32 nlayers, u32 nmqc, 505 u32 norm_type, u32 special_qc, u32 no_final_parity, 506 u32 max_schedule, u32 offset) 507 { 508 u32 wdata; 509 510 if (nlayers < XSDFEC_REG2_NLAYERS_MIN || 511 nlayers > XSDFEC_REG2_NLAYERS_MAX) { 512 dev_dbg(xsdfec->dev, "Nlayers is not in range"); 513 return -EINVAL; 514 } 515 516 if (nmqc & ~(XSDFEC_REG2_NNMQC_MASK >> XSDFEC_REG2_NMQC_LSB)) 517 dev_dbg(xsdfec->dev, "NMQC exceeds 11 bits"); 518 nmqc = (nmqc << XSDFEC_REG2_NMQC_LSB) & XSDFEC_REG2_NNMQC_MASK; 519 520 if (norm_type > 1) 521 dev_dbg(xsdfec->dev, "Norm type is invalid"); 522 norm_type = ((norm_type << XSDFEC_REG2_NORM_TYPE_LSB) & 523 XSDFEC_REG2_NORM_TYPE_MASK); 524 if (special_qc > 1) 525 dev_dbg(xsdfec->dev, "Special QC in invalid"); 526 special_qc = ((special_qc << XSDFEC_REG2_SPEICAL_QC_LSB) & 527 XSDFEC_REG2_SPECIAL_QC_MASK); 528 529 if (no_final_parity > 1) 530 dev_dbg(xsdfec->dev, "No final parity check invalid"); 531 no_final_parity = 532 ((no_final_parity << XSDFEC_REG2_NO_FINAL_PARITY_LSB) & 533 XSDFEC_REG2_NO_FINAL_PARITY_MASK); 534 if (max_schedule & 535 ~(XSDFEC_REG2_MAX_SCHEDULE_MASK >> XSDFEC_REG2_MAX_SCHEDULE_LSB)) 536 dev_dbg(xsdfec->dev, "Max Schdule exceeds 2 bits"); 537 max_schedule = ((max_schedule << XSDFEC_REG2_MAX_SCHEDULE_LSB) & 538 XSDFEC_REG2_MAX_SCHEDULE_MASK); 539 540 wdata = (max_schedule | no_final_parity | special_qc | norm_type | 541 nmqc | nlayers); 542 543 if (XSDFEC_LDPC_CODE_REG2_ADDR_BASE + (offset * XSDFEC_LDPC_REG_JUMP) > 544 XSDFEC_LDPC_CODE_REG2_ADDR_HIGH) { 545 dev_dbg(xsdfec->dev, "Writing outside of LDPC reg2 space 0x%x", 546 XSDFEC_LDPC_CODE_REG2_ADDR_BASE + 547 (offset * XSDFEC_LDPC_REG_JUMP)); 548 return -EINVAL; 549 } 550 xsdfec_regwrite(xsdfec, 551 XSDFEC_LDPC_CODE_REG2_ADDR_BASE + 552 (offset * XSDFEC_LDPC_REG_JUMP), 553 wdata); 554 return 0; 555 } 556 557 static int xsdfec_reg3_write(struct xsdfec_dev *xsdfec, u8 sc_off, u8 la_off, 558 u16 qc_off, u32 offset) 559 { 560 u32 wdata; 561 562 wdata = ((qc_off << XSDFEC_REG3_QC_OFF_LSB) | 563 (la_off << XSDFEC_REG3_LA_OFF_LSB) | sc_off); 564 if (XSDFEC_LDPC_CODE_REG3_ADDR_BASE + (offset * XSDFEC_LDPC_REG_JUMP) > 565 XSDFEC_LDPC_CODE_REG3_ADDR_HIGH) { 566 dev_dbg(xsdfec->dev, "Writing outside of LDPC reg3 space 0x%x", 567 XSDFEC_LDPC_CODE_REG3_ADDR_BASE + 568 (offset * XSDFEC_LDPC_REG_JUMP)); 569 return -EINVAL; 570 } 571 xsdfec_regwrite(xsdfec, 572 XSDFEC_LDPC_CODE_REG3_ADDR_BASE + 573 (offset * XSDFEC_LDPC_REG_JUMP), 574 wdata); 575 return 0; 576 } 577 578 static int xsdfec_table_write(struct xsdfec_dev *xsdfec, u32 offset, 579 u32 *src_ptr, u32 len, const u32 base_addr, 580 const u32 depth) 581 { 582 u32 reg = 0; 583 u32 res; 584 u32 n, i; 585 u32 *addr = NULL; 586 struct page *page[MAX_NUM_PAGES]; 587 588 /* 589 * Writes that go beyond the length of 590 * Shared Scale(SC) table should fail 591 */ 592 if ((XSDFEC_REG_WIDTH_JUMP * (offset + len)) > depth) { 593 dev_dbg(xsdfec->dev, "Write exceeds SC table length"); 594 return -EINVAL; 595 } 596 597 n = (len * XSDFEC_REG_WIDTH_JUMP) / PAGE_SIZE; 598 if ((len * XSDFEC_REG_WIDTH_JUMP) % PAGE_SIZE) 599 n += 1; 600 601 res = get_user_pages_fast((unsigned long)src_ptr, n, 0, page); 602 if (res < n) { 603 for (i = 0; i < res; i++) 604 put_page(page[i]); 605 return -EINVAL; 606 } 607 608 for (i = 0; i < n; i++) { 609 addr = kmap(page[i]); 610 do { 611 xsdfec_regwrite(xsdfec, 612 base_addr + ((offset + reg) * 613 XSDFEC_REG_WIDTH_JUMP), 614 addr[reg]); 615 reg++; 616 } while ((reg < len) && 617 ((reg * XSDFEC_REG_WIDTH_JUMP) % PAGE_SIZE)); 618 put_page(page[i]); 619 } 620 return reg; 621 } 622 623 static int xsdfec_add_ldpc(struct xsdfec_dev *xsdfec, void __user *arg) 624 { 625 struct xsdfec_ldpc_params *ldpc; 626 int ret, n; 627 628 ldpc = kzalloc(sizeof(*ldpc), GFP_KERNEL); 629 if (!ldpc) 630 return -ENOMEM; 631 632 ret = copy_from_user(ldpc, arg, sizeof(*ldpc)); 633 if (ret) 634 goto err_out; 635 636 if (xsdfec->config.code == XSDFEC_TURBO_CODE) { 637 ret = -EIO; 638 goto err_out; 639 } 640 641 /* Verify Device has not started */ 642 if (xsdfec->state == XSDFEC_STARTED) { 643 ret = -EIO; 644 goto err_out; 645 } 646 647 if (xsdfec->config.code_wr_protect) { 648 ret = -EIO; 649 goto err_out; 650 } 651 652 /* Write Reg 0 */ 653 ret = xsdfec_reg0_write(xsdfec, ldpc->n, ldpc->k, ldpc->psize, 654 ldpc->code_id); 655 if (ret) 656 goto err_out; 657 658 /* Write Reg 1 */ 659 ret = xsdfec_reg1_write(xsdfec, ldpc->psize, ldpc->no_packing, ldpc->nm, 660 ldpc->code_id); 661 if (ret) 662 goto err_out; 663 664 /* Write Reg 2 */ 665 ret = xsdfec_reg2_write(xsdfec, ldpc->nlayers, ldpc->nmqc, 666 ldpc->norm_type, ldpc->special_qc, 667 ldpc->no_final_parity, ldpc->max_schedule, 668 ldpc->code_id); 669 if (ret) 670 goto err_out; 671 672 /* Write Reg 3 */ 673 ret = xsdfec_reg3_write(xsdfec, ldpc->sc_off, ldpc->la_off, 674 ldpc->qc_off, ldpc->code_id); 675 if (ret) 676 goto err_out; 677 678 /* Write Shared Codes */ 679 n = ldpc->nlayers / 4; 680 if (ldpc->nlayers % 4) 681 n++; 682 683 ret = xsdfec_table_write(xsdfec, ldpc->sc_off, ldpc->sc_table, n, 684 XSDFEC_LDPC_SC_TABLE_ADDR_BASE, 685 XSDFEC_SC_TABLE_DEPTH); 686 if (ret < 0) 687 goto err_out; 688 689 ret = xsdfec_table_write(xsdfec, 4 * ldpc->la_off, ldpc->la_table, 690 ldpc->nlayers, XSDFEC_LDPC_LA_TABLE_ADDR_BASE, 691 XSDFEC_LA_TABLE_DEPTH); 692 if (ret < 0) 693 goto err_out; 694 695 ret = xsdfec_table_write(xsdfec, 4 * ldpc->qc_off, ldpc->qc_table, 696 ldpc->nqc, XSDFEC_LDPC_QC_TABLE_ADDR_BASE, 697 XSDFEC_QC_TABLE_DEPTH); 698 if (ret > 0) 699 ret = 0; 700 err_out: 701 kfree(ldpc); 702 return ret; 703 } 704 705 static int xsdfec_set_order(struct xsdfec_dev *xsdfec, void __user *arg) 706 { 707 bool order_invalid; 708 enum xsdfec_order order; 709 int err; 710 711 err = get_user(order, (enum xsdfec_order *)arg); 712 if (err) 713 return -EFAULT; 714 715 order_invalid = (order != XSDFEC_MAINTAIN_ORDER) && 716 (order != XSDFEC_OUT_OF_ORDER); 717 if (order_invalid) 718 return -EINVAL; 719 720 /* Verify Device has not started */ 721 if (xsdfec->state == XSDFEC_STARTED) 722 return -EIO; 723 724 xsdfec_regwrite(xsdfec, XSDFEC_ORDER_ADDR, order); 725 726 xsdfec->config.order = order; 727 728 return 0; 729 } 730 731 static int xsdfec_set_bypass(struct xsdfec_dev *xsdfec, bool __user *arg) 732 { 733 bool bypass; 734 int err; 735 736 err = get_user(bypass, arg); 737 if (err) 738 return -EFAULT; 739 740 /* Verify Device has not started */ 741 if (xsdfec->state == XSDFEC_STARTED) 742 return -EIO; 743 744 if (bypass) 745 xsdfec_regwrite(xsdfec, XSDFEC_BYPASS_ADDR, 1); 746 else 747 xsdfec_regwrite(xsdfec, XSDFEC_BYPASS_ADDR, 0); 748 749 xsdfec->config.bypass = bypass; 750 751 return 0; 752 } 753 754 static int xsdfec_is_active(struct xsdfec_dev *xsdfec, bool __user *arg) 755 { 756 u32 reg_value; 757 bool is_active; 758 int err; 759 760 reg_value = xsdfec_regread(xsdfec, XSDFEC_ACTIVE_ADDR); 761 /* using a double ! operator instead of casting */ 762 is_active = !!(reg_value & XSDFEC_IS_ACTIVITY_SET); 763 err = put_user(is_active, arg); 764 if (err) 765 return -EFAULT; 766 767 return err; 768 } 769 770 static u32 771 xsdfec_translate_axis_width_cfg_val(enum xsdfec_axis_width axis_width_cfg) 772 { 773 u32 axis_width_field = 0; 774 775 switch (axis_width_cfg) { 776 case XSDFEC_1x128b: 777 axis_width_field = 0; 778 break; 779 case XSDFEC_2x128b: 780 axis_width_field = 1; 781 break; 782 case XSDFEC_4x128b: 783 axis_width_field = 2; 784 break; 785 } 786 787 return axis_width_field; 788 } 789 790 static u32 xsdfec_translate_axis_words_cfg_val(enum xsdfec_axis_word_include 791 axis_word_inc_cfg) 792 { 793 u32 axis_words_field = 0; 794 795 if (axis_word_inc_cfg == XSDFEC_FIXED_VALUE || 796 axis_word_inc_cfg == XSDFEC_IN_BLOCK) 797 axis_words_field = 0; 798 else if (axis_word_inc_cfg == XSDFEC_PER_AXI_TRANSACTION) 799 axis_words_field = 1; 800 801 return axis_words_field; 802 } 803 804 static int xsdfec_cfg_axi_streams(struct xsdfec_dev *xsdfec) 805 { 806 u32 reg_value; 807 u32 dout_words_field; 808 u32 dout_width_field; 809 u32 din_words_field; 810 u32 din_width_field; 811 struct xsdfec_config *config = &xsdfec->config; 812 813 /* translate config info to register values */ 814 dout_words_field = 815 xsdfec_translate_axis_words_cfg_val(config->dout_word_include); 816 dout_width_field = 817 xsdfec_translate_axis_width_cfg_val(config->dout_width); 818 din_words_field = 819 xsdfec_translate_axis_words_cfg_val(config->din_word_include); 820 din_width_field = 821 xsdfec_translate_axis_width_cfg_val(config->din_width); 822 823 reg_value = dout_words_field << XSDFEC_AXIS_DOUT_WORDS_LSB; 824 reg_value |= dout_width_field << XSDFEC_AXIS_DOUT_WIDTH_LSB; 825 reg_value |= din_words_field << XSDFEC_AXIS_DIN_WORDS_LSB; 826 reg_value |= din_width_field << XSDFEC_AXIS_DIN_WIDTH_LSB; 827 828 xsdfec_regwrite(xsdfec, XSDFEC_AXIS_WIDTH_ADDR, reg_value); 829 830 return 0; 831 } 832 833 static int xsdfec_dev_open(struct inode *iptr, struct file *fptr) 834 { 835 return 0; 836 } 837 838 static int xsdfec_dev_release(struct inode *iptr, struct file *fptr) 839 { 840 return 0; 841 } 842 843 static long xsdfec_dev_ioctl(struct file *fptr, unsigned int cmd, 844 unsigned long data) 845 { 846 struct xsdfec_dev *xsdfec; 847 void __user *arg = NULL; 848 int rval = -EINVAL; 849 850 xsdfec = container_of(fptr->private_data, struct xsdfec_dev, miscdev); 851 852 /* check if ioctl argument is present and valid */ 853 if (_IOC_DIR(cmd) != _IOC_NONE) { 854 arg = (void __user *)data; 855 if (!arg) 856 return rval; 857 } 858 859 switch (cmd) { 860 case XSDFEC_GET_CONFIG: 861 rval = xsdfec_get_config(xsdfec, arg); 862 break; 863 case XSDFEC_SET_IRQ: 864 rval = xsdfec_set_irq(xsdfec, arg); 865 break; 866 case XSDFEC_SET_TURBO: 867 rval = xsdfec_set_turbo(xsdfec, arg); 868 break; 869 case XSDFEC_GET_TURBO: 870 rval = xsdfec_get_turbo(xsdfec, arg); 871 break; 872 case XSDFEC_ADD_LDPC_CODE_PARAMS: 873 rval = xsdfec_add_ldpc(xsdfec, arg); 874 break; 875 case XSDFEC_SET_ORDER: 876 rval = xsdfec_set_order(xsdfec, arg); 877 break; 878 case XSDFEC_SET_BYPASS: 879 rval = xsdfec_set_bypass(xsdfec, arg); 880 break; 881 case XSDFEC_IS_ACTIVE: 882 rval = xsdfec_is_active(xsdfec, (bool __user *)arg); 883 break; 884 default: 885 /* Should not get here */ 886 break; 887 } 888 return rval; 889 } 890 891 #ifdef CONFIG_COMPAT 892 static long xsdfec_dev_compat_ioctl(struct file *file, unsigned int cmd, 893 unsigned long data) 894 { 895 return xsdfec_dev_ioctl(file, cmd, (unsigned long)compat_ptr(data)); 896 } 897 #endif 898 899 static unsigned int xsdfec_poll(struct file *file, poll_table *wait) 900 { 901 unsigned int mask = 0; 902 struct xsdfec_dev *xsdfec; 903 904 xsdfec = container_of(file->private_data, struct xsdfec_dev, miscdev); 905 906 if (!xsdfec) 907 return POLLNVAL | POLLHUP; 908 909 poll_wait(file, &xsdfec->waitq, wait); 910 911 /* XSDFEC ISR detected an error */ 912 spin_lock_irqsave(&xsdfec->error_data_lock, xsdfec->flags); 913 if (xsdfec->state_updated) 914 mask |= POLLIN | POLLPRI; 915 916 if (xsdfec->stats_updated) 917 mask |= POLLIN | POLLRDNORM; 918 spin_unlock_irqrestore(&xsdfec->error_data_lock, xsdfec->flags); 919 920 return mask; 921 } 922 923 static const struct file_operations xsdfec_fops = { 924 .owner = THIS_MODULE, 925 .open = xsdfec_dev_open, 926 .release = xsdfec_dev_release, 927 .unlocked_ioctl = xsdfec_dev_ioctl, 928 .poll = xsdfec_poll, 929 #ifdef CONFIG_COMPAT 930 .compat_ioctl = xsdfec_dev_compat_ioctl, 931 #endif 932 }; 933 934 static int xsdfec_parse_of(struct xsdfec_dev *xsdfec) 935 { 936 struct device *dev = xsdfec->dev; 937 struct device_node *node = dev->of_node; 938 int rval; 939 const char *fec_code; 940 u32 din_width; 941 u32 din_word_include; 942 u32 dout_width; 943 u32 dout_word_include; 944 945 rval = of_property_read_string(node, "xlnx,sdfec-code", &fec_code); 946 if (rval < 0) 947 return rval; 948 949 if (!strcasecmp(fec_code, "ldpc")) 950 xsdfec->config.code = XSDFEC_LDPC_CODE; 951 else if (!strcasecmp(fec_code, "turbo")) 952 xsdfec->config.code = XSDFEC_TURBO_CODE; 953 else 954 return -EINVAL; 955 956 rval = of_property_read_u32(node, "xlnx,sdfec-din-words", 957 &din_word_include); 958 if (rval < 0) 959 return rval; 960 961 if (din_word_include < XSDFEC_AXIS_WORDS_INCLUDE_MAX) 962 xsdfec->config.din_word_include = din_word_include; 963 else 964 return -EINVAL; 965 966 rval = of_property_read_u32(node, "xlnx,sdfec-din-width", &din_width); 967 if (rval < 0) 968 return rval; 969 970 switch (din_width) { 971 /* Fall through and set for valid values */ 972 case XSDFEC_1x128b: 973 case XSDFEC_2x128b: 974 case XSDFEC_4x128b: 975 xsdfec->config.din_width = din_width; 976 break; 977 default: 978 return -EINVAL; 979 } 980 981 rval = of_property_read_u32(node, "xlnx,sdfec-dout-words", 982 &dout_word_include); 983 if (rval < 0) 984 return rval; 985 986 if (dout_word_include < XSDFEC_AXIS_WORDS_INCLUDE_MAX) 987 xsdfec->config.dout_word_include = dout_word_include; 988 else 989 return -EINVAL; 990 991 rval = of_property_read_u32(node, "xlnx,sdfec-dout-width", &dout_width); 992 if (rval < 0) 993 return rval; 994 995 switch (dout_width) { 996 /* Fall through and set for valid values */ 997 case XSDFEC_1x128b: 998 case XSDFEC_2x128b: 999 case XSDFEC_4x128b: 1000 xsdfec->config.dout_width = dout_width; 1001 break; 1002 default: 1003 return -EINVAL; 1004 } 1005 1006 /* Write LDPC to CODE Register */ 1007 xsdfec_regwrite(xsdfec, XSDFEC_FEC_CODE_ADDR, xsdfec->config.code); 1008 1009 xsdfec_cfg_axi_streams(xsdfec); 1010 1011 return 0; 1012 } 1013 1014 static irqreturn_t xsdfec_irq_thread(int irq, void *dev_id) 1015 { 1016 struct xsdfec_dev *xsdfec = dev_id; 1017 irqreturn_t ret = IRQ_HANDLED; 1018 u32 ecc_err; 1019 u32 isr_err; 1020 u32 uecc_count; 1021 u32 cecc_count; 1022 u32 isr_err_count; 1023 u32 aecc_count; 1024 u32 tmp; 1025 1026 WARN_ON(xsdfec->irq != irq); 1027 1028 /* Mask Interrupts */ 1029 xsdfec_isr_enable(xsdfec, false); 1030 xsdfec_ecc_isr_enable(xsdfec, false); 1031 /* Read ISR */ 1032 ecc_err = xsdfec_regread(xsdfec, XSDFEC_ECC_ISR_ADDR); 1033 isr_err = xsdfec_regread(xsdfec, XSDFEC_ISR_ADDR); 1034 /* Clear the interrupts */ 1035 xsdfec_regwrite(xsdfec, XSDFEC_ECC_ISR_ADDR, ecc_err); 1036 xsdfec_regwrite(xsdfec, XSDFEC_ISR_ADDR, isr_err); 1037 1038 tmp = ecc_err & XSDFEC_ALL_ECC_ISR_MBE_MASK; 1039 /* Count uncorrectable 2-bit errors */ 1040 uecc_count = hweight32(tmp); 1041 /* Count all ECC errors */ 1042 aecc_count = hweight32(ecc_err); 1043 /* Number of correctable 1-bit ECC error */ 1044 cecc_count = aecc_count - 2 * uecc_count; 1045 /* Count ISR errors */ 1046 isr_err_count = hweight32(isr_err); 1047 dev_dbg(xsdfec->dev, "tmp=%x, uecc=%x, aecc=%x, cecc=%x, isr=%x", tmp, 1048 uecc_count, aecc_count, cecc_count, isr_err_count); 1049 dev_dbg(xsdfec->dev, "uecc=%x, cecc=%x, isr=%x", xsdfec->uecc_count, 1050 xsdfec->cecc_count, xsdfec->isr_err_count); 1051 1052 spin_lock_irqsave(&xsdfec->error_data_lock, xsdfec->flags); 1053 /* Add new errors to a 2-bits counter */ 1054 if (uecc_count) 1055 xsdfec->uecc_count += uecc_count; 1056 /* Add new errors to a 1-bits counter */ 1057 if (cecc_count) 1058 xsdfec->cecc_count += cecc_count; 1059 /* Add new errors to a ISR counter */ 1060 if (isr_err_count) 1061 xsdfec->isr_err_count += isr_err_count; 1062 1063 /* Update state/stats flag */ 1064 if (uecc_count) { 1065 if (ecc_err & XSDFEC_ECC_ISR_MBE_MASK) 1066 xsdfec->state = XSDFEC_NEEDS_RESET; 1067 else if (ecc_err & XSDFEC_PL_INIT_ECC_ISR_MBE_MASK) 1068 xsdfec->state = XSDFEC_PL_RECONFIGURE; 1069 xsdfec->stats_updated = true; 1070 xsdfec->state_updated = true; 1071 } 1072 1073 if (cecc_count) 1074 xsdfec->stats_updated = true; 1075 1076 if (isr_err_count) { 1077 xsdfec->state = XSDFEC_NEEDS_RESET; 1078 xsdfec->stats_updated = true; 1079 xsdfec->state_updated = true; 1080 } 1081 1082 spin_unlock_irqrestore(&xsdfec->error_data_lock, xsdfec->flags); 1083 dev_dbg(xsdfec->dev, "state=%x, stats=%x", xsdfec->state_updated, 1084 xsdfec->stats_updated); 1085 1086 /* Enable another polling */ 1087 if (xsdfec->state_updated || xsdfec->stats_updated) 1088 wake_up_interruptible(&xsdfec->waitq); 1089 else 1090 ret = IRQ_NONE; 1091 1092 /* Unmask Interrupts */ 1093 xsdfec_isr_enable(xsdfec, true); 1094 xsdfec_ecc_isr_enable(xsdfec, true); 1095 1096 return ret; 1097 } 1098 1099 static int xsdfec_clk_init(struct platform_device *pdev, 1100 struct xsdfec_clks *clks) 1101 { 1102 int err; 1103 1104 clks->core_clk = devm_clk_get(&pdev->dev, "core_clk"); 1105 if (IS_ERR(clks->core_clk)) { 1106 dev_err(&pdev->dev, "failed to get core_clk"); 1107 return PTR_ERR(clks->core_clk); 1108 } 1109 1110 clks->axi_clk = devm_clk_get(&pdev->dev, "s_axi_aclk"); 1111 if (IS_ERR(clks->axi_clk)) { 1112 dev_err(&pdev->dev, "failed to get axi_clk"); 1113 return PTR_ERR(clks->axi_clk); 1114 } 1115 1116 clks->din_words_clk = devm_clk_get(&pdev->dev, "s_axis_din_words_aclk"); 1117 if (IS_ERR(clks->din_words_clk)) { 1118 if (PTR_ERR(clks->din_words_clk) != -ENOENT) { 1119 err = PTR_ERR(clks->din_words_clk); 1120 return err; 1121 } 1122 clks->din_words_clk = NULL; 1123 } 1124 1125 clks->din_clk = devm_clk_get(&pdev->dev, "s_axis_din_aclk"); 1126 if (IS_ERR(clks->din_clk)) { 1127 if (PTR_ERR(clks->din_clk) != -ENOENT) { 1128 err = PTR_ERR(clks->din_clk); 1129 return err; 1130 } 1131 clks->din_clk = NULL; 1132 } 1133 1134 clks->dout_clk = devm_clk_get(&pdev->dev, "m_axis_dout_aclk"); 1135 if (IS_ERR(clks->dout_clk)) { 1136 if (PTR_ERR(clks->dout_clk) != -ENOENT) { 1137 err = PTR_ERR(clks->dout_clk); 1138 return err; 1139 } 1140 clks->dout_clk = NULL; 1141 } 1142 1143 clks->dout_words_clk = 1144 devm_clk_get(&pdev->dev, "s_axis_dout_words_aclk"); 1145 if (IS_ERR(clks->dout_words_clk)) { 1146 if (PTR_ERR(clks->dout_words_clk) != -ENOENT) { 1147 err = PTR_ERR(clks->dout_words_clk); 1148 return err; 1149 } 1150 clks->dout_words_clk = NULL; 1151 } 1152 1153 clks->ctrl_clk = devm_clk_get(&pdev->dev, "s_axis_ctrl_aclk"); 1154 if (IS_ERR(clks->ctrl_clk)) { 1155 if (PTR_ERR(clks->ctrl_clk) != -ENOENT) { 1156 err = PTR_ERR(clks->ctrl_clk); 1157 return err; 1158 } 1159 clks->ctrl_clk = NULL; 1160 } 1161 1162 clks->status_clk = devm_clk_get(&pdev->dev, "m_axis_status_aclk"); 1163 if (IS_ERR(clks->status_clk)) { 1164 if (PTR_ERR(clks->status_clk) != -ENOENT) { 1165 err = PTR_ERR(clks->status_clk); 1166 return err; 1167 } 1168 clks->status_clk = NULL; 1169 } 1170 1171 err = clk_prepare_enable(clks->core_clk); 1172 if (err) { 1173 dev_err(&pdev->dev, "failed to enable core_clk (%d)", err); 1174 return err; 1175 } 1176 1177 err = clk_prepare_enable(clks->axi_clk); 1178 if (err) { 1179 dev_err(&pdev->dev, "failed to enable axi_clk (%d)", err); 1180 goto err_disable_core_clk; 1181 } 1182 1183 err = clk_prepare_enable(clks->din_clk); 1184 if (err) { 1185 dev_err(&pdev->dev, "failed to enable din_clk (%d)", err); 1186 goto err_disable_axi_clk; 1187 } 1188 1189 err = clk_prepare_enable(clks->din_words_clk); 1190 if (err) { 1191 dev_err(&pdev->dev, "failed to enable din_words_clk (%d)", err); 1192 goto err_disable_din_clk; 1193 } 1194 1195 err = clk_prepare_enable(clks->dout_clk); 1196 if (err) { 1197 dev_err(&pdev->dev, "failed to enable dout_clk (%d)", err); 1198 goto err_disable_din_words_clk; 1199 } 1200 1201 err = clk_prepare_enable(clks->dout_words_clk); 1202 if (err) { 1203 dev_err(&pdev->dev, "failed to enable dout_words_clk (%d)", 1204 err); 1205 goto err_disable_dout_clk; 1206 } 1207 1208 err = clk_prepare_enable(clks->ctrl_clk); 1209 if (err) { 1210 dev_err(&pdev->dev, "failed to enable ctrl_clk (%d)", err); 1211 goto err_disable_dout_words_clk; 1212 } 1213 1214 err = clk_prepare_enable(clks->status_clk); 1215 if (err) { 1216 dev_err(&pdev->dev, "failed to enable status_clk (%d)\n", err); 1217 goto err_disable_ctrl_clk; 1218 } 1219 1220 return err; 1221 1222 err_disable_ctrl_clk: 1223 clk_disable_unprepare(clks->ctrl_clk); 1224 err_disable_dout_words_clk: 1225 clk_disable_unprepare(clks->dout_words_clk); 1226 err_disable_dout_clk: 1227 clk_disable_unprepare(clks->dout_clk); 1228 err_disable_din_words_clk: 1229 clk_disable_unprepare(clks->din_words_clk); 1230 err_disable_din_clk: 1231 clk_disable_unprepare(clks->din_clk); 1232 err_disable_axi_clk: 1233 clk_disable_unprepare(clks->axi_clk); 1234 err_disable_core_clk: 1235 clk_disable_unprepare(clks->core_clk); 1236 1237 return err; 1238 } 1239 1240 static void xsdfec_disable_all_clks(struct xsdfec_clks *clks) 1241 { 1242 clk_disable_unprepare(clks->status_clk); 1243 clk_disable_unprepare(clks->ctrl_clk); 1244 clk_disable_unprepare(clks->dout_words_clk); 1245 clk_disable_unprepare(clks->dout_clk); 1246 clk_disable_unprepare(clks->din_words_clk); 1247 clk_disable_unprepare(clks->din_clk); 1248 clk_disable_unprepare(clks->core_clk); 1249 clk_disable_unprepare(clks->axi_clk); 1250 } 1251 1252 static void xsdfec_idr_remove(struct xsdfec_dev *xsdfec) 1253 { 1254 mutex_lock(&dev_idr_lock); 1255 idr_remove(&dev_idr, xsdfec->dev_id); 1256 mutex_unlock(&dev_idr_lock); 1257 } 1258 1259 static int xsdfec_probe(struct platform_device *pdev) 1260 { 1261 struct xsdfec_dev *xsdfec; 1262 struct device *dev; 1263 struct resource *res; 1264 int err; 1265 bool irq_enabled = true; 1266 1267 xsdfec = devm_kzalloc(&pdev->dev, sizeof(*xsdfec), GFP_KERNEL); 1268 if (!xsdfec) 1269 return -ENOMEM; 1270 1271 xsdfec->dev = &pdev->dev; 1272 spin_lock_init(&xsdfec->error_data_lock); 1273 1274 err = xsdfec_clk_init(pdev, &xsdfec->clks); 1275 if (err) 1276 return err; 1277 1278 dev = xsdfec->dev; 1279 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1280 xsdfec->regs = devm_ioremap_resource(dev, res); 1281 if (IS_ERR(xsdfec->regs)) { 1282 err = PTR_ERR(xsdfec->regs); 1283 goto err_xsdfec_dev; 1284 } 1285 1286 xsdfec->irq = platform_get_irq(pdev, 0); 1287 if (xsdfec->irq < 0) { 1288 dev_dbg(dev, "platform_get_irq failed"); 1289 irq_enabled = false; 1290 } 1291 1292 err = xsdfec_parse_of(xsdfec); 1293 if (err < 0) 1294 goto err_xsdfec_dev; 1295 1296 update_config_from_hw(xsdfec); 1297 1298 /* Save driver private data */ 1299 platform_set_drvdata(pdev, xsdfec); 1300 1301 if (irq_enabled) { 1302 init_waitqueue_head(&xsdfec->waitq); 1303 /* Register IRQ thread */ 1304 err = devm_request_threaded_irq(dev, xsdfec->irq, NULL, 1305 xsdfec_irq_thread, IRQF_ONESHOT, 1306 "xilinx-sdfec16", xsdfec); 1307 if (err < 0) { 1308 dev_err(dev, "unable to request IRQ%d", xsdfec->irq); 1309 goto err_xsdfec_dev; 1310 } 1311 } 1312 1313 mutex_lock(&dev_idr_lock); 1314 err = idr_alloc(&dev_idr, xsdfec->dev_name, 0, 0, GFP_KERNEL); 1315 mutex_unlock(&dev_idr_lock); 1316 if (err < 0) 1317 goto err_xsdfec_dev; 1318 xsdfec->dev_id = err; 1319 1320 snprintf(xsdfec->dev_name, DEV_NAME_LEN, "xsdfec%d", xsdfec->dev_id); 1321 xsdfec->miscdev.minor = MISC_DYNAMIC_MINOR; 1322 xsdfec->miscdev.name = xsdfec->dev_name; 1323 xsdfec->miscdev.fops = &xsdfec_fops; 1324 xsdfec->miscdev.parent = dev; 1325 err = misc_register(&xsdfec->miscdev); 1326 if (err) { 1327 dev_err(dev, "error:%d. Unable to register device", err); 1328 goto err_xsdfec_idr; 1329 } 1330 return 0; 1331 1332 err_xsdfec_idr: 1333 xsdfec_idr_remove(xsdfec); 1334 err_xsdfec_dev: 1335 xsdfec_disable_all_clks(&xsdfec->clks); 1336 return err; 1337 } 1338 1339 static int xsdfec_remove(struct platform_device *pdev) 1340 { 1341 struct xsdfec_dev *xsdfec; 1342 1343 xsdfec = platform_get_drvdata(pdev); 1344 misc_deregister(&xsdfec->miscdev); 1345 xsdfec_idr_remove(xsdfec); 1346 xsdfec_disable_all_clks(&xsdfec->clks); 1347 return 0; 1348 } 1349 1350 static const struct of_device_id xsdfec_of_match[] = { 1351 { 1352 .compatible = "xlnx,sd-fec-1.1", 1353 }, 1354 { /* end of table */ } 1355 }; 1356 MODULE_DEVICE_TABLE(of, xsdfec_of_match); 1357 1358 static struct platform_driver xsdfec_driver = { 1359 .driver = { 1360 .name = "xilinx-sdfec", 1361 .of_match_table = xsdfec_of_match, 1362 }, 1363 .probe = xsdfec_probe, 1364 .remove = xsdfec_remove, 1365 }; 1366 1367 static int __init xsdfec_init(void) 1368 { 1369 int err; 1370 1371 mutex_init(&dev_idr_lock); 1372 idr_init(&dev_idr); 1373 err = platform_driver_register(&xsdfec_driver); 1374 if (err < 0) { 1375 pr_err("%s Unabled to register SDFEC driver", __func__); 1376 return err; 1377 } 1378 return 0; 1379 } 1380 1381 static void __exit xsdfec_exit(void) 1382 { 1383 platform_driver_unregister(&xsdfec_driver); 1384 idr_destroy(&dev_idr); 1385 } 1386 1387 module_init(xsdfec_init); 1388 module_exit(xsdfec_exit); 1389 1390 MODULE_AUTHOR("Xilinx, Inc"); 1391 MODULE_DESCRIPTION("Xilinx SD-FEC16 Driver"); 1392 MODULE_LICENSE("GPL"); 1393