Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

misc: xilinx_sdfec: Add ability to configure turbo

Add the capability to configure and retrieve turbo mode
via the ioctls XSDFEC_SET_TURBO and XSDFEC_GET_TURBO.
Add char device interface per DT node present and support
file operations:
- open(),
- close(),
- unlocked_ioctl(),
- compat_ioctl().

Tested-by: Dragan Cvetic <dragan.cvetic@xilinx.com>
Signed-off-by: Derek Kiernan <derek.kiernan@xilinx.com>
Signed-off-by: Dragan Cvetic <dragan.cvetic@xilinx.com>
Link: https://lore.kernel.org/r/1564216438-322406-3-git-send-email-dragan.cvetic@xilinx.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Dragan Cvetic and committed by
Greg Kroah-Hartman
6f86ed82 6d54e455

+177
+110
drivers/misc/xilinx_sdfec.c
··· 19 19 #include <linux/poll.h> 20 20 #include <linux/slab.h> 21 21 #include <linux/clk.h> 22 + #include <linux/compat.h> 22 23 23 24 #include <uapi/misc/xilinx_sdfec.h> 24 25 ··· 106 105 107 106 /* BYPASS Register */ 108 107 #define XSDFEC_BYPASS_ADDR (0x3C) 108 + 109 + /* Turbo Code Register */ 110 + #define XSDFEC_TURBO_ADDR (0x100) 111 + #define XSDFEC_TURBO_SCALE_MASK (0xFFF) 112 + #define XSDFEC_TURBO_SCALE_BIT_POS (8) 113 + #define XSDFEC_TURBO_SCALE_MAX (15) 109 114 110 115 /** 111 116 * struct xsdfec_clks - For managing SD-FEC clocks ··· 221 214 xsdfec->state = XSDFEC_STOPPED; 222 215 } 223 216 217 + static int xsdfec_set_turbo(struct xsdfec_dev *xsdfec, void __user *arg) 218 + { 219 + struct xsdfec_turbo turbo; 220 + int err; 221 + u32 turbo_write; 222 + 223 + err = copy_from_user(&turbo, arg, sizeof(turbo)); 224 + if (err) 225 + return -EFAULT; 226 + 227 + if (turbo.alg >= XSDFEC_TURBO_ALG_MAX) 228 + return -EINVAL; 229 + 230 + if (turbo.scale > XSDFEC_TURBO_SCALE_MAX) 231 + return -EINVAL; 232 + 233 + /* Check to see what device tree says about the FEC codes */ 234 + if (xsdfec->config.code == XSDFEC_LDPC_CODE) 235 + return -EIO; 236 + 237 + turbo_write = ((turbo.scale & XSDFEC_TURBO_SCALE_MASK) 238 + << XSDFEC_TURBO_SCALE_BIT_POS) | 239 + turbo.alg; 240 + xsdfec_regwrite(xsdfec, XSDFEC_TURBO_ADDR, turbo_write); 241 + return err; 242 + } 243 + 244 + static int xsdfec_get_turbo(struct xsdfec_dev *xsdfec, void __user *arg) 245 + { 246 + u32 reg_value; 247 + struct xsdfec_turbo turbo_params; 248 + int err; 249 + 250 + if (xsdfec->config.code == XSDFEC_LDPC_CODE) 251 + return -EIO; 252 + 253 + reg_value = xsdfec_regread(xsdfec, XSDFEC_TURBO_ADDR); 254 + 255 + turbo_params.scale = (reg_value & XSDFEC_TURBO_SCALE_MASK) >> 256 + XSDFEC_TURBO_SCALE_BIT_POS; 257 + turbo_params.alg = reg_value & 0x1; 258 + 259 + err = copy_to_user(arg, &turbo_params, sizeof(turbo_params)); 260 + if (err) 261 + err = -EFAULT; 262 + 263 + return err; 264 + } 265 + 224 266 static u32 225 267 xsdfec_translate_axis_width_cfg_val(enum xsdfec_axis_width axis_width_cfg) 226 268 { ··· 333 277 return 0; 334 278 } 335 279 280 + static int xsdfec_dev_open(struct inode *iptr, struct file *fptr) 281 + { 282 + return 0; 283 + } 284 + 285 + static int xsdfec_dev_release(struct inode *iptr, struct file *fptr) 286 + { 287 + return 0; 288 + } 289 + 290 + static long xsdfec_dev_ioctl(struct file *fptr, unsigned int cmd, 291 + unsigned long data) 292 + { 293 + struct xsdfec_dev *xsdfec; 294 + void __user *arg = NULL; 295 + int rval = -EINVAL; 296 + 297 + xsdfec = container_of(fptr->private_data, struct xsdfec_dev, miscdev); 298 + 299 + /* check if ioctl argument is present and valid */ 300 + if (_IOC_DIR(cmd) != _IOC_NONE) { 301 + arg = (void __user *)data; 302 + if (!arg) 303 + return rval; 304 + } 305 + 306 + switch (cmd) { 307 + case XSDFEC_SET_TURBO: 308 + rval = xsdfec_set_turbo(xsdfec, arg); 309 + break; 310 + case XSDFEC_GET_TURBO: 311 + rval = xsdfec_get_turbo(xsdfec, arg); 312 + break; 313 + default: 314 + /* Should not get here */ 315 + break; 316 + } 317 + return rval; 318 + } 319 + 320 + #ifdef CONFIG_COMPAT 321 + static long xsdfec_dev_compat_ioctl(struct file *file, unsigned int cmd, 322 + unsigned long data) 323 + { 324 + return xsdfec_dev_ioctl(file, cmd, (unsigned long)compat_ptr(data)); 325 + } 326 + #endif 327 + 336 328 static const struct file_operations xsdfec_fops = { 337 329 .owner = THIS_MODULE, 330 + .open = xsdfec_dev_open, 331 + .release = xsdfec_dev_release, 332 + .unlocked_ioctl = xsdfec_dev_ioctl, 333 + #ifdef CONFIG_COMPAT 334 + .compat_ioctl = xsdfec_dev_compat_ioctl, 335 + #endif 338 336 }; 339 337 340 338 static int xsdfec_parse_of(struct xsdfec_dev *xsdfec)
+67
include/uapi/misc/xilinx_sdfec.h
··· 41 41 }; 42 42 43 43 /** 44 + * enum xsdfec_turbo_alg - Turbo Algorithm Type. 45 + * @XSDFEC_MAX_SCALE: Max Log-Map algorithm with extrinsic scaling. When 46 + * scaling is set to this is equivalent to the Max Log-Map 47 + * algorithm. 48 + * @XSDFEC_MAX_STAR: Log-Map algorithm. 49 + * @XSDFEC_TURBO_ALG_MAX: Used to indicate out of bound Turbo algorithms. 50 + * 51 + * This enum specifies which Turbo Decode algorithm is in use. 52 + */ 53 + enum xsdfec_turbo_alg { 54 + XSDFEC_MAX_SCALE = 0, 55 + XSDFEC_MAX_STAR, 56 + XSDFEC_TURBO_ALG_MAX, 57 + }; 58 + 59 + /** 44 60 * enum xsdfec_state - State. 45 61 * @XSDFEC_INIT: Driver is initialized. 46 62 * @XSDFEC_STARTED: Driver is started. ··· 114 98 }; 115 99 116 100 /** 101 + * struct xsdfec_turbo - User data for Turbo codes. 102 + * @alg: Specifies which Turbo decode algorithm to use 103 + * @scale: Specifies the extrinsic scaling to apply when the Max Scale algorithm 104 + * has been selected 105 + * 106 + * Turbo code structure to communicate parameters to XSDFEC driver. 107 + */ 108 + struct xsdfec_turbo { 109 + __u32 alg; 110 + __u8 scale; 111 + }; 112 + 113 + /** 114 + * struct xsdfec_status - Status of SD-FEC core. 115 + * @state: State of the SD-FEC core 116 + * @activity: Describes if the SD-FEC instance is Active 117 + */ 118 + struct xsdfec_status { 119 + __u32 state; 120 + __s8 activity; 121 + }; 122 + 123 + /** 117 124 * struct xsdfec_irq - Enabling or Disabling Interrupts. 118 125 * @enable_isr: If true enables the ISR 119 126 * @enable_ecc_isr: If true enables the ECC ISR ··· 174 135 * XSDFEC IOCTL List 175 136 */ 176 137 #define XSDFEC_MAGIC 'f' 138 + /** 139 + * DOC: XSDFEC_SET_TURBO 140 + * @Parameters 141 + * 142 + * @struct xsdfec_turbo * 143 + * Pointer to the &struct xsdfec_turbo that contains the Turbo decode 144 + * settings for the SD-FEC core 145 + * 146 + * @Description 147 + * 148 + * ioctl that sets the SD-FEC Turbo parameter values 149 + * 150 + * This can only be used when the driver is in the XSDFEC_STOPPED state 151 + */ 152 + #define XSDFEC_SET_TURBO _IOW(XSDFEC_MAGIC, 4, struct xsdfec_turbo) 153 + /** 154 + * DOC: XSDFEC_GET_TURBO 155 + * @Parameters 156 + * 157 + * @struct xsdfec_turbo * 158 + * Pointer to the &struct xsdfec_turbo that contains the current Turbo 159 + * decode settings of the SD-FEC Block 160 + * 161 + * @Description 162 + * 163 + * ioctl that returns SD-FEC turbo param values 164 + */ 165 + #define XSDFEC_GET_TURBO _IOR(XSDFEC_MAGIC, 7, struct xsdfec_turbo) 177 166 #endif /* __XILINX_SDFEC_H__ */